Skip to main content
Agon stores all protocol state in four account types, each held at a canonical PDA. This page describes their layouts, seeds, and roles.

GlobalConfig

Singleton account holding protocol-wide configuration. Seeds: ["global-config"]
FieldTypeNotes
authorityPubkeyActive config authority
fee_recipientPubkeyReceives withdrawal fees and registration fees
fee_bpsu16Withdrawal fee in basis points (3–30)
withdrawal_timelock_secondsi64Fixed at initialize time by chain ID
registration_fee_lamportsu64Flat SOL fee charged at initialize_participant
next_participant_idu32Monotonic counter for new participants
bumpu8PDA bump
chain_idu16Deployment chain ID, fixed at initialize
message_domain[u8; 16]Deployment-scoped signing domain
pending_authorityPubkeyNominated successor (two-step handoff)
_reserved[u8; 14]Future expansion
chain_id and message_domain are immutable after initialize. Updating them would require a fresh deployment.

TokenRegistry

Singleton account holding the allowlist of supported settlement tokens. Seeds: ["token-registry"]
FieldTypeNotes
authorityPubkeyRegistry authority — can register new tokens
tokensVec<TokenEntry>Up to 198 entries
bumpu8PDA bump
pending_authorityPubkeyNominated successor (two-step handoff)
Each TokenEntry (51 bytes):
FieldTypeNotes
idu16Unique token_id used in signed messages
mintPubkeySPL token mint
decimalsu8Token decimals (≤ 20)
symbol[u8; 8]ASCII symbol, null-terminated
registered_ati64Unix timestamp of registration (immutable)
A registered (id, mint) mapping is immutable. The registry authority cannot swap which mint a token_id refers to.

ParticipantAccount

One account per registered wallet. Holds all per-token balances and the inbound channel policy. Seeds: ["participant", owner_pubkey]
FieldTypeNotes
ownerPubkeyWallet that owns this participant
participant_idu32Permanent protocol identity
token_balancesVec<TokenBalance>Up to 16 entries
bumpu8PDA bump
inbound_channel_policyu8Permissionless / ConsentRequired / Disabled
_reserved[u8; 7]Future expansion
Each TokenBalance:
FieldTypeNotes
token_idu16Registered token
available_balanceu64Spendable balance
withdrawing_balanceu64Amount queued for withdrawal
withdrawal_unlock_ati64Timelock unlock timestamp
withdrawal_destinationPubkeyFixed destination token account
Participant identities are permanent: the participant_id never changes, and the PDA is bound to owner. See Participants.

ChannelState

One account per one-way channel (payer, payee, token). Seeds: ["channel-v2", payer_id (LE u32), payee_id (LE u32), token_id (LE u16)]
FieldTypeNotes
token_idu16Settlement token
payer_idu32Payer participant ID
payee_idu32Payee participant ID
settled_cumulativeu64Highest cumulative amount ever settled
locked_balanceu64Funds earmarked for this channel
authorized_signerPubkeyKey that signs agon-cmt-v5 for this channel
pending_unlock_amountu64Amount in a pending unlock request
unlock_requested_ati64Timestamp of pending unlock
pending_authorized_signerPubkeyNominated new signer
authorized_signer_update_requested_ati64Timestamp of pending rotation
bumpu8PDA bump
Channels are permanent. Both settled_cumulative and the PDA persist for the life of the deployment, so replays of older commitments always lose against the highest cumulative already seen.

Protocol vault

Tokens deposited into Agon live in per-token vault token accounts derived from the program. They are SPL Token accounts owned by the program, not participant balances. Participant available_balance and channel locked_balance are ledger positions against this vault — the vault is the single source of truth for tokens actually held by the program. See Balances and withdrawals for how the vault relates to participant state.

See also