Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.ryvo.network/llms.txt

Use this file to discover all available pages before exploring further.

Ryvo stores protocol state in global singletons plus bucketed state accounts. This page describes the live bucket architecture and canonical PDA seeds.

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.

Participant buckets

Participant state is bucketed. A participant ID maps to one slot inside one ParticipantBucket. Seeds: ["participant-bucket-v2", bucket_id (LE u32)] Live sizing constants:
  • PARTICIPANT_BUCKET_SLOT_COUNT = 9
  • MAX_BUCKET_TOKEN_BALANCES = 16
Routing from participant_id:
  • bucket_id = participant_id / 9
  • slot_index = participant_id % 9
Each participant slot stores:
  • owner
  • participant_id
  • inbound_channel_policy
  • BLS registration fields (bls_scheme_version, bls_pubkey_compressed)
  • up to 16 token-balance entries (available_balance, withdrawing_balance, withdrawal_unlock_at, withdrawal_destination)

Owner index buckets

Owner lookup is bucketed separately so owner -> participant_id resolution stays deterministic. Seeds: ["owner-index-bucket-v2", bucket_id (LE u32)] Live sizing constants:
  • OWNER_INDEX_BUCKET_COUNT = 1024
  • OWNER_INDEX_BUCKET_SLOT_COUNT = 32
Routing from owner:
  • bucket_id = sha256(owner)[0..4] % 1024

Channel buckets

Channel state is also bucketed by token and participant pair ordinal. Seeds: ["channel-bucket-v2", token_id (LE u16), bucket_id (LE u32)] Live sizing constants:
  • CHANNEL_BUCKET_SLOT_COUNT = 46
Each slot stores one canonical participant pair (lower_participant_id, higher_participant_id) and two directional lanes:
  • lower_to_higher
  • higher_to_lower
Each directional lane stores:
  • settled_cumulative
  • locked_balance
  • authorized_signer
  • pending unlock fields
  • pending signer-rotation fields
Canonical lane selection is derived from (payer_id, payee_id) ordering, so settlement always writes one deterministic lane per direction.

Protocol vault

Tokens deposited into Ryvo 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