> ## 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.

# Accounts

> The on-chain account layouts used by the Ryvo protocol.

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"]`

| Field                         | Type       | Notes                                            |
| ----------------------------- | ---------- | ------------------------------------------------ |
| `authority`                   | `Pubkey`   | Active config authority                          |
| `fee_recipient`               | `Pubkey`   | Receives withdrawal fees and registration fees   |
| `fee_bps`                     | `u16`      | Withdrawal fee in basis points (3–30)            |
| `withdrawal_timelock_seconds` | `i64`      | Fixed at initialize time by chain ID             |
| `registration_fee_lamports`   | `u64`      | Flat SOL fee charged at `initialize_participant` |
| `next_participant_id`         | `u32`      | Monotonic counter for new participants           |
| `bump`                        | `u8`       | PDA bump                                         |
| `chain_id`                    | `u16`      | Deployment chain ID, fixed at initialize         |
| `message_domain`              | `[u8; 16]` | Deployment-scoped signing domain                 |
| `pending_authority`           | `Pubkey`   | Nominated 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"]`

| Field               | Type              | Notes                                        |
| ------------------- | ----------------- | -------------------------------------------- |
| `authority`         | `Pubkey`          | Registry authority - can register new tokens |
| `tokens`            | `Vec<TokenEntry>` | Up to 198 entries                            |
| `bump`              | `u8`              | PDA bump                                     |
| `pending_authority` | `Pubkey`          | Nominated successor (two-step handoff)       |

Each `TokenEntry` (51 bytes):

| Field           | Type      | Notes                                      |
| --------------- | --------- | ------------------------------------------ |
| `id`            | `u16`     | Unique `token_id` used in signed messages  |
| `mint`          | `Pubkey`  | SPL token mint                             |
| `decimals`      | `u8`      | Token decimals (≤ 20)                      |
| `symbol`        | `[u8; 8]` | ASCII symbol, null-terminated              |
| `registered_at` | `i64`     | Unix 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](/core-concepts/balances-and-withdrawals) for how the vault relates to participant state.

## See also

* [Instructions](/reference/instructions)
* [Events](/reference/events)
* [On-chain properties](/security/properties)
