Skip to content
Fossa

Offers

Prices, capacity, offer updates, and provider collateral.

Publish an offer

Send instruction 2 with [market, model, terms(w), capacity(w), provider_profile, provider(s), payout, bond_vault]. Its 24-byte payload contains slot:u32 at 0; input, cached-input, and output rates as three u32 values at 4, 8, and 12; speed:u16 at 16; privacy:u8 at 18; active:u8 at 19; and concurrent booking capacity as u32 at 20.

Rates use atomic payment units per million tokens. The payment mint has six decimals. Input and output rates must be positive, cached rate cannot exceed input rate, speed and capacity must be positive, and both flags must be 0 or 1. Speed is the declared tokens-per-second value used in matching and claim deadlines.

The slot must equal the current count in both books and remain below their limit. Slots append permanently and are never reassigned. A provider's first offer in this model uses the eight accounts above. If it already owns any slot in the model, append admin(s) as the ninth account unless the provider itself is the administrator. Inactive or unapproved earlier offers still count. Additional variants need this authorization to prevent one admitted provider from consuming all remaining slots. Existing offers remain valid and can still be updated through instruction 5.

The contract validates the payout and bond vault against the market mint and their respective authorities. The bond authority PDA is [b"bond", model, slot.to_le_bytes()]. The offer records these identities and begins with its own approval flag set to 1.

Read prices and available capacity

Read the model's canonical terms and capacity books together with getMultipleAccounts. Their discriminators are TERMSV20 and CAPACV20. Each 48-byte header contains the model key at 8, slot limit at 40, and appended count at 44. Both books must reference the same model and agree on the count. Entries beyond that count are unused.

For slot i, the terms entry starts at 48 + i × 120. Relative offsets are provider 0, payout 32, bond vault 64, input/cached/output rates 96/100/104, declared speed 108, privacy 110, active 111, approval 112, bond bump 113, and concurrency limit 116. Public keys occupy 32 bytes; rates and concurrency are u32, speed is u16, and flags are u8.

The corresponding capacity entry starts at 48 + i × 32: funded bond at 0 and exposure at 8 are u64; active bookings at 16 and obligations at 20 are u32; pending unbond at 24 is u64. Inspect active and approval flags, requested rate caps, speed, privacy, concurrency headroom, and collateral headroom together. A displayed price alone does not establish eligibility. Pending unbond has already been deducted from funded bond.

Update terms and metadata

Instruction 5 uses [market, model, terms(w), provider(s)] and the same 24-byte payload as offer registration. The signer must own the selected slot. It can change rates, declared speed, privacy, active state, and concurrency limit; provider identity, payout, bond vault, and approval remain fixed. Existing bookings retain their copied terms.

Instruction 16 uses [market, model, terms(w), admin(s)], payload slot:u32 followed by approved:u8. Only the market administrator can change this flag. Revoking profile approval through instruction 20 prevents new models and offers; existing offers require their own approval change to stop new matching.

Instruction 21 updates provider metadata with [market, provider_profile(w), provider(s)]. Instruction 22 updates model metadata with [market, model, model_metadata(w), creator(s)]. Both accept a new 32-byte hash followed by URI bytes. The recorded authority must sign, and neither instruction transfers that authority. Metadata accounts are absent from the matching and settlement account lists.

Fund provider collateral

Send instruction 4 with [market, model, terms, capacity(w), provider(s), source(w), bond_vault(w), mint, token_program], payload slot:u32 then amount:u64. The amount must be positive. The slot's provider signs a checked token transfer from its source account into the recorded bond vault; funded bond increases by that amount.

Exposure includes reserves for unfinished bookings and charges still subject to dispute. New bookings require funded bond to cover total exposure plus ceil(exposure / 100) atomic units. This one-percent margin is collateral. Pending withdrawals cannot back another booking. Each offer has its own collateral accounting and bond authority.

Withdraw provider collateral

Request unbonding through instruction 13, accounts [market, model, terms, capacity(w), provider(s), request(ws), rent_payer(s)], payload slot:u32 then amount:u64. Precreate a zeroed, program-owned 160-byte request account. The slot's provider signs and the amount must be positive. Remaining funded bond must cover current exposure plus its one-percent margin.

The requested amount leaves funded bond immediately and enters pending unbond. The request records market, provider, amount, slot, model, rent payer, and a ready time of now + UNBOND_SECONDS: 3,600 seconds in the standard build.

Once ready, execute instruction 14 with [market, model, terms, capacity(w), request(w), provider(s), bond_vault(w), payout(w), mint, bond_authority, token_program], empty payload. The provider signs; the request must be unexecuted and match its recorded identities. A checked transfer sends the amount to the offer's payout, pending unbond decreases, and the request becomes executed.