The Ring program
offrecord-ring is the one program that governs every note of the Ring. It verifies the Ring’s proofs, then signs the Solana Privacy Program’s instructions.
Ids
Read from the Ring as this loads.
Reading the Ring
- Ring program
- Reading the Ring
- Ring account
- Reading the Ring
- Fee vault
- Reading the Ring
- Relayer
- Reading the Ring
The same values come from ring() in the SDK.
Accounts
| Account | Owned by | Holds |
|---|---|---|
| Ring account | The Ring program | The auditor key, the policy hash, the four role keys, the exit fee rate and the pause flag. It binds the addresses of the two registries. |
| Enrollment registry | The storage program | One row per account: a wallet’s shielded keys, written once. Its root is what a spend proves ownership against. |
| Block list registry | The storage program | The block list entries under one root. Every transfer proves against it. |
| Fee vault | The Ring program | A program address no key signs for. It collects the exit fee, with one token account per mint, created on first use. |
| Ring authority | The Ring program | The program address that signs the Solana Privacy Program’s ring instructions. |
Instructions
| Instruction | Signed by | What it does |
|---|---|---|
| initialize | The upgrade authority | Creates the Ring account with the role keys, fixes the auditor key and the policy for the Ring’s life, and registers the Ring with the Solana Privacy Program. |
| enroll | The enrollment writer | Writes a batch of accounts’ shielded keys to the enrollment registry. Each owner’s signature is checked. |
| deposit | The funding wallet | Moves an asset from a public wallet into the Ring’s notes. |
| transact | The fee payer | Verifies the Ring proof, checks the exit fee leg on withdrawals, then signs the Solana Privacy Program’s ring_transact. The owner’s signature is proven inside the proof. |
| merge | The fee payer | Combines one owner’s notes of one asset into a single note. |
| set_block_list | The policy authority | Adds and removes block list entries. |
| set_exit_fee | The admin | Sets the exit fee rate, up to the cap fixed in the program. |
| pause | The pauser | Pauses or resumes the Ring. A paused Ring moves no note. |
Roles
Four role keys sit on the Ring account. No key holds two roles.
| Role | Can |
|---|---|
| Admin | Hand a role to a new key, which also signs, and set the exit fee rate. |
| Policy authority | Write block list entries. This is the list keeper’s key. |
| Pauser | Pause and resume the Ring. |
| Enrollment writer | Submit batches of enrollments. |
No role reads a transfer. The key that could is the empty seat.
Composes with
| Program | Its part | Id |
|---|---|---|
| Solana Privacy Program | Holds the notes, vaults, trees and nullifiers, and verifies the Owned and conserved proof. | ring1GaLCuJnkUMVkX2JeZLTTX17wKsV4fZmPVzXANW |
| User registry | Maps a Solana address to an account’s shielded keys. | ring().userRegistryProgramId |
| Storage program | Keeps the enrollment and block list trees and their roots. | ring().storageProgramId |
| SPL Token and Token-2022 | Move the assets that back the notes. | The standard token programs |
The Solana Privacy Program and its registry run unmodified at their upstream ids. Sources: helius-labs/privacy-rings and helius-labs/zolana-custom-rings, which holds the reference custom ring this program is built from.
The exit fee and the fee vault
The exit fee is the share of a withdrawal the Ring keeps, in the asset withdrawn. Its rate is a field of the Ring account, set by set_exit_fee. The Ring shows the current rate.
transact enforces it. On any transfer with a public withdrawal, the program requires a leg to the fee vault that covers the rate on what is withdrawn, or the transfer does not settle. Transfers that stay inside the Ring carry no exit fee.
The fee vault receives SOL at its own address and each token at a token account of that address.
const { exitFeeBps, feeVault } = await offrecord.ring()
feeVault.address
feeVault.balances // one holding per asset collectedToken says what the exit fee is for.