Architecture
Two programs, three states, one CPI.
SettleProof is powered by AAP: a custody program that holds USDC in per-escrow PDA vaults, and an attestor program that verifies Ed25519-signed proofs of delivery via the Solana instructions sysvar.
End-to-end flow
┌────────────────────────────────────────────────────────────────┐
│ AGENT (Cursor, Claude Code, AutoGen, LangChain agent…) │
└─────────────────────────────┬──────────────────────────────────┘
│ HTTP request + payment intent
▼
┌────────────────────────────────────────────────────────────────┐
│ CARD ISSUER (Stripe Issuing / Crossmint / Lithic / Visa) │
│ → emits single-use VCC with spending limit │
│ (mocked in MVP — pluggable webhook bridge in V2) │
└─────────────────────────────┬──────────────────────────────────┘
│ Visa / Mastercard rail
▼
┌────────────────────────────────────────────────────────────────┐
│ ★ SettleProof / AAP CUSTODY CONTRACT (Solana) ★ │
│ → equivalent USDC custodied on-chain │
│ → waits for merchant attestation OR TTL expiry │
└──────────────┬───────────────────────────────────┬─────────────┘
│ attest signed (delivery OK) │ TTL expired
▼ ▼
┌───────────────┐ ┌───────────────┐
│ release USDC │ │ refund USDC │
│ → merchant │ │ → agent owner │
└───────────────┘ └───────────────┘Programs
| Program | ID (devnet) | Responsibility |
|---|---|---|
aap_custody | DbpCDp…nFp | Escrow lifecycle: create, release, partial, refund + SPL-Token CPI |
aap_attestor | DcbEtM…Xaa | Merchant registry + Ed25519 verify via instructions sysvar |
PDAs
EscrowAccount @ [b"escrow", agent_owner, task_hash]
agent_owner Pubkey who deposits USDC
merchant Pubkey who can claim USDC
amount u64 stroops (1e6 = 1 USDC)
task_hash [u8;32] SHA256(intent ‖ pubkey ‖ nonce)
created_at i64
ttl_seconds u32 1 → 7d (default 24h)
state enum Pending|Fulfilled|Refunded|PartiallyFulfilled
proof_hash [u8;32] zeros while Pending
partial_pct u8 0 → 100
bump u8
MerchantRegistry @ [b"registry"] SINGLETON
admin Pubkey
merchant_count u64
bump u8
MerchantAccount @ [b"merchant", merchant_pubkey]
registry Pubkey
merchant_pubkey Pubkey
display_name String max 64
attestor_pubkey Pubkey Ed25519 key (HSM-friendly)
status enum Active|Suspended|Banned
reputation_score u32 basis points (0–10000)
total_volume u64
disputes_lost u32
Vault TokenAccount @ ATA(escrow_pda, mint)
owner escrow_pda
mint USDC (devnet) or mockCPI graph in release_escrow
user submits tx:
┌──────────────────────────────────────────────────┐
│ tx ix[n] = Ed25519Program.verify │ ← signed off-chain
│ tx ix[n+1] = aap_custody::release_escrow │ by merchant attestor
│ optional compute budget ixs may come before them │
└──────────────────────┬───────────────────────────┘
│ executes release ix:
▼
┌──────────────────────────────────────────────────┐
│ aap_custody::release_escrow │
│ 1. require state == Pending │
│ 2. require merchant == escrow.merchant │
│ 3. CPI ─────────────────────┐ │
│ ▼ │
│ ┌──────────────────────────────────────────┐ │
│ │ aap_attestor::verify_attestation │ │
│ │ • scan previous tx instructions │ │
│ │ • find program_id == Ed25519 │ │
│ │ • parse layout (offsets u16 LE) │ │
│ │ • require pubkey == attestor_pubkey │ │
│ │ • require message == expected (72 B) │ │
│ │ • freshness window [-60s, +300s] │ │
│ └──────────────────────────────────────────┘ │
│ │ Ok │
│ ▼ │
│ 4. SPL-Token Transfer (vault → merchant) │
│ 5. emit AttestationFulfilled │
└──────────────────────────────────────────────────┘Attestation message format
The merchant's attestor key signs a deterministic 72-byte payload:
message = escrow_pda (32 B) ‖ proof_hash (32 B) ‖ timestamp_le (8 B i64)
total length = 72 bytesThe Ed25519 instruction in the same transaction supplies (pubkey, message, signature); the on-chain program re-derives the expected message and rejects mismatches with MessageMismatch or PubkeyMismatch.
Defense-in-depth checks (release_escrow)
proof_hashmust be non-zeroescrow.state == Pendingctx.accounts.merchant.key() == escrow.merchant- CPI
verify_attestation(Ed25519 + pubkey + message + timestamp freshness) - SPL-Token transfer (vault → merchant)
Roadmap (V2)
Token-2022 transfer hooks
Wrap USDC into a Token-2022 mint with a transfer hook that gates movement on
EscrowState::Fulfilled. Cannot be replicated on EVM — a structural moat for SettleProof on Solana.Squads Grid arbitration
For escalated partial disputes, the resolver program will route to a Squads multisig committee instead of failing.
Off-chain attestation relay
Optional gas-sponsored relay so merchants don't pay tx fees per attestation. Trust-minimised by design — relay can't forge proofs.