> ## Documentation Index
> Fetch the complete documentation index at: https://docs.altheia.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# DeepBook swap agent

> A runnable agent that swaps SUI on DeepBook, capped by an on-chain policy, halted by owner revoke.

A runnable agent that acts as itself — its own key, its own `AgentCap` — and swaps SUI on DeepBook through the gated adapter. One swap within the cap is allowed. One over the cap is denied on-chain. After the owner revokes, the same swap halts.

<Card title="Source on GitHub" icon="github" href="https://github.com/altheia-xyz/altheia-sui-demo" horizontal>
  `altheia-sui-demo` — the demo agent repo.
</Card>

## What this shows

| Step | Action                                               | Expected                   |
| ---- | ---------------------------------------------------- | -------------------------- |
| 1    | Agent swaps 0.05 SUI (within the per-tx cap)         | allowed, transaction lands |
| 2    | Agent swaps 0.2 SUI (over the per-tx cap)            | denied `over_per_tx_cap`   |
| 3    | Owner revokes in the dashboard, agent retries step 1 | denied `policy_revoked`    |

<Note>
  Step 1 is a **policy decision**, not a guaranteed fill. The agent submits a gated DeepBook order; on a thin testnet book it can fill zero. Allowed means the policy permitted the action and the transaction landed — it does not assert the order filled.
</Note>

## Setup

### 1. Provision the agent

In the dashboard, [provision an agent](/guides/provision-agent) with:

| Field           | Value             |
| --------------- | ----------------- |
| Budget asset    | SUI               |
| Per-tx cap      | `0.5 SUI`         |
| Per-day cap     | `2 SUI`           |
| Allowed actions | `swap`            |
| Scope           | the DeepBook pool |

Save the agent private key.

### 2. Configure

```bash theme={null}
npm i @altheia-xyz/sui
npm i -D tsx
```

```bash theme={null}
AGENT_PRIVKEY=suiprivkey1...
ALTHEIA_API=https://api.altheia.xyz   # for recording denials
TOKEN=<operator token>
AGENT_ID=<dashboard agent id>
```

## The loop

`agentRefs` derives the agent's objects from its key. `guardedSubmit` dry-runs each swap: an allowed swap submits and the on-chain `AllowedAction` event indexes it; a denied swap is recorded to the Chronicle without spending gas.

```ts theme={null}
import {
  SuiJsonRpcClient, getJsonRpcFullnodeUrl, Ed25519Keypair, decodeSuiPrivateKey,
  agentRefs, buildSwap, keypairExecutor, guardedSubmit,
} from "@altheia-xyz/sui";

const client = new SuiJsonRpcClient({ url: getJsonRpcFullnodeUrl("testnet"), network: "testnet" });
const kp = Ed25519Keypair.fromSecretKey(decodeSuiPrivateKey(process.env.AGENT_PRIVKEY!).secretKey);
const agentAddr = kp.getPublicKey().toSuiAddress();
const refs = await agentRefs(client, agentAddr);

const audit = {
  baseUrl: process.env.ALTHEIA_API!, token: process.env.TOKEN!,
  agent_id: process.env.AGENT_ID!, action_type: "deepbook_swap", asset: "SUI",
};

async function swap(sui: number) {
  const amount = BigInt(Math.round(sui * 1e9));
  const r = await guardedSubmit(client, keypairExecutor(client, kp), agentAddr,
    buildSwap(refs, amount), { ...audit, amount: sui });
  if (r.ok) console.log(`allowed — DeepBook order submitted: ${r.digest}`);
  else console.log(`denied on-chain (logged to Chronicle): ${r.reason_code}`);
}

await swap(0.05);  // STEP 1 — within the per-tx cap
await swap(0.2);   // STEP 2 — over the per-tx cap → over_per_tx_cap
// STEP 3 — revoke in the dashboard, then:
await swap(0.05);  // → policy_revoked
```

## What the run shows

Step 1 submits a real gated DeepBook order; the digest is on a Sui explorer. Step 2 aborts inside `check_and_consume` before any coin leaves the vault, and the denial is recorded. After the owner revokes (via the dashboard, signed with the `OwnerCap`), step 3 aborts `policy_revoked` — the same action that worked now halts.

## Owner side

Revoke and the kill-and-drain are owner operations. In the dashboard the owner clicks **Revoke** (or **Withdraw to wallet**, which revokes and sweeps the vault back). Programmatically, with owner refs:

```ts theme={null}
const agent = new AltheiaSui(client, ownerRefs, keypairExecutor(client, ownerKp));
await agent.revoke();
await agent.killAndDrain(ownerAddr);  // revoke + sweep SUI + acquired DEEP to the owner
```

## Verify

Open the agent in the dashboard. The Chronicle has the allowed swap (settled, with a digest), the denied attempt (`over_per_tx_cap`), and the post-revoke halt.

<Frame>
  <img src="https://mintcdn.com/altheia/FaUWnizMhLhPg3t5/images/chronicle.png?fit=max&auto=format&n=FaUWnizMhLhPg3t5&q=85&s=b8f758b8286e4b02c1fb8b9b3de4e5cf" alt="Chronicle: allowed swap, denied over-cap, revoke" width="3024" height="1674" data-path="images/chronicle.png" />
</Frame>

<Card title="SDK reference" icon="arrow-right" href="/sdk/altheia" horizontal>
  AltheiaSui, agentRefs, builders, reads.
</Card>
