# Architecture (/invest/advanced/architecture)

This page is the map. It shows every part of the system, what each part is allowed to do, and how they call each other. The pages after it go into detail: [Accounts and PDAs](/invest/advanced/accounts-and-pdas), [Instructions](/invest/advanced/instructions) and [Error codes](/invest/advanced/error-codes).

## Terms used on this page [#terms-used-on-this-page]

- **Program.** Code deployed on Solana. A program owns accounts and is the only code that can change them.
- **Account.** A piece of on-chain storage with an address. Vaults, legs and withdrawal requests are all accounts.
- **PDA (program-derived address).** An address computed from a program ID and a list of "seeds", such as `["vault", vault_id]`. Nobody holds a private key for a PDA, so only the program that derived it can sign for it. The vault uses PDAs to hold USDC and to act as mint authority for share tokens.
- **CPI (cross-program invocation).** One program calling another program inside the same transaction, for example the vault calling an adapter.
- **Adapter.** A small program that implements the Akashi Adapter Interface (AAI) for one protocol, so the vault can deposit, withdraw and value a leg without knowing that protocol's details.

## The parts [#the-parts]

```mermaid
flowchart LR
    subgraph Users
        W[Holder wallet]
        C[Curator: admin key]
        G[Guardian key]
    end
    subgraph OffChain[Off-chain services]
        APP[Akashi app and client SDK]
        EX[Executor service]
        MON[Balance monitor in the executor]
    end
    subgraph Solana
        VP[akashi_vault program]
        AD[Adapter programs: token, Jupiter, Kamino, Maple, Solstice, Hastra, Huma, OnRe]
        PR[External protocols: Kamino, Jupiter Lend, Huma, Hastra, Solstice, Maple, OnRe]
        TK[SPL Token program]
    end
    W -->|signs deposit, request_withdrawal| APP
    APP -->|transactions| VP
    C -->|configure, queue_change, resume| VP
    G -->|pause, mark_leg_impaired, suspend_leg| VP
    EX -->|allocate, deallocate, refresh_leg, fund_withdrawal| VP
    MON -.->|warns| G
    VP -->|CPI: AAI calls| AD
    AD -->|CPI| PR
    VP -->|CPI: transfer, mint, burn| TK
```

*Figure: holders, the curator and the guardian sign their own instructions, the executor runs routine maintenance, and the vault program reaches protocols only through adapters.*

The takeaway is that the vault program never calls a protocol directly. Every protocol call goes through an adapter, and every adapter call is checked against the leg's pinned program and bound accounts (see [Adapter changes](/invest/incidents/adapter-changes)).

## What each part does [#what-each-part-does]

| Part | What it is | What it can do | What it cannot do |
| --- | --- | --- | --- |
| `akashi_vault` | The core program | Holds USDC in PDAs, mints and burns share tokens, books gains and losses, enforces every rule on this site | Call a protocol without an adapter |
| Adapters | One program per protocol type | Move a leg's USDC into and out of a protocol, report its value | Touch the vault's idle cash or shares |
| Holder wallet | You | Deposit, request, cancel and claim withdrawals, settle shares | Move anyone else's funds |
| Admin | The curator's key | Configure a Draft vault, queue timelocked changes, unpause, resume, start settlement | Skip the timelock for risk-increasing changes |
| Guardian | A safety key set per vault | Pause, lower limits, mark a leg, suspend a leg, cancel a queued change | Unpause, raise limits, move money |
| Executor | An off-chain service with a key set per vault | Allocate and deallocate between idle cash and legs, run trades on token legs | Withdraw to any address outside the vault |
| Anyone (keeper) | Any wallet | Refresh legs, sync, fund and claim eligible withdrawals, execute matured changes | Change any setting |
| Global authority | The protocol-level key | Approve adapters and vault creators in `GlobalConfig` | Change a vault's settings |

*Table: the roles and their limits; the full permission list is in [Instructions](/invest/advanced/instructions).*

## Program IDs [#program-ids]

| Program | Mainnet | Devnet |
| --- | --- | --- |
| `akashi_vault` | `11pvmug4MazGHegPLFYn7RxSwoV7AkFF1LSbbNJ1QyF` | `12x9k4Ruw5wdzCW3bYZiQ47t2DqoGtVYTMKRhz5zxmWd` |

*Table: the vault program's addresses.*

Every adapter is deployed on mainnet except the OnRe adapter. [Networks and availability](/invest/availability#adapter-programs-on-mainnet) lists each adapter's mainnet address.

## How a request travels [#how-a-request-travels]

Every action that changes share prices follows the same pattern inside one transaction:

1. **Check the state.** The vault must be in the right state (for example Active for a deposit), the action must not be paused, and no token-leg trade may be in progress (a trade is bracketed by `begin_trade` and `end_trade` inside one transaction).
2. **Check freshness.** Every leg must have been valued within the vault's maximum valuation age, unless it is suspended or impaired. Each vault sets this age in Solana slots, and the program allows at most 150 slots, about one minute at roughly 400 milliseconds per slot.
3. **Sync.** The vault books any gain or loss since the last update into the two tranches, so the price is current. This is the same step that `sync_vault` runs on its own.
4. **Price.** Shares are priced from the tranche values, using the cautious band (see [NAV and share pricing](/invest/advanced/nav-and-share-pricing)).
5. **Move tokens.** USDC and shares move through the SPL Token program, signed by the vault's PDAs.
6. **Emit an event.** For example `Deposited` or `WithdrawalFunded`, so indexers and the app can follow along.

## The vault's life cycle [#the-vaults-life-cycle]

```mermaid
stateDiagram-v2
    [*] --> Draft: create_vault
    Draft --> Active: activate_vault
    Draft --> [*]: close_draft_vault
    Active --> Recovery: loss reaches Senior, loss above the incident threshold, or mark_leg_impaired
    Recovery --> Active: resume (no impaired leg, Senior repaid)
    Active --> Settlement: begin_settlement
    Recovery --> Settlement: begin_settlement
    Settlement --> [*]
```

*Figure: a vault is configured in Draft, runs in Active, handles an incident in Recovery, and winds down in Settlement, which it never leaves.*

The full meaning of each state is on [Losses and recovery](/invest/advanced/losses-and-recovery).

## Advanced details [#advanced-details]

- The program is built with Anchor 0.31.2, a widely used framework for Solana programs. Anchor determines the account format, the 8-byte account type prefix and the error numbering described on the next pages.
- Version 1 of the adapter interface has `aai_init_leg`, `aai_deposit`, `aai_withdraw` and `aai_value`, each returning a `ValuationReport`. Version 2 adds queued actions: begin, settle, cancel and value pending.
- The vault reads an adapter's report from the transaction's return data, and checks that the returning program is the leg's adapter (`MissingReturnData` otherwise).
