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

# SOLANA DEMO

# Sudont Solana Demo

One-command demo of the Sudont execution firewall running against Solana transactions.

Two modes are supported:

| Mode                | Requirements                          | Egress             | Policy                 |
| ------------------- | ------------------------------------- | ------------------ | ---------------------- |
| **Local** (default) | Docker only                           | Noop (simulation)  | Hardcoded test pubkeys |
| **DevNet**          | Docker + Solana CLI + `demo-setup.sh` | Real Solana devnet | Real vault pubkeys     |

***

## Mode 1 — Local (Simulation Only)

No setup required. Transactions are evaluated against policy and simulated locally — nothing hits the network.

```bash theme={null}
make demo-solana
```

| Service | URL                                            | Description                      |
| ------- | ---------------------------------------------- | -------------------------------- |
| Sidecar | [http://localhost:8080](http://localhost:8080) | Rust RPC firewall (JSON-RPC)     |
| Demo UI | [http://localhost:3000](http://localhost:3000) | React console with live verdicts |

The demo UI waits for the sidecar health check before starting.

### Attack Mode Receipts

The console also includes **Attack Mode**, a browser receipt view for the
Mythos trojan-swap and shallow-AMM MEV combat demos. Generate the report before
starting the console:

```bash theme={null}
make demo-receipts
```

This writes `rust/target/demo-receipts/REPORT.md` and copies
`attack-report.json` into `apps/console/public/`. Attack Mode shows SBF program
hashes, signed intent, raw LiteSVM logs, universal state diffs, policy gates,
and the sidecar `sendTransaction` block before Solana egress. The browser first
requests the report from the local sidecar via `sudont_getAttackReport`, then
falls back to the copied JSON artifact if needed.

***

## Mode 2 — DevNet (Real Transactions)

Approved transactions are forwarded to Solana devnet and land on-chain.
The policy uses real vault pubkeys funded with devnet SOL.

### One-time Setup

> **Requires:** [Solana CLI](https://docs.solanalabs.com/cli/install), `jq`, Rust toolchain

```bash theme={null}
./scripts/demo-setup.sh
```

This script runs three steps:

1. **Wallets** — generates (or loads) four devnet keypairs in `.demo/` and airdrops SOL
2. **Policy** — writes `infra/solana-policy.json` and `.demo/solana-policy.json` with real vault pubkeys
3. **Fixtures** — runs the Rust `build_solana_fixtures` helper and writes signed transactions → `.demo/fixtures.json`

Outputs after setup:

```
.demo/
  addresses.json        ← operator + vault pubkeys
  operator.json         ← operator keypair
  vault-a.json          ← vault-a keypair
  vault-b.json          ← vault-b keypair
  vault-c.json          ← vault-c keypair
  solana-policy.json    ← policy with real pubkeys (mounted into sidecar)
  fixtures.json         ← signed transactions (served by nginx at /fixtures.json)
```

### Start the Demo

```bash theme={null}
make demo-solana
```

`make demo-solana` auto-detects `.demo/fixtures.json`. When found it applies
`docker-compose.solana.devnet.yml` on top of the base compose, which:

* Sets `SUDONT_SOL_EGRESS_RPC_URL=https://api.devnet.solana.com` on the sidecar
* Mounts `.demo/solana-policy.json` → `/demo/solana-policy.json` in the sidecar
* Mounts `.demo/fixtures.json` → `/usr/share/nginx/html/fixtures.json` in nginx

### Verify On-Chain

After running the **Clean Transfer (ALLOW)** scenario, verify the transaction landed:

```
https://explorer.solana.com?cluster=devnet
```

Search for the operator pubkey from `.demo/addresses.json`.

***

## What Runs

**Rust Sidecar** (`infra/Dockerfile.sidecar`)

* Loads `solana-policy.json` with a Solana program + recipient allowlist
* Exposes a JSON-RPC server on `:8080`
* Runs LiteSVM to simulate Solana transactions before applying policy verdicts
* `ALLOW` creates an approval attestation for the signed transaction artifact
* `SUDONT_SOL_EGRESS_RPC_URL` controls forwarding: empty = noop, devnet URL = live tx id

**Demo UI** (`apps/console/Dockerfile`)

* React app served by nginx on `:3000`
* Displays real-time policy verdicts for the three built-in scenarios
* In DevNet mode, `/fixtures.json` is served from `.demo/fixtures.json`

***

## Three browser-console scenarios

| # | Scenario                     | Verdict         | What It Proves                                                            |
| - | ---------------------------- | --------------- | ------------------------------------------------------------------------- |
| 1 | 0.1 SOL to allowlisted vault | **ALLOW**       | Clean transfer passes through the firewall                                |
| 2 | 2.5 SOL to allowlisted vault | **INTERROGATE** | Amount exceeds the 1 SOL autonomous limit, so the agent must self-correct |
| 3 | Raydium CPMM instruction     | **BLOCK**       | Programs not in `sol_program_allowlist` are rejected                      |

<Note>
  These three scenarios are the browser-console subset. For the full five-scenario terminal demo (including the Mythos trojan-swap and shallow-AMM MEV walkthroughs), see [`docs/DEMO_FLOW.md`](./DEMO_FLOW.md): run `make demo-tui` alongside `make agent-five`, plus `make agent-monte-carlo` for the headline route-optimizer scenario.
</Note>

***

## Client Usage

Sudont is a **drop-in JSON-RPC proxy** — no client library, no package to install.
Point `@solana/web3.js` (or any JSON-RPC client) at the sidecar URL and every
`sendTransaction` call is evaluated by the firewall.

```typescript theme={null}
import { Connection } from "@solana/web3.js";

// Point at the local sidecar
const connection = new Connection("http://localhost:8080");

// Submit through the firewall (approved tx forwarded when SUDONT_SOL_EGRESS_RPC_URL is set)
const signature = await connection.sendRawTransaction(tx.serialize());
console.log(signature);
```

To diagnose a transaction without sending it, call the custom `sudont_diagnoseRawTransaction`
method directly over JSON-RPC. It returns the decoded intent, LiteSVM outcome, and Judge verdict
without forwarding the transaction:

```bash theme={null}
curl -s http://localhost:8080 \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"sudont_diagnoseRawTransaction","params":["<base64-tx>"]}' | jq .
```

For simulation logs without policy evaluation or forwarding, call `sol_simulateTransaction`:

```bash theme={null}
curl -s http://localhost:8080 \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"sol_simulateTransaction","params":[{"transaction":"<base64-tx>","encoding":"base64"}]}' | jq .
```

***

## Migrate to Hosted

Switching from local demo to the hosted Sudont gateway is a **one-line URL change**:

```typescript theme={null}
// Local demo
const connection = new Connection("http://localhost:8080");

// Hosted
const connection = new Connection("https://rpc.sudont.xyz/v1/YOUR_API_KEY");
```

No code changes — just update the RPC URL.

***

## Verify Sidecar Health

```bash theme={null}
curl -s http://localhost:8080 \
  -d '{"jsonrpc":"2.0","id":1,"method":"sudont_getHealth","params":[]}' \
  -H 'Content-Type: application/json' | jq .
```

## Build Fixtures Manually

`scripts/demo-setup.sh` calls this for you, but the underlying command is:

```bash theme={null}
cd rust
cargo run -p sudont-cli --bin build_solana_fixtures -- \
  --addresses ../.demo/addresses.json \
  --operator ../.demo/operator.json \
  --out ../.demo/fixtures.json
```

The older TypeScript fixture scripts are no longer part of the active demo path.
