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
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
AWorkflow 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).
MintWorkflow accounts — and the licensing CPI
MintWorkflow takes 13 fixed accounts, then 4 accounts per agent you compose in:
market-authority PDA, and splits that agent’s license_price:
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.
AddAgentlater works — but only within the space already allocated (and the 64-agent cap). Mint with the slots you plausibly need.
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.
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%).
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.
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):Worth knowing
pauseddoesn’t gate anything yet.Pause/Unpauseset 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 torecipients[n].recipient— the SDK always builds the list from the same array, but if you hand-assemble accounts, order is safety-critical. ConsumeUnitandCreateLeasemove no tokens. Counters and state only. Revenue flows throughDistribute/DistributeLease— compose them in the same transaction if you need atomicity.ProposeChildis 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,
AcceptAgentwill fail. The SDK’smarket.createRfabuilder 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.
encodeMarketInstruction, the full marketPdas helper set, and typed decoders for every account below.