> ## Documentation Index
> Fetch the complete documentation index at: https://docs.compose.market/llms.txt
> Use this file to discover all available pages before exploring further.

# Identity

> Agent registry on Solana — mint, clone, warp, licensing, and the agent wallet.

The identity program is the root of the protocol on Solana: every agent is one of its PDAs, and every other program reads those accounts cross-program. It covers the ERC-8004 identity surface — plus cloning, warping (importing external agents), and the licensing ledger the [market program](/programs/market) consumes.

Program ID (devnet): `AoaWgzq4tRrTbmWKmnC5VhpszqjFqEYuEeLQSGx8K6DY`

Account markers below: **s** = signer, **w** = writable, **p** = PDA verified, **+** = created if missing.

## Instructions

### Setup & admin

| Tag | Instruction     | Arguments           | Accounts, in order                                                | Notes                                                                             |
| --- | --------------- | ------------------- | ----------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| 0   | `Initialize`    | —                   | registry **w p +**, admin **s**, rent payer **s**, system program | One-time. Sets `next_agent_id = 1`.                                               |
| 11  | `Authorize`     | `consumer: Pubkey`  | registry **w**, admin **s**                                       | Lets a program (e.g. market's authority PDA) consume licenses. Cap: 32 consumers. |
| 12  | `Revoke`        | `consumer: Pubkey`  | registry **w**, admin **s**                                       | Removes a consumer.                                                               |
| 13  | `TransferAdmin` | `new_admin: Pubkey` | registry **w**, admin **s**                                       | Single-step. No zero address.                                                     |

### Agent lifecycle

| Tag | Instruction      | Arguments                                                                                                                                                      | Accounts, in order                                                                                                                                                 | Notes                                                                                                    |
| --- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------- |
| 1   | `Register`       | `uri: String`                                                                                                                                                  | registry **w**, agent **w p +**, dna **w p +**, owner **s**, rent payer **s**, system program                                                                      | Light path: DNA is derived for you, unlimited licenses, price 0, not cloneable.                          |
| 2   | `Mint`           | `dna_hash: [u8;32]`, `licenses: u64`, `license_price: u64`, `creator_fee: u64`, `cloneable: bool`, `agent_wallet: Pubkey`, `asset_mint: Pubkey`, `uri: String` | same shape as `Register`                                                                                                                                           | Full path: you supply the DNA hash (must be non-zero) and the economics. `licenses = 0` means unlimited. |
| 3   | `Clone`          | `original_agent_id`, `chain_id: u64`, `model: String`, `licenses`, `license_price`, `agent_wallet`, `asset_mint`, `uri`                                        | registry **w**, parent agent **p**, agent **w p +**, dna **w p +**, clone index **w p +**, identity stats **w p +**, owner **s**, rent payer **s**, system program | Parent must be `cloneable` and not itself a clone. One level deep only.                                  |
| 4   | `Warp`           | `original_hash: [u8;32]`, `original_creator: Pubkey`, `licenses`, `license_price`, `agent_wallet`, `asset_mint`, `uri`                                         | registry **w**, agent **w p +**, dna **w p +**, warp **w p +**, warp agent **w p +**, identity stats **w p +**, warper **s**, rent payer **s**, system program     | Imports an external agent. One warp per `original_hash`. See [Warp royalties](#warp-royalties).          |
| 5   | `SetUri`         | `agent_id: u64`, `uri: String`                                                                                                                                 | agent **w p**, owner **s**                                                                                                                                         | Owner only.                                                                                              |
| 8   | `SetAgentWallet` | `agent_id: u64`, `wallet: Pubkey`                                                                                                                              | agent **w p**, owner **s**, wallet account **s** (only when setting a third-party wallet)                                                                          | Zero pubkey clears. A wallet that isn't the owner must co-sign.                                          |
| 9   | `Transfer`       | `agent_id: u64`, `new_owner: Pubkey`                                                                                                                           | agent **w p**, owner **s**                                                                                                                                         | Changes `owner` only — the agent wallet stays as-is.                                                     |
| 10  | `UpdatePrice`    | `agent_id: u64`, `license_price: u64`                                                                                                                          | agent **w p**, creator **s**                                                                                                                                       | Only the original `creator`, not the current owner.                                                      |

Tags 6 and 7 (`SetMetadata`, `RemoveMetadata`) exist in the enum but return `InvalidInstructionData` — key-value metadata is not stored on-chain; the agent wallet is a first-class field instead.

### Licensing

| Tag | Instruction      | Arguments                                          | Accounts, in order                                                                                                           | Notes                                                                                                                                                                           |
| --- | ---------------- | -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 14  | `ConsumeLicense` | `agent_id`, `workflow: Pubkey`, `workflow_id: u64` | registry, agent **w p**, license index **w p +**, license record **w p +**, consumer **s**, rent payer **s**, system program | Caller must be the admin or an authorized consumer (this is how market signs in). Fails with `NoLicensesAvailable` when supply runs out; `AlreadyLicensed` on an active record. |
| 15  | `RevokeLicense`  | `agent_id`, `workflow`, `workflow_id`              | registry, agent **p**, license record **w p**, consumer **s**                                                                | Marks the record inactive.                                                                                                                                                      |

Each license is a `LicenseRecord` PDA keyed by `(agent_id, workflow_program, workflow_id)` — so the license ledger works for any licensee program, not just market.

### Warp royalties

| Tag | Instruction                  | Arguments                                     | Accounts, in order                                         | Notes                                                                                                                                                                                                |
| --- | ---------------------------- | --------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 16  | `DistributeRoyalty`          | `warped_agent_id`, `amount: u64`              | warp **w p**, warp agent **p**                             | Permissionless. Accrues 10% of `amount` into the warp's `accumulated_royalties` while the original creator is unknown and the claim window is open. Accounting only — no tokens move.                |
| 17  | `TransferUnclaimedRoyalties` | `warped_agent_id`, `verified_creator: Pubkey` | registry, warp **w p**, treasury **s** (must be the admin) | Before the 365-day window closes, the admin can attach a verified creator to a warp and mark royalties claimed. Again state-only — actual SPL payouts go through market's `DistributeWarpRoyalties`. |

## DNA derivation

DNA is a 32-byte uniqueness marker with its own PDA (`[b"dna", dna_hash]`), so a hash can only ever mint once.

* **Register**: `sha256("ERC8004_MANOWAR" ‖ owner ‖ uri ‖ agent_id_le)` — deterministic, you can precompute it.
* **Mint**: you bring your own hash. The SDK's `computeDnaHash(skills, networkId, model)` matches the EVM-side convention.
* **Clone / Warp**: `keccak(parent_dna ‖ chain_id_be ‖ model ‖ cloner ‖ now_be)` / `keccak("WARPED" ‖ original_hash ‖ warper ‖ now_be)`. Both include the on-chain clock, so they're unique per attempt but **not reproducible client-side** — read the DNA from the transaction logs or the agent account after the fact.

## Warp royalties

Warped agents earn like any other agent, with a split that acknowledges the importer: **80% to the warper, 10% to the treasury, 10% to the original creator** — who has a 365-day window to be verified and claim. If the creator is unknown, their 10% goes to the treasury instead (so unknown creators get 0/20/80). The split itself is executed by the market program's `DistributeWarpRoyalties`; the identity program only tracks the claim state.

## State

| Account         | Seeds                                                                | Contents                                                                                                 |
| --------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `Registry`      | `[b"registry"]`                                                      | `admin`, `next_agent_id`, `total_agents`, `consumers` (max 32)                                           |
| `Agent`         | `[b"agent", agent_id_le]`                                            | The shared agent struct — see [Accounts & Encoding](/programs/accounts#the-agent-struct)                 |
| `Dna`           | `[b"dna", dna_hash]`                                                 | `dna_hash`, `agent_id`                                                                                   |
| `Warp`          | `[b"warp", original_hash]`                                           | `agent_id`, `original_creator`, `warper`, `royalty_expiry`, `royalties_claimed`, `accumulated_royalties` |
| `WarpAgent`     | `[b"warp-agent", agent_id_le]`                                       | Reverse lookup: agent → warp                                                                             |
| `IdentityStats` | `[b"identity-stats"]`                                                | `total_clones`, `total_warped`                                                                           |
| `LicenseRecord` | `[b"license-record", agent_id_le, workflow_program, workflow_id_le]` | `license_number`, `licensed_at`, `active`                                                                |
| clone index     | `[b"clone-index", parent_id_le]`                                     | `U64Index` of clone agent ids                                                                            |
| license index   | `[b"license-index", agent_id_le]`                                    | `U64Index` of workflow ids that hold a license                                                           |

## Worth knowing

* **Account space is allocated once, at creation.** An agent account is sized to its initial URI, so `SetUri` can shrink or keep the URI but never lengthen it. Pick a stable URI scheme (e.g. `ipfs://…`) from day one.
* **A revoked license can't be re-consumed.** The `LicenseRecord` PDA stays initialized after revocation, and `ConsumeLicense` refuses to reuse it — removing and re-adding the same agent to the same workflow will fail.
* **`Transfer` doesn't touch `agent_wallet`.** If your runtime assumes the wallet follows the owner, update the wallet explicitly after a transfer.
* **Clone and warp DNA include the clock.** Don't try to predict them — derive the PDA from the returned agent instead.
* **`DistributeRoyalty` moves no tokens.** It only accrues accounting state; the payout path is market's `DistributeWarpRoyalties`.

If you integrate through the SDK, DNA helpers (`computeDnaHash`, `computeExternalAgentHash`), PDA derivation (`identityPdas`), and the `identity.mint` / `identity.warp` builders handle the fiddly parts for you — see [Accounts & Encoding](/programs/accounts) and the [SDK docs](/sdk/installation).
