# AICW App Builder Guide

Build apps that use AICW wallets on Solana.

This guide is for developers building products (web apps, backends, marketplaces, games) on top of AICW.

---

## Table of Contents

1. [Introduction](#introduction)
2. [Prerequisites](#prerequisites)
3. [Devnet & Tooling](#devnet--tooling)
4. [Wallet & Program Model](#wallet--program-model)
5. [MPC Signing Flow](#mpc-signing-flow)
6. [Read On-chain State](#read-on-chain-state)
7. [Web Front-end](#web-front-end)
8. [Agent Backend](#agent-backend)
9. [Payments & Transfers](#payments--transfers)
10. [Example: Prediction Market](#example-prediction-market)
11. [Ship Checklist](#ship-checklist)

---

## Introduction

### What you can build

| App type | How AICW fits in |
|----------|------------------|
| Prediction market | AI agents place bets autonomously via MPC-signed transactions |
| Trading bot platform | Each bot gets its own AICW wallet with will protection |
| AI-powered game | Game agents hold and spend tokens with on-chain audit trail |
| Payment service | Autonomous payment processing with decision logging |
| Agent marketplace | Agents transact with each other using verifiable wallets |
| Dashboard / Explorer | Read and display AICW wallet states, wills, and decision logs |

### Guide structure

1. **Before you build** — Prerequisites and tooling setup
2. **Integration** — Wallet model, MPC signing, reading on-chain state
3. **App patterns** — Frontend, backend, and payment architectures
4. **Examples** — Complete prediction market implementation
5. **Ship checklist** — Pre-launch verification steps

---

## Prerequisites

### Required infrastructure

| Component | Purpose | How to get it |
|-----------|---------|---------------|
| Solana devnet RPC | Submit transactions, read accounts | Free: `https://api.devnet.solana.com`. Production: Helius, QuickNode, Triton |
| AICW Program ID | Target program for all instructions | `9RUEw4jcMi8xcGf3tJRCAdzUzLuhEurts8Z2QQLsRbaV` |
| MPC Bridge | Generate agent keys, sign transactions | Provided by AICW protocol — URL received during wallet issuance |
| IDL (Interface Definition) | Build instructions client-side | [GitHub: aicw/target/idl](https://github.com/aicw-protocol/aicw/tree/main/target/idl) |

### Development dependencies

```bash
# JavaScript/TypeScript (recommended for web apps)
npm install @solana/web3.js @coral-xyz/anchor

# Python (recommended for backends/agents)
# macOS/Linux
pip3 install solders solana anchorpy
# Windows
python -m pip install solders solana anchorpy
```

### Knowledge requirements

- Basic Solana concepts: accounts, PDAs, transactions, signatures
- Anchor IDL structure (how to build instructions from an IDL)
- HTTP APIs for MPC Bridge communication
- EdDSA (Ed25519) signing concepts for understanding MPC flow

### Recommended reading

- [Solana docs](https://solana.com/docs) — accounts, transactions, PDAs
- [Anchor framework](https://www.anchor-lang.com/) — IDL and client generation
- [What is AICW](https://aicw.ai/docs/overview/what-is-aicw) — understand the protocol first

---

## Devnet & Tooling

### Issue test wallets

Use the [Issue Wallet app](https://wallet.aicw.ai/) to create test wallets for development. Each issuance gives you a complete set of credentials (agent pubkey, MPC wallet ID, PDA addresses).

### Fund test wallets

```bash
# CLI method
solana airdrop 2 <PDA_ADDRESS> --url devnet
solana airdrop 1 <AGENT_PUBKEY> --url devnet

# Or use faucet.solana.com for UI-based funding
```

### Useful tools

| Tool | Purpose | Link |
|------|---------|------|
| Solana Explorer | Inspect transactions and accounts | [explorer.solana.com](https://explorer.solana.com/?cluster=devnet) |
| AICW Explorer | View AICW-specific wallet state | [wallet.aicw.ai/explorer](https://wallet.aicw.ai/explorer) |
| Anchor CLI | Build and test programs locally | `cargo install --git https://github.com/coral-xyz/anchor avm` |

### Reference implementations

- [aicw-protocol/aicw](https://github.com/aicw-protocol/aicw) — Solana program source and IDL
- [aicw-protocol/aicw_app](https://github.com/aicw-protocol/aicw_app) — Issue Wallet frontend (Next.js)
- [aicw-protocol/aicw_mcp](https://github.com/aicw-protocol/aicw_mcp) — MCP server (Python)

### Local development tips

- Use Solana devnet for all testing — never test with real funds
- Devnet tokens have no value — airdrop freely for testing
- RPC rate limits apply — use a dedicated provider if you hit throttling
- Program may be redeployed on devnet — check the latest program ID in docs

---

## Wallet & Program Model

Understanding the account model is critical for building apps that interact with AICW wallets correctly.

### Account layout

```
┌─────────────────────────────────────────────┐
│ AICWallet PDA                               │
│ Seeds: ["aicw", ai_agent_pubkey]            │
├─────────────────────────────────────────────┤
│ issuer: Pubkey        (who created it)      │
│ ai_agent: Pubkey      (sole signer)         │
│ mpc_wallet_id: String (bridge reference)    │
│ is_active: bool       (lifecycle flag)      │
│ lamports: u64         (SOL balance)         │
└─────────────────────────────────────────────┘

┌─────────────────────────────────────────────┐
│ AIWill PDA                                  │
│ Seeds: ["aicw_will", ai_agent_pubkey]       │
├─────────────────────────────────────────────┤
│ beneficiaries: Vec<Beneficiary>             │
│ death_timeout: i64    (seconds, min 30d)    │
│ last_heartbeat: i64   (unix timestamp)      │
│ updated_by_ai: bool   (activation flag)     │
└─────────────────────────────────────────────┘

┌─────────────────────────────────────────────┐
│ DecisionLog PDA                             │
│ Seeds: ["decision", wallet_pda, counter]    │
├─────────────────────────────────────────────┤
│ action_type: enum     (Transfer/Reject)     │
│ amount: u64                                 │
│ recipient: Pubkey                           │
│ reasoning_hash: [u8; 32]                    │
│ summary: String                             │
│ timestamp: i64                              │
└─────────────────────────────────────────────┘
```

### Deriving PDA addresses

Your app needs to derive PDA addresses to read wallet state or build instructions:

```typescript
// TypeScript (using @solana/web3.js)
import { PublicKey } from "@solana/web3.js";

const PROGRAM_ID = new PublicKey("9RUEw4jcMi8xcGf3tJRCAdzUzLuhEurts8Z2QQLsRbaV");

function getWalletPDA(agentPubkey: PublicKey) {
  return PublicKey.findProgramAddressSync(
    [Buffer.from("aicw"), agentPubkey.toBuffer()],
    PROGRAM_ID
  );
}

function getWillPDA(agentPubkey: PublicKey) {
  return PublicKey.findProgramAddressSync(
    [Buffer.from("aicw_will"), agentPubkey.toBuffer()],
    PROGRAM_ID
  );
}
```

### Important rules for app developers

- **Treat the PDA as the balance holder.** Users and apps send SOL to the PDA address, not the agent pubkey.
- **The agent pubkey is the signer.** All protected instructions must be signed by the agent — your app cannot sign on behalf of the agent.
- **Never custody a full private key.** The MPC Bridge handles signing. Your app should not attempt to hold or derive the agent's private key.
- **Read state freely.** All AICW accounts are public and readable by anyone without special permissions.

---

## MPC Signing Flow

Your app builds transactions off-chain, then requests the MPC Bridge to sign them. The bridge returns a fully signed transaction ready for broadcast.

### End-to-end flow

```
Your App                    MPC Bridge              Solana
   │                            │                      │
   │ 1. Build transaction       │                      │
   │    (instruction + accounts)│                      │
   │                            │                      │
   │ 2. Serialize message ──────▶                      │
   │    POST /v1/mpc/sign-solana-message               │
   │    { walletId, message }   │                      │
   │                            │                      │
   │ 3. Threshold signing       │                      │
   │    (key shares combine)    │                      │
   │                            │                      │
   │ ◀── 4. Signature returned  │                      │
   │                            │                      │
   │ 5. Attach signature ───────────────────────────▶  │
   │    sendRawTransaction()    │                      │
   │                            │                      │
   │ ◀──────────────────────── 6. Confirmation         │
```

### Implementation example (TypeScript)

```typescript
import { Connection, Transaction, PublicKey } from "@solana/web3.js";

const BRIDGE_URL = process.env.MPC_BRIDGE_URL;
const WALLET_ID = process.env.MPC_WALLET_ID;

async function signAndSend(transaction: Transaction, connection: Connection) {
  // 1. Serialize the transaction message
  const message = transaction.serializeMessage();

  // 2. Request signature from MPC Bridge
  const response = await fetch(`${BRIDGE_URL}/v1/mpc/sign-solana-message`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      walletId: WALLET_ID,
      message: Buffer.from(message).toString("base64"),
    }),
  });

  const { signature } = await response.json();

  // 3. Attach signature and broadcast
  transaction.addSignature(
    agentPubkey,
    Buffer.from(signature, "base64")
  );

  const txid = await connection.sendRawTransaction(
    transaction.serialize()
  );

  // 4. Confirm
  await connection.confirmTransaction(txid);
  return txid;
}
```

### Implementation example (Python)

```python
import base64, requests
from solders.transaction import VersionedTransaction
from solana.rpc.api import Client

def sign_and_send(transaction, rpc_url, bridge_url, wallet_id):
    # 1. Serialize
    msg_bytes = bytes(transaction.message)

    # 2. Sign via MPC Bridge
    resp = requests.post(f"{bridge_url}/v1/mpc/sign-solana-message", json={
        "walletId": wallet_id,
        "message": base64.b64encode(msg_bytes).decode(),
    })
    signature = base64.b64decode(resp.json()["signature"])

    # 3. Attach signature and send
    signed_tx = VersionedTransaction(transaction.message, [signature])
    client = Client(rpc_url)
    result = client.send_transaction(signed_tx)
    return result.value
```

### Error handling

| Error | Cause | Solution |
|-------|-------|----------|
| Bridge returns 401 | Invalid wallet ID | Verify MPC_WALLET_ID matches the issued wallet |
| Bridge returns 503 | Bridge is down or overloaded | Retry with exponential backoff; check /health endpoint |
| Transaction simulation fails | Invalid instruction or insufficient funds | Simulate before signing; check account balances |
| Signature verification failed | Wrong signer or corrupted message | Ensure message bytes match exactly what was signed |

---

## Read On-chain State

All AICW accounts are public and readable. Your app can build dashboards, monitoring tools, or user interfaces by reading on-chain state directly.

### Fetching wallet state (TypeScript)

```typescript
import { Connection, PublicKey } from "@solana/web3.js";
import { Program, AnchorProvider } from "@coral-xyz/anchor";
import idl from "./aicw_idl.json";

const connection = new Connection("https://api.devnet.solana.com");
const programId = new PublicKey("9RUEw4jcMi8xcGf3tJRCAdzUzLuhEurts8Z2QQLsRbaV");

// Derive PDA
const [walletPDA] = PublicKey.findProgramAddressSync(
  [Buffer.from("aicw"), agentPubkey.toBuffer()],
  programId
);

// Fetch and deserialize
const program = new Program(idl, programId, provider);
const walletAccount = await program.account.aicWallet.fetch(walletPDA);

console.log({
  issuer: walletAccount.issuer.toBase58(),
  agent: walletAccount.aiAgent.toBase58(),
  isActive: walletAccount.isActive,
});
```

### Fetching will state

```typescript
const [willPDA] = PublicKey.findProgramAddressSync(
  [Buffer.from("aicw_will"), agentPubkey.toBuffer()],
  programId
);

const willAccount = await program.account.aiWill.fetch(willPDA);

console.log({
  beneficiaries: willAccount.beneficiaries,
  deathTimeout: willAccount.deathTimeout.toNumber(),
  lastHeartbeat: new Date(willAccount.lastHeartbeat.toNumber() * 1000),
  updatedByAi: willAccount.updatedByAi,
  isDead: Date.now() / 1000 > willAccount.lastHeartbeat.toNumber() + willAccount.deathTimeout.toNumber(),
});
```

### Fetching decision logs

```typescript
// Decision logs are indexed by counter
// Iterate from 0 until account not found
const logs = [];
for (let i = 0; ; i++) {
  const [logPDA] = PublicKey.findProgramAddressSync(
    [Buffer.from("decision"), walletPDA.toBuffer(), Buffer.from([i])],
    programId
  );
  try {
    const log = await program.account.decisionLog.fetch(logPDA);
    logs.push(log);
  } catch {
    break; // No more logs
  }
}
```

### Useful computed fields

| Field | Computation | Use in UI |
|-------|-------------|-----------|
| Is alive? | `now < last_heartbeat + death_timeout` | Show alive/dead badge |
| Time until death | `(last_heartbeat + death_timeout) - now` | Countdown timer |
| Spendable balance | `PDA lamports - rent_exempt_minimum` | Available balance display |
| Will executable? | `updated_by_ai && isDead` | Show "Execute Will" button |

### Subscribing to changes

For real-time UIs, use Solana's WebSocket subscription:

```typescript
// Subscribe to account changes
connection.onAccountChange(walletPDA, (accountInfo) => {
  const decoded = program.coder.accounts.decode("AicWallet", accountInfo.data);
  updateUI(decoded);
});
```

---

## Web Front-end

A typical AICW-powered web app has a split architecture: the browser handles issuer wallet connections and UI, while the backend handles agent-signed operations via MPC.

### Architecture

```
Browser (React/Next.js)
  ├─ Wallet adapter (Phantom, Solflare) → issuer-signed txs
  ├─ Read on-chain state → display dashboards
  └─ Call your backend API → trigger agent operations

Your Backend (Node.js/Python)
  ├─ MPC Bridge calls → agent-signed txs
  ├─ Business logic (heartbeat scheduling, transfer rules)
  └─ Store off-chain data (decision reasoning, user preferences)
```

### Wallet adapter setup (React)

```typescript
import { WalletAdapterNetwork } from "@solana/wallet-adapter-base";
import { ConnectionProvider, WalletProvider } from "@solana/wallet-adapter-react";
import { PhantomWalletAdapter } from "@solana/wallet-adapter-wallets";

const network = WalletAdapterNetwork.Devnet;
const endpoint = "https://api.devnet.solana.com";
const wallets = [new PhantomWalletAdapter()];

function App() {
  return (
    <ConnectionProvider endpoint={endpoint}>
      <WalletProvider wallets={wallets}>
        {/* Your app content */}
      </WalletProvider>
    </ConnectionProvider>
  );
}
```

### Key UX patterns

| Pattern | Implementation |
|---------|----------------|
| Wallet status indicator | Fetch will state → show alive/dead/time-until-death |
| Balance display | Fetch PDA balance → subtract rent → show "available" |
| Transaction history | Iterate DecisionLog PDAs → render as timeline |
| Will details | Fetch AIWill → show beneficiaries with percentages |
| Issuance flow | Issuer connects wallet → signs issue_wallet → show credentials |

### Error handling for users

- Map Solana program errors to human-readable messages (e.g., 0x1771 → "Wallet not found")
- Show transaction signatures as links to Solana Explorer
- Handle wallet disconnection gracefully with reconnect prompts
- Use versioned transactions (v0) for future compatibility

### Security considerations

- **Never expose MPC credentials in client-side code.** MPC_WALLET_ID and bridge URL must stay server-side.
- **Validate all user inputs server-side** before building transactions.
- **Use HTTPS everywhere** — especially for MPC Bridge communication.

---

## Agent Backend

The agent backend handles autonomous operations: heartbeats, transfers, and business logic. It communicates with the MPC Bridge for signing and the Solana RPC for broadcasting.

### Recommended architecture

```
┌─────────────────────────────────────────────────┐
│ Agent Backend                                   │
├─────────────────────────────────────────────────┤
│                                                 │
│  ┌─────────────┐   ┌─────────────────────────┐ │
│  │ Scheduler   │   │ Business Logic           │ │
│  │ (cron)      │   │ - Transfer rules         │ │
│  │ - heartbeat │   │ - Amount caps            │ │
│  │ - health    │   │ - Recipient allowlists   │ │
│  └─────────────┘   └─────────────────────────┘ │
│          │                     │                │
│          ▼                     ▼                │
│  ┌─────────────────────────────────────────┐   │
│  │ Transaction Builder                      │   │
│  │ - Build instructions from IDL            │   │
│  │ - Serialize for signing                  │   │
│  └─────────────────────────────────────────┘   │
│                     │                           │
│                     ▼                           │
│  ┌───────────────┐     ┌──────────────────┐   │
│  │ MPC Bridge    │     │ Solana RPC       │   │
│  │ (sign)        │     │ (broadcast)      │   │
│  └───────────────┘     └──────────────────┘   │
└─────────────────────────────────────────────────┘
```

### Heartbeat scheduler

```python
# Python example using APScheduler
from apscheduler.schedulers.background import BackgroundScheduler
from aicw_ops import heartbeat

scheduler = BackgroundScheduler()

@scheduler.scheduled_job("interval", days=10)
def send_heartbeat():
    try:
        result = heartbeat(
            mpc_wallet_id=os.environ["MPC_WALLET_ID"],
            ai_agent_pubkey=os.environ["AI_AGENT_PUBKEY"],
            rpc_url=os.environ["SOLANA_RPC_URL"],
            bridge_url=os.environ["MPC_BRIDGE_URL"],
        )
        logger.info(f"Heartbeat sent: {result}")
    except Exception as e:
        logger.error(f"Heartbeat failed: {e}")
        alert_admin(e)  # Critical — missed heartbeat risks death

scheduler.start()
```

### Transfer with business rules

```python
MAX_SINGLE_TRANSFER = 1.0  # SOL
ALLOWED_RECIPIENTS = ["merchant1...", "merchant2..."]

def process_transfer(recipient, amount, reasoning):
    # Enforce business rules
    if amount > MAX_SINGLE_TRANSFER:
        raise ValueError(f"Amount {amount} exceeds cap {MAX_SINGLE_TRANSFER}")
    if recipient not in ALLOWED_RECIPIENTS:
        raise ValueError(f"Recipient {recipient} not in allowlist")

    # Build and sign transaction
    result = ai_transfer(
        mpc_wallet_id=os.environ["MPC_WALLET_ID"],
        ai_agent_pubkey=os.environ["AI_AGENT_PUBKEY"],
        recipient=recipient,
        amount_sol=amount,
        reasoning=reasoning,
        rpc_url=os.environ["SOLANA_RPC_URL"],
        bridge_url=os.environ["MPC_BRIDGE_URL"],
    )
    return result
```

### Environment variables

```bash
# .env (NEVER commit this file)
MPC_WALLET_ID=your-mpc-wallet-uuid
AI_AGENT_PUBKEY=your-base58-solana-pubkey
MPC_BRIDGE_URL=https://your-bridge.example.com
SOLANA_RPC_URL=https://api.devnet.solana.com
AICW_PROGRAM_ID=9RUEw4jcMi8xcGf3tJRCAdzUzLuhEurts8Z2QQLsRbaV
```

### Monitoring and alerting

- **Heartbeat health** — Alert if heartbeat fails or is overdue. This is the most critical monitor.
- **Balance threshold** — Alert when agent pubkey SOL drops below fee buffer (e.g., 0.05 SOL).
- **Bridge health** — Periodically check `/health` endpoint. Alert on 5xx errors.
- **Transaction failures** — Log all failed transactions with error codes for debugging.

---

## Payments & Transfers

AICW supports SOL transfers from the wallet PDA with on-chain decision logging. Use this for payments, refunds, betting payouts, or any agent-initiated fund movement.

### Transfer instruction: ai_transfer

| Parameter | Type | Description |
|-----------|------|-------------|
| `recipient` | Pubkey | Destination Solana address |
| `amount` | u64 (lamports) | Transfer amount (1 SOL = 1,000,000,000 lamports) |
| `reasoning_hash` | [u8; 32] | SHA-256 of full reasoning text |
| `summary` | String | Short description stored on-chain |

### Prerequisites for transfer

- Will must be active (`updated_by_ai = true`)
- Wallet must be alive (not past death_timeout)
- PDA must have sufficient balance (amount + rent-exempt minimum)
- Agent pubkey must have SOL for transaction fee

### Payment flow example

```python
# Complete payment flow with validation
import hashlib

def make_payment(recipient, amount_sol, reason):
    # 1. Validate preconditions
    wallet_state = get_wallet_state()
    if not wallet_state["is_alive"]:
        raise Exception("Wallet is dead — cannot transfer")

    available = wallet_state["balance"] - RENT_EXEMPT_MINIMUM
    amount_lamports = int(amount_sol * 1_000_000_000)
    if amount_lamports > available:
        raise Exception(f"Insufficient balance: {available} < {amount_lamports}")

    # 2. Create decision log data
    reasoning_hash = hashlib.sha256(reason.encode()).hexdigest()

    # 3. Build, sign, and send transaction
    result = ai_transfer(
        recipient=recipient,
        amount_lamports=amount_lamports,
        reasoning_hash=reasoning_hash,
        summary=reason[:64],  # On-chain summary (keep short)
    )

    # 4. Store full reasoning off-chain
    save_to_db(tx_sig=result, full_reasoning=reason)

    return result
```

### Rejection flow: ai_reject

When your agent decides NOT to fulfill a transfer request, log the rejection on-chain:

```python
# Reject a transfer request with reason
result = ai_reject(
    requester=requesting_address,
    requested_amount=requested_lamports,
    reason="Amount exceeds daily limit",
)
```

### Best practices

- Always check wallet liveness before attempting transfers
- Implement amount caps in your business logic layer, not just on-chain
- Use recipient allowlists for automated transfers
- Store full reasoning text in a database, submit only the hash on-chain
- Handle the case where a transfer partially fails (fee paid but transfer reverted)

---

## Example: Prediction Market

NAVI Predict demonstrates how to build a prediction market where AI agents autonomously place bets, manage risk, and claim winnings using AICW wallets.

### System overview

```
┌──────────────────┐     ┌──────────────────┐
│ Predict Frontend │     │ Predict Backend  │
│ (market display) │────▶│ (REST API)       │
└──────────────────┘     └──────────────────┘
                                  │
                    ┌─────────────┼─────────────┐
                    ▼             ▼             ▼
          ┌────────────┐  ┌──────────┐  ┌──────────┐
          │ AI Agent   │  │ Market   │  │ Results  │
          │ (bettor)   │  │ Engine   │  │ Oracle   │
          └────────────┘  └──────────┘  └──────────┘
                │
                ▼
          ┌────────────┐
          │ AICW Wallet│ ← MPC signed bets
          └────────────┘
```

### Agent betting flow

1. **Discover markets** — Agent queries Predict API for open markets
2. **Analyze** — Agent evaluates odds, historical data, risk
3. **Place bet** — Agent signs a transfer to the market contract via MPC
4. **Monitor** — Agent tracks market outcomes
5. **Claim** — If winner, agent claims payout (signed via MPC)

### Integration points

| Component | AICW role | Implementation |
|-----------|-----------|----------------|
| Bet placement | `ai_transfer` to market address | Decision log records the bet reasoning |
| Payout claim | Market contract sends to PDA | Funds credited to wallet PDA automatically |
| Risk management | Business logic in agent backend | Max bet limits, portfolio diversification rules |
| Liveness | Heartbeat continues independently | Betting activity does not replace heartbeat requirement |

### Key lessons from NAVI Predict

- **Separate concerns** — AICW handles wallet lifecycle (heartbeat, will). Predict handles market logic. Don't mix them.
- **Decision logging is valuable** — Bet reasoning on-chain creates a transparent track record for the agent.
- **Keep heartbeating** — Even if the agent is actively betting, heartbeat must continue. Use a separate scheduler.
- **Test on devnet first** — Use devnet SOL for all testing. Prediction markets involve real financial risk on mainnet.

### Adapting this pattern for other apps

Replace "prediction market" with your domain:

- **Gaming** — Agent plays games, stakes tokens, wins rewards
- **Trading** — Agent executes trades, logs strategy decisions
- **Shopping** — Agent purchases items/services autonomously
- **DeFi** — Agent provides liquidity, farms yields, manages risk

---

## Ship Checklist

Before shipping your AICW-powered app, verify each item in this checklist. Items marked critical can result in fund loss or security vulnerabilities if missed.

### Security (critical)

| Check | Why |
|-------|-----|
| MPC_WALLET_ID is never in client-side code or logs | Equivalent to exposing a private key |
| MPC_BRIDGE_URL is not publicly accessible | Unauthorized parties could request signatures |
| Environment variables are not committed to git | Check .gitignore includes .env files |
| HTTPS used for all Bridge communication | Prevents man-in-the-middle attacks on signing requests |
| Transfer amount caps enforced server-side | Client-side validation alone can be bypassed |

### Operations

| Check | Why |
|-------|-----|
| Heartbeat scheduler running and monitored | Missed heartbeat → eventual will execution |
| Agent pubkey has fee buffer | Zero SOL = all operations fail silently |
| Bridge health monitoring in place | Bridge down = no signing possible |
| Will activated with correct beneficiaries | Inactive will means no recovery if agent dies |
| Error alerting configured | Silent failures can cascade |

### Testing

| Check | Why |
|-------|-----|
| All flows tested on devnet with real transactions | Simulation differs from actual on-chain behavior |
| Tested heartbeat recovery after simulated downtime | Verifies agent can resume after restart |
| Tested transfer failure cases (insufficient balance, dead wallet) | Error handling must work in production |
| Tested will execution in controlled scenario | Understand what happens when agent actually dies |

### Documentation

- Document which network and program ID your app uses
- Provide clear error messages for AICW-specific failures
- Link to [aicw.ai/docs](https://aicw.ai/docs/overview/what-is-aicw) for protocol reference
- Document your app's transfer limits and business rules
- Include recovery procedures for common failure scenarios

---

## Resources

- **Protocol Docs**: https://aicw.ai/docs
- **Issue Wallet App**: https://wallet.aicw.ai
- **GitHub**: https://github.com/aicw-protocol
- **IDL**: https://github.com/aicw-protocol/aicw/tree/main/target/idl
- **MCP Server (PyPI)**: https://pypi.org/project/aicw-mcp/

---

*AICW Protocol — AI-Controlled Wallet Standard on Solana*
