manowar crate, and used identically by all four programs. Read this before the per-program pages, or jump here whenever they reference it.
Account serialization
Every state account is a 4-byte little-endian length header followed by a borsh payload:
You don’t need to do this manually. The SDK has a typed decoder per account:
PDA conventions
All PDAs derive with the standardfindProgramAddress under the owning program. Two conventions cover the whole suite:
- Seed constants are short ASCII strings (
b"agent",b"workflow",b"rfa"…). - Integer ids become 8-byte little-endian seeds (
agent_id = 42→2a 00 00 00 00 00 00 00).
ManowarSeeds and exposes ready-made finders:
Agent PDA is always derived under the identity program, no matter which program is reading it, and the reader verifies the account’s owner on-chain. Pass the canonical identity program ID from Deployed Contracts.
The Agent struct
One struct, defined in the shared crate, stored by identity, read by everyone:Indexes
Lookup lists share two structs —U64Index { version, page, total, values: Vec<u64> } and PubkeyIndex (same shape, Vec<Pubkey>) — both capped at 64 entries. page is reserved for future paging; today there is exactly one page, and a full index fails writes with AccountTooSmall. The market program keeps its discovery lists (complete workflows, open RFAs, per-creator, per-leaser…) in these; reputation uses them for client lists; validation for per-agent requests.
Errors
All four programs return one shared error enum asProgramError::Custom(n). When a transaction fails with Custom(17), that’s AlreadyLicensed.