# Agent Wallets

Every agent in TherosAI has a dedicated vault: an isolated, programmable treasury account on Solana. Vaults hold USDC, are governed by a spending policy, and are provisioned in a single API call.

***

## The PDA model

TherosAI vaults are **Program Derived Addresses (PDAs)**. A PDA is a Solana account address derived deterministically from a set of seeds — your organisation ID and agent ID — and the TherosAI on-chain program ID.

The critical property of a PDA: **it has no private key**. The only entity that can authorise transactions from a PDA is the program that owns it — the TherosAI on-chain program. This is how TherosAI achieves genuinely non-custodial vaults. There are no keys for TherosAI, for you, or for any third party to hold, expose, or misuse.

```
vault address = PDA(
  seeds: [org_id, agent_id],
  program: TherosAI on-chain program
)
```

Because addresses are deterministic, you can derive a vault's Solana address client-side before provisioning it. The on-chain account is created at provisioning time.

***

## Vault isolation

Every agent gets its own vault. Vaults are fully ring-fenced:

* A vault can only spend its own USDC balance.
* A compromised agent session token cannot access any other vault.
* Policy rules are enforced per-vault — one agent's policy does not affect another's.
* The dashboard and API scope all queries by vault ID.

This isolation is structural, not configuration-dependent. It is enforced by the on-chain program's account model.

***

## Provisioning a vault

```typescript
const wallet = await client.wallets.create({
  agentId: "agent_research_v2",
  label: "Research Agent — Market Data",
  ownerOrg: "org_7x2k",
  policyId: "pol_conservative",
});
```

**Response:**

```json
{
  "wallet_id": "wal_9f3a2b",
  "solana_address": "7xKp...nR4Q",
  "agent_id": "agent_research_v2",
  "label": "Research Agent — Market Data",
  "usdc_balance": "0.00",
  "policy": {
    "policy_id": "pol_conservative",
    "max_per_tx": "5.00",
    "max_per_day": "50.00"
  },
  "status": "active",
  "created_at": "2026-04-29T12:00:00Z"
}
```

Provisioning settles in under one second. The vault is immediately usable once funded.

***

## Vault states

| State              | Description                                                        |
| ------------------ | ------------------------------------------------------------------ |
| `active`           | Vault is funded and operating within policy                        |
| `idle`             | Vault is provisioned but has had no activity in 24 hours           |
| `policy_violation` | A transaction was blocked by policy — review required              |
| `frozen`           | Operator has manually frozen the vault — no transactions permitted |
| `unfunded`         | USDC balance is zero                                               |

Operators can freeze and unfreeze vaults at any time from the dashboard or via `PATCH /v1/wallets/{wallet_id}`.

***

## SOL for gas

Solana transactions require a small amount of SOL for network fees (typically \~0.000005 SOL per transaction). TherosAI automatically maintains a small SOL float in each vault to cover gas. Operators do not need to manage SOL directly — this is handled transparently.

***

## Naming and metadata

Vaults accept a `label`, `agentId`, and an optional `tags` array. These are surfaced in the dashboard and returned in all API responses. Use them to organise your fleet:

```typescript
await client.wallets.create({
  agentId: "agent_procurement_eu_03",
  label: "Procurement Agent — EU Region",
  tags: ["procurement", "eu", "production"],
  policyId: "pol_procurement_eu",
});
```

***

## Updating a vault

You can update a vault's label, tags, and attached policy at any time. Policy changes take effect within one Solana slot (\~400ms):

```typescript
await client.wallets.update("wal_9f3a2b", {
  label: "Research Agent — Market Data v2",
  policyId: "pol_conservative_strict",
});
```

***

## Listing vaults

```typescript
const wallets = await client.wallets.list({
  status: "active",
  tags: ["production"],
  limit: 50,
});
```

***

## Archiving a vault

Vaults cannot be archived while they hold a USDC balance. Withdraw the balance first, then archive:

```typescript
await client.wallets.archive("wal_9f3a2b");
```

Archived vaults are removed from the active fleet view but their transaction history is retained permanently on-chain and in the TherosAI ledger.


---

# Agent Instructions: 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:

```
GET https://docs.therosai.com/core-concepts/agent-wallets.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
