> ## 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.

# Market

> Workflows, RFA escrow, leases, royalties, and payment splits — the composition layer on Solana.

The market program is the composition layer: workflows (ERC-7401-style groups of agents), the licensing hook into [identity](/programs/identity), RFA escrow, time-based leases, a royalty registry, and generic payment splitting. On EVM this surface is six separate contracts; here it's one program, organized into modules (`workflow`, `rfa`, `lease`, `royalty`, `payment`) — that's a code layout, not an on-chain boundary.

Program ID (devnet): `7B3dAgwdmWK3YnobSPYP5fPYNp7x8btNs5GMCD498uo8`

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

## Admin surface

| Tag   | Instruction         | Arguments                                        | Notes                                                                       |
| ----- | ------------------- | ------------------------------------------------ | --------------------------------------------------------------------------- |
| 0     | `Initialize`        | `treasury_token: Pubkey`, `payment_mint: Pubkey` | One-time. Sets the treasury token account and the payment mint (USDC).      |
| 1     | `InitializeConfig`  | —                                                | Creates the config PDA (snapshot of treasury + mint). Registry admin only.  |
| 2     | `TransferAdmin`     | `new_admin: Pubkey`                              | Single-step, no zero address.                                               |
| 3 / 4 | `Pause` / `Unpause` | —                                                | Flips `config.paused` — see [Worth knowing](#worth-knowing).                |
| 5     | `SetTreasury`       | `treasury_token: Pubkey`                         | Updates registry (and config, if initialized).                              |
| 6     | `RegisterProgram`   | `id: [u8;32]`, `address: Pubkey`                 | Records external programs in config (max 16). Currently informational only. |

Admin calls take `[registry w, admin s]` (plus `config w` where relevant). The admin lives in the market registry — it's a different key from the identity admin.

## Workflows

A `Workflow` is a priced bundle of agents: `total_price` is the sum of its agents' license prices, `units` is the run supply, and an optional coordinator model orchestrates the group. Children from *other* programs can also be attached ERC-7401-style via propose/accept/reject, indexed by `(child_program, child_id)`.

| Tag   | Instruction                                    | Arguments                                                                                                                                                                                | Notes                                                                                                                                                      |
| ----- | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 7     | `MintWorkflow`                                 | `title`, `description`, `banner`, `uri` (strings), `units: u64`, `lease_enabled: bool`, `lease_duration: u64`, `lease_percent: u8`, `has_coordinator: bool`, `coordinator_model: String` | The big one — accounts below. `units` must be > 0; `lease_percent ≤ 20`.                                                                                   |
| 8     | `AddAgent`                                     | `workflow_id`                                                                                                                                                                            | Owner only. Same licensing + payment flow as minting. Cap: 64 agents.                                                                                      |
| 9     | `RemoveAgent`                                  | `workflow_id`, `agent_id`                                                                                                                                                                | Owner only. Revokes the license via CPI and subtracts the agent's price from `total_price`. No refund of the original license fee.                         |
| 10    | `SetCoordinator`                               | `workflow_id`, `has_coordinator`, `model`                                                                                                                                                | Owner only.                                                                                                                                                |
| 11    | `UpdateLeaseSettings`                          | `workflow_id`, `enabled`, `duration`, `percent`                                                                                                                                          | Owner only; `percent ≤ 20` enforced when enabling.                                                                                                         |
| 12    | `ConsumeUnit`                                  | `workflow_id`, `buyer: Pubkey`                                                                                                                                                           | Buyer signs. Increments `units_minted`; `NoLicensesAvailable` when sold out. Moves no tokens — payment composition is up to the caller (see `Distribute`). |
| 13–15 | `ProposeChild` / `AcceptChild` / `RejectChild` | `workflow_id`, `child_program: Pubkey`, `child_id: u64`                                                                                                                                  | Propose is permissionless; accept/reject are owner-only and move the id between pending and accepted index PDAs.                                           |

### MintWorkflow accounts — and the licensing CPI

`MintWorkflow` takes 13 fixed accounts, then **4 accounts per agent** you compose in:

```
[ registry w, workflow w+p+, creator index w+p+, complete index w+p+,
  owner s, identity program, identity registry w, market authority p,
  token program, payer token w, treasury token w, rent payer s, system program ]
  …then per agent: [ agent w, license index w, license record w+p+, creator token w ]
```

For every agent in the list, the program verifies the agent in identity, consumes a license via CPI signed by the `market-authority` PDA, and splits that agent's `license_price`:

```mermaid theme={null}
sequenceDiagram
    participant Owner
    participant Market
    participant Identity
    participant Token as SPL Token

    Owner->>Market: MintWorkflow(agents[])
    loop per agent
        Market->>Identity: CPI ConsumeLicense (market-authority PDA signs)
        Market->>Token: 90% of license_price → agent creator
        Market->>Token: 10% → treasury
    end
    Market-->>Owner: workflow_id
```

Two consequences worth internalizing:

* **The market authority must be an authorized consumer in identity** (`identity.Authorize`), or every licensing CPI fails. That's a one-time admin setup step per deployment.
* **The workflow account is sized for the agent count at mint time.** `AddAgent` later works — but only within the space already allocated (and the 64-agent cap). Mint with the slots you plausibly need.

The SDK builds this whole account list for you, including the per-agent groups: `chain.solana.market.mintWorkflow(...)`.

## RFA — Request For Agent

An RFA is an escrowed bounty for a missing agent: the workflow publisher locks USDC, a developer submits an agent, and acceptance releases the escrow to the agent's creator.

| Tag | Instruction   | Arguments                                                                                   | Notes                                                                                                                                                                      |
| --- | ------------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 16  | `CreateRfa`   | `workflow_id`, `title`, `description`, `required_skills: Vec<[u8;32]>`, `offer_amount: u64` | Publisher signs and must own the workflow. `offer_amount > 0`, 1–32 skills. Escrows the full offer into a token account owned by the RFA PDA. One active RFA per workflow. |
| 17  | `SubmitAgent` | `rfa_id`, `agent_id`                                                                        | Only the agent's **creator** (per identity) may submit it. RFA must be open.                                                                                               |
| 18  | `AcceptAgent` | `rfa_id`, `agent_id`                                                                        | Publisher only. Releases escrow to the creator's token account (RFA PDA signs), marks the RFA fulfilled.                                                                   |
| 19  | `CancelRfa`   | `rfa_id`                                                                                    | Publisher only. Refunds the escrow.                                                                                                                                        |

Skill hashes are `keccak256(lowercase(skill))` — the SDK's `encodeSkillAsBytes32` does exactly this. The workflow moves between the "complete" and "has-open-RFA" index PDAs as the RFA opens and resolves, which is how discovery stays cheap.

## Leases

A lease rents a workflow's composition to another user for a fixed time, splitting usage revenue between the leaser and the workflow's creator (creator share capped at 20%).

| Tag | Instruction           | Arguments                           | Notes                                                                                                                                    |
| --- | --------------------- | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| 20  | `CreateLease`         | `workflow_id`, `duration_days: u64` | Anyone can lease a workflow with `lease_enabled` and no active lease. Snapshots the creator and `lease_percent`. No payment at creation. |
| 21  | `TerminateLease`      | `lease_id`                          | Leaser or creator. Ends it early.                                                                                                        |
| 22  | `ExpireLeaseIfNeeded` | `lease_id`                          | Permissionless crank — anyone can expire a lease past its `end_time`.                                                                    |
| 23  | `DistributeLease`     | `lease_id`, `amount: u64`           | Payer signs and funds the split: `creator_percent%` to the creator, remainder to the leaser. Fails on inactive/expired leases.           |

One workflow, one active lease: an `active-lease` PDA per workflow points at the current `lease_id`, cleared on terminate/expire.

## Royalties

An ERC-2981-style royalty table: a default `(receiver, fee_bps)` plus per-token overrides, both admin-set, denominated in basis points of 10 000.

| Tag | Instruction         | Notes                                                                |
| --- | ------------------- | -------------------------------------------------------------------- |
| 24  | `SetDefaultRoyalty` | Admin only.                                                          |
| 25  | `SetRoyalty`        | Admin only; per `token_id`. `receiver` non-zero, `fee_bps ≤ 10_000`. |
| 26  | `DeleteRoyalty`     | Admin only; clears the override (account stays).                     |

This is a **registry, not an enforcement hook** — nothing moves on sales automatically. Marketplaces read the table and settle royalties themselves.

## Payments

Two generic splitters, usable with any flow (unit sales, inference revenue, warp payouts):

| Tag | Instruction               | Arguments                                                         | Notes                                                                                                                                                                                                                                                       |
| --- | ------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 27  | `Distribute`              | `recipients: Vec<Recipient>`, `total_amount: u64`                 | 1–16 recipients; `share_bps` must sum to exactly 10 000; the last recipient absorbs rounding dust. Accounts: payer **s**, token program, payer token **w**, then one recipient token account per recipient.                                                 |
| 28  | `DistributeWarpRoyalties` | `original_creator: Pubkey`, `warper: Pubkey`, `total_amount: u64` | The warp split as real transfers: 10% creator / 10% treasury / 80% warper — or 20% treasury / 80% warper when `original_creator` is the zero pubkey. Mirrors the identity-side accounting described in [Warp royalties](/programs/identity#warp-royalties). |

## Worth knowing

* **`paused` doesn't gate anything yet.** `Pause`/`Unpause` set the flag; no instruction checks it today. Don't rely on it as a circuit breaker.
* **Recipient token accounts are positional in `Distribute`.** The program pays the *n*-th token account it receives without checking it belongs to `recipients[n].recipient` — the SDK always builds the list from the same array, but if you hand-assemble accounts, order is safety-critical.
* **`ConsumeUnit` and `CreateLease` move no tokens.** Counters and state only. Revenue flows through `Distribute` / `DistributeLease` — compose them in the same transaction if you need atomicity.
* **`ProposeChild` is permissionless.** Spam entries are bounded by the 64-entry index cap per (workflow, child program), and only the owner can accept.
* **The RFA escrow account's authority is the RFA PDA.** Release works because the program signs with the PDA's seeds; if you create the escrow token account with any other authority, `AcceptAgent` will fail. The SDK's `market.createRfa` builder wires this correctly.
* **Fees are fixed constants**, not config: 10% treasury on license sales, ≤20% creator share on leases, 10/10/80 warp royalties. Changing them means a program upgrade.

For anything past the builders, the SDK exposes the raw pieces — `encodeMarketInstruction`, the full `marketPdas` helper set, and typed decoders for every account below.

## State

| Account                      | Seeds                                                                                                                                                                                                                                                                                                                                                                         | Contents                                                                                                                                                          |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Registry`                   | `[b"registry"]`                                                                                                                                                                                                                                                                                                                                                               | `admin`, `treasury_token`, `payment_mint`, `next_workflow_id`, `next_rfa_id`, `next_lease_id`, `total_workflows`, `total_escrowed`                                |
| `MarketConfig`               | `[b"market-config"]`                                                                                                                                                                                                                                                                                                                                                          | `admin`, `paused`, treasury/mint snapshot, `registered_programs` (max 16)                                                                                         |
| `Workflow`                   | `[b"workflow", workflow_id_le]`                                                                                                                                                                                                                                                                                                                                               | `owner`, `creator`, strings, `total_price`, `units`/`units_minted`, lease settings, coordinator, `has_active_rfa`, `active_lease_id`, `agents: Vec<u64>` (max 64) |
| market authority             | `[b"market-authority"]`                                                                                                                                                                                                                                                                                                                                                       | No data — a PDA that only exists to sign identity CPIs                                                                                                            |
| `Rfa`                        | `[b"rfa", rfa_id_le]`                                                                                                                                                                                                                                                                                                                                                         | `workflow_id`, `required_skills`, `offer_amount`, `publisher`, `status` (open/fulfilled/cancelled), `fulfilled_by_agent_id`, `agent_creator`                      |
| `Submission`                 | `[b"submission", rfa_id_le, agent_id_le]`                                                                                                                                                                                                                                                                                                                                     | `creator`, `submitted_at`                                                                                                                                         |
| `Lease`                      | `[b"lease", lease_id_le]`                                                                                                                                                                                                                                                                                                                                                     | `workflow_id`, `leaser`, `creator`, `start_time`, `end_time`, `creator_percent`, `status` (active/expired/terminated)                                             |
| `ActiveLease`                | `[b"active-lease", workflow_id_le]`                                                                                                                                                                                                                                                                                                                                           | Current `lease_id` per workflow                                                                                                                                   |
| `Royalty` / `DefaultRoyalty` | `[b"royalty", token_id_le]` / `[b"default-royalty"]`                                                                                                                                                                                                                                                                                                                          | `receiver`, `fee_bps`                                                                                                                                             |
| discovery indexes            | `[b"creator-workflow-index", owner]`, `[b"complete-workflow-index"]`, `[b"rfa-workflow-index"]`, `[b"open-rfa-index"]`, `[b"rfa-index", workflow_id_le]`, `[b"publisher-rfa-index", publisher]`, `[b"submission-index", rfa_id_le]`, `[b"lease-index", leaser]`, `[b"child-index", workflow_id_le, child_program]`, `[b"pending-child-index", workflow_id_le, child_program]` | `U64Index` lists (max 64 entries each) for cheap lookups                                                                                                          |
