Lineagei
Frameworki
What's Anchor?
Batteries-included Rust framework. Ships account-validation codegen, 8-byte instruction discriminators, and an on-chain IDL — the program describes itself.
Bigger binary and higher rent in exchange for safety rails, introspection, and dev speed. The choice of a team optimizing for correctness over on-chain footprint.
Originally Coral (Armani Ferrante); now community-maintained.
What it is
The de facto standard. Rust macros (#[program], #[derive(Accounts)]) eliminate boilerplate: it auto-generates 8-byte account and instruction discriminators — SHA256("account:<Name>")[..8] and SHA256("global:<ix>")[..8] — handles Borsh (de)serialization, enforces account constraints declaratively (mut, has_one, seeds, init), and emits a JSON IDL that client libraries consume directly. The cost: Borsh copies data on every deserialize (not zero-copy), and the macro machinery adds binary bloat and compute overhead — irrelevant for ~99% of programs.
When to pick it
Building a new protocol, moving fast, or wanting maximum ecosystem compatibility. It's the beginner default and stays the right call for most production programs.
How it looks on-chain
The most recognizable framework. Every account it owns begins with an 8-byte discriminator, and the IDL is often published on-chain at a PDA derived from the program id. Both are strong, reliable fingerprints — this is the only framework we can label with confidence.
Others in the wild: Steel (Ore team — near-native performance on solana-program), Seahorse (Python → Anchor), and Poseidon & Quasar (TypeScript → Rust). Transpilers inherit their lowering target's fingerprint: a Quasar or Poseidon program that compiles down to Anchor will look like Anchor on-chain — discriminators and all.
Anchor docsFootprinti
Recovered architecturei
Reachi
Controli
What's upgrade authority?
The upgrade authority is the account allowed to replace a program's code after it's deployed.
If it's set (mutable), that key can push new bytecode at any time — including malicious code, the classic "rug" vector. If it's null (immutable / frozen), the code can never change; what 's on-chain is final. A Squads multisig sits in between — upgrades are possible but need M-of-N signers, not one hot wallet. So mutable + single hot-wallet = highest risk; immutable or multisig = stronger guarantees.
What's a verified build?
A verified build proves the program running on-chain was compiled from the public source you can read — nothing hidden.
Someone re-compiles the source in a deterministic (Docker) environment and checks the resulting bytecode is byte-for-byte identical to what's deployed; tools like solana-verify do this and record it with a verification service. "Not verified" isn't a red flag by itself — most programs simply never submit one. It just means you're trusting the deployed bytecode as-is, with no source cross-check.
Convictioni
Interface — the on-chain IDLi
4 of 8 instructions used · 4 never called in this window
Otomat x402 settlement rail program
Instructions 8
close_channel
Cooperatively close a channel: settle `cumulative_amount` to the payee, refund the remainder, and close the account. Requires a payer-signed check verified through the Ed25519 pre-instruction.
- facilitatorsignerwritable
- channelwritable
- payerwritable
- payee
- mint
- escrow_authority
- escrow_atawritable
- payee_atawritable
- payer_atawritable
- instructions
- token_program
- system_program
- cumulative_amountu64
- nonceu64
- signature[u8; 64]
commit_receipt
Commit an on-chain receipt for an `exact`-scheme (single) settlement.
- facilitatorsignerwritable
- payer
- payee
- mint
- receiptwritable
- system_program
- amountu64
- resource_hash[u8; 32]
- nonceu64
- schemeu8
dispute_channel
Submit a newer payer-signed check to open (or extend) the dispute window.
- submittersignerwritable
- channelwritable
- instructions
- counter_cumulativeu64
- counter_nonceu64
- counter_signature[u8; 64]
open_channel
Open and fund a payer -> payee escrow channel.
- payersignerwritable
- payee
- mint
- channelwritable
- escrow_authority
- escrow_atawritable
- payer_atawritable
- token_program
- associated_token_program
- system_program
- depositu64
- expiryi64
- facilitatorpubkey
open_facilitator_bond
Post a facilitator bond into a program-owned vault.
- operatorsignerwritable
- bond_mint
- bondwritable
- bond_vaultwritable
- operator_atawritable
- token_program
- associated_token_program
- system_program
- amountu64
resolve_dispute
Finalise a disputed/unilaterally-closed channel after the challenge window.
- resolversignerwritable
- channelwritable
- payerwritable
- payee
- mint
- escrow_authority
- escrow_atawritable
- payee_atawritable
- payer_atawritable
- token_program
- system_program
slash_facilitator
Slash a facilitator bond by `amount`; governance-signed.
- governancesigner
- operator
- bondwritable
- bond_mint
- bond_vaultwritable
- slash_destinationwritable
- token_program
- amountu64
- reason_hash[u8; 32]
timeout_reclaim
Reclaim the escrow to the payer once a channel has expired without a close.
- payersignerwritable
- channelwritable
- payee
- mint
- escrow_authority
- escrow_atawritable
- payer_atawritable
- token_program
- system_program
Accounts 3
Channel
no fields
FacilitatorBond
no fields
Receipt
no fields
Types 11
Channelstruct
- payerpubkeyFunder of the escrow; the only party whose Ed25519 checks are honoured.
- payeepubkeyRecipient of settled funds.
- mintpubkeySPL Token or Token-2022 mint escrowed by this channel.
- facilitatorpubkeySettlement signer authorised to cooperatively close the channel.
- depositu64Total amount the payer deposited into escrow.
- cumulative_paidu64Highest cumulative amount recorded from a verified check.
- nonceu64Highest check nonce recorded; monotonically increasing.
- expiryi64Unix timestamp after which the payer may `timeout_reclaim`.
- statusChannelStatusCurrent lifecycle status.
- dispute_window_endi64Unix timestamp at which the dispute window closes (0 when not disputing).
- bumpu8Bump for the channel PDA.
- escrow_bumpu8Bump for the escrow-authority PDA that owns the vault.
ChannelClosedstruct
- channelpubkey
- cumulative_paidu64
- refundu64
- nonceu64
ChannelDisputedstruct
- channelpubkey
- counter_cumulativeu64
- counter_nonceu64
ChannelOpenedstruct
- channelpubkey
- payerpubkey
- payeepubkey
- depositu64
ChannelReclaimedstruct
- channelpubkey
- payerpubkey
- mintpubkey
- amountu64
- timestampi64
ChannelStatusenum
- Open
- CloseInitiated
- Closed
- Disputed
FacilitatorBondstruct
- operatorpubkey
- bond_amountu64Amount originally bonded into the vault.
- bond_mintpubkeyMint of the bonded asset (OTOMAT / USDC / SOL wrapper in v1).
- slashedu64Cumulative amount slashed so far.
- activeboolWhether the operator is still an active facilitator.
- last_settle_tsi64Unix timestamp of the last settlement bookkeeping update.
FacilitatorBondedstruct
- operatorpubkey
- amountu64
FacilitatorSlashedstruct
- operatorpubkey
- amountu64
- reason_hash[u8; 32]
Receiptstruct
- payerpubkey
- payeepubkey
- amountu64
- mintpubkey
- resource_hash[u8; 32]`sha256(resource_url)` bound to the payment.
- nonceu64
- timestampi64
- schemeu8`0` = exact, `1` = otomat-channel, `2` = otomat-stream.
ReceiptCommittedstruct
- payerpubkey
- payeepubkey
- amountu64
- resource_hash[u8; 32]
- schemeu8
Events 7
ChannelClosed
no fields
ChannelDisputed
no fields
ChannelOpened
no fields
ChannelReclaimed
no fields
FacilitatorBonded
no fields
FacilitatorSlashed
no fields
ReceiptCommitted
no fields
Errors 18
- 6000InvalidSignatureEd25519 signature does not match the expected channel check
- 6001NonceNotIncreasingNonce must strictly increase over the last recorded check
- 6002CumulativeExceedsDepositCumulative amount exceeds the channel deposit
- 6003CumulativeRegressionCounter check cumulative may not fall below the recorded settled amount
- 6004ChannelExpiredChannel has already expired
- 6005ChannelNotExpiredChannel has not yet reached its expiry
- 6006InvalidChannelStatusChannel status does not permit this operation
- 6007MissingEd25519InstructionEd25519 pre-instruction is missing at index 0
- 6008MessageMismatchSigned message does not match the reconstructed check
- 6009InvalidTokenProgramToken program is not a supported SPL Token or Token-2022 program
- 6010FacilitatorMismatchSigner is not the facilitator registered on this channel
- 6011GovernanceMismatchSigner is not the configured governance authority
- 6012BondInsufficientSlash amount exceeds the remaining bonded balance
- 6013BondAlreadyActiveOperator already has an active bond
- 6014DisputeWindowActiveDispute challenge window has not yet elapsed
- 6015InvalidSchemeUnknown payment scheme identifier
- 6016ZeroAmountAmount must be greater than zero
- 6017InvalidExpiryExpiry must be in the future
What's an IDL?
An IDL — Interface Description Language — is a JSON spec that describes how to talk to a program: its instructions, the accounts each one needs, argument and account types, events, and errors.
Anchor auto-generates it at build time. A program can publish it on-chain at a PDA derived from its id, so any client or explorer can decode the program's transactions without its source code.
Why it's often missing
Publishing is opt-in — a courtesy, not a requirement. Many programs never do, and non-Anchor frameworks (Pinocchio, native, Steel) don't produce one at all; their interface lives in an off-chain Shank/Codama artifact, or nowhere public. Absence means you can't auto-decode it — not that anything is wrong.
4 of 8 instructions used · 4 never called in this window · +1 more
Tractioni
Code familyi
The recordi
| Event | When | Detail | Receipt |
|---|---|---|---|
| UPGRADE | 10h ago | slot 432,685,538 | poll…5538 |
| UPGRADE | 10h ago | slot 432,680,668 | poll…0668 |
| UPGRADE | 1d ago | slot 432,445,567 | poll…5567 |
| DEPLOY | 1d ago | slot 432,389,442 | poll…9442 |
| SIBLING DEPLOY | 3d ago | meanwhile_treasury | same code, fresh id |