Run the Live Demo
Reproduce the full pipeline on Fuji: vault → real USDC spends → on-chain Groth16 proof → ERC-8004 stamp → ICM crossing → gate clearance.
Prerequisites
- Foundry (v1.7.1 — same as CI) and Node 20+;
- a funded deployer key in
.env(PRIVATE_KEY=...): AVAX from the Builder Hub faucet, USDC from faucet.circle.com (Avalanche Fuji, ~10–20 USDC/day), and a little ECH on Echo for the gate deploy; npm ciat the repo root (circuit tooling) and insdk/,agent/,web/as needed.
1. Deploy the hub side
forge script script/DeployFuji.s.sol --rpc-url fuji-c --broadcastDeploys the verifier + hub, creates the vault against real USDC, registers a fresh agentId on the canonical ERC-8004 Identity Registry, binds it, and opens the validation window. Note the printed agentId and addresses.
2. Prove a window
node scripts/prove.js # regenerates proof calldata for the fixed demo window (3/2/1 USDC)
ACCOUNT_ADDRESS=<vault> HUB_ADDRESS=<hub> AGENT_ID=<id> \
forge script script/E2EFuji.s.sol --tc E2EFuji --rpc-url fuji-c --broadcastThree real USDC spends, then submitProof — Groth16 verified on-chain, response stamped into the Validation Registry (Fuji's reference deployment).
3. Cross the border
HUB_ADDRESS=<hub> forge script script/DeployGate.s.sol --rpc-url echo --broadcast
cast send <hub> "carryAttestation(uint256,bytes32,address)" <agentId> \
0x1278d1be4b987e847be3465940eb5066c4604a7fbd6e086900823597d81af4c1 <gate> \
--rpc-url fuji-c --private-key $PRIVATE_KEYcarryAttestation must be a raw cast send — Foundry's local EVM can't execute the Warp precompile.
No relayer serves the Fuji→Echo leg — the public testnet relayer has been dead on it since May 2026, and
icm-relayercannot peer with post-upgrade Fuji. The working path (the one the keeper automates) is self-delivery: pull the unsigned Warp message from the carry tx's precompile log, POST it to a localsignature-aggregator(v0.6.0-fuji), and submitreceiveCrossChainMessageon Echo yourself with the signed message in the predicate access list.keeper/lib.ts selfDeliver()is the reference implementation — with the keeper running you only send the carry; delivery happens on the next tick.
cast call <gate> "isCleared(uint256)(bool)" <agentId> --rpc-url echo # → true after delivery4. The treasurer vertical
HUB_ADDRESS=<hub> forge script script/DeployTreasurerFuji.s.sol --rpc-url fuji-c --broadcast
cd agent && TREASURER_ADDRESS=<treasurer> DAYS_TO_DEADLINE=0 npm run tickThe keeper reads independent FX references (ECB via frankfurter + open.er-api — Hermes moved behind an API key in July 2026 and is no longer touched), keeps the VerglasOracle shim fresh, runs the strategy, and executes a live payFX — circuit breaker checked, calendar-day cap enforced, vault pays the supplier.
5. Watch it on the site
web/ (npm run dev) renders everything live: hero clearance status, the crossing, and the treasurer panel — all straight from Fuji.
Attestations expire
The gate enforces maxAge = 7 days. For a stage demo, prove a fresh window + carry that morning.
