Skip to main content
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"] 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"] Each TokenEntry (51 bytes): 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