> For the complete documentation index, see [llms.txt](https://docs.useprivatus.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.useprivatus.com/protocol-and-architecture/on-chain-architecture.md).

# On-Chain Architecture

Privatus accounts are built directly on Token-2022 confidential balances, the confidential transfer extension of Solana's token program, with Privatus's own Rust programs (written with Anchor, open-source) layered on top for handles, agents, and disclosure. There is no separate Privatus ledger, no shadow database of record. If you understand the Token-2022 confidential transfer account, you understand the core of how Privatus's balances and transfers work on-chain. The chain is the product.

***

## Confidential token account state

Each user holds a Token-2022 token account for USDG (USDC, also natively issued on Solana, is supported as well) with the confidential transfer extension enabled, which stores encrypted state alongside the normal public token account fields:

```rust
pub struct ConfidentialTransferAccount {
    pub approved: bool,                        // Whether confidential transfers are enabled
    pub elgamal_pubkey: ElGamalPubkey,         // Public key used to encrypt this account's balance
    pub pending_balance_lo: ElGamalCiphertext, // Encrypted incoming balance, low bits
    pub pending_balance_hi: ElGamalCiphertext, // Encrypted incoming balance, high bits
    pub available_balance: ElGamalCiphertext,  // Encrypted spendable balance
    pub decryptable_available_balance: AeCiphertext, // Balance encrypted for owner's fast local decryption
    pub allow_confidential_credits: bool,
    pub allow_non_confidential_credits: bool,
    pub pending_balance_credit_counter: u64,
    pub maximum_pending_balance_credit_counter: u64,
    pub expected_pending_balance_credit_counter: u64,
    pub actual_pending_balance_credit_counter: u64,
}
```

`available_balance` and the pending balance fields are twisted ElGamal ciphertexts. Only the holder of the corresponding ElGamal private key, derived from your Privatus account key, can decrypt them. To everyone else, including Privatus and every Solana validator, they are opaque.

The token account itself is owned by your Privatus smart account: a PDA (program-derived address) derived deterministically from your `.privatus` handle, with Squads multisig attached for recovery and key rotation.

***

## Transfer proof data

A confidential transfer carries zero-knowledge proof data alongside the encrypted amount, generated client-side by the sender and included in the same Solana transaction:

```rust
pub struct TransferProofData {
    pub new_source_ciphertext: ElGamalCiphertext,        // Sender's updated encrypted balance
    pub transfer_amount_ciphertext_lo: ElGamalCiphertext, // Encrypted transfer amount, low bits
    pub transfer_amount_ciphertext_hi: ElGamalCiphertext, // Encrypted transfer amount, high bits
    pub equality_proof: Proof,  // Proves ciphertext consistency
    pub validity_proof: Proof,  // Proves amount is well-formed
    pub range_proof: Proof,     // Proves amount is non-negative and in range
}
```

These proofs are checked by Solana's native ZK proof program, in the same transaction, before the encrypted balances are updated. Verification is part of Solana consensus itself: a transaction with an invalid proof fails, and no validator can settle it. The proofs never reveal the transfer amount, only that it's valid.

***

## The shielded pool

Layer 3 accounts (Shadow Pro and above) go further than encrypted amounts. Privatus's shielded pool program commits account state as leaves in an on-chain Merkle commitment tree; the leaf data itself lives off-chain, held by the account owner. Spending from the pool means proving, in zero knowledge, that you own an unspent commitment in the tree, without revealing which one. These proofs are Groth16 (constant-size, cheap to verify), produced from Circom and Noir circuits client-side and verified on-chain by Privatus's Rust verifier through Solana's alt\_bn128 syscalls.

Recipients stay unlinkable through stealth meta-addresses: a recipient publishes a meta-address once, and each payer derives a fresh one-time address per payment that on-chain analysis cannot connect back to the recipient's public identity.

***

## Privatus's off-chain index

Privatus maintains an off-chain PostgreSQL index, populated from program event streams, purely for UI performance and search. It stores:

* Address to `@handle` mappings
* Transaction metadata that's already public on-chain: sender, receiver, timestamp, transaction signature
* Webhook subscription and delivery state

It never stores decrypted balances or transfer amounts. Anything sensitive exists in exactly two places: encrypted on-chain, and decrypted on your own device.

***

## Agent account structure

An Agent account is, on-chain, a PDA-based smart account holding a confidential token balance, with its own signing key. What makes it an "agent account" is the Privatus agent program: Privatus's Agent Engine associates the account with a parent account and provisions its spend policy into on-chain program state, so a transaction that exceeds the policy fails the program's checks and never settles. Policy checks also run client-side before a transaction is ever built, but the on-chain constraint is what keeps the limit binding even if the client is compromised. This is how autonomous agents get real spending power without unbounded risk. See [Trust & Security Model](/protocol-and-architecture/trust-and-security.md) for what that means for agent security.

***

## Further reading

* [Protocol Overview](/protocol-and-architecture/protocol-overview.md)
* [Trust & Security Model](/protocol-and-architecture/trust-and-security.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.useprivatus.com/protocol-and-architecture/on-chain-architecture.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
