You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs(example): DEPLOY.md RWA runbook + Orbit gas gotcha, fix stale RPC/test-count/scenario-C status
Scenario C is live (was 'not implemented'). Added 3d (MockRwaRouter via forge
create --gas-limit) + RWA smoke (dry-run + cast send on Robinhood). Documented
the Orbit gas gotcha (forge script ignores gas flags). Fixed Robinhood RPC host
(rpc.testnet, not testnet.rpc), Arbitrum RPC to publicnode, test count 20->25,
deployed.json template + decoder note for both routers on both chains.
Copy file name to clipboardExpand all lines: examples/arbitrum-london/DEPLOY.md
+59-17Lines changed: 59 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,18 +1,21 @@
1
1
# Deploy runbook - txKit Arbitrum London Buildathon demo
2
2
3
-
Copy-paste deploy of the demo's on-chain pieces to Arbitrum Sepolia (scenario A, Pendle yield swap) and Robinhood Chain testnet (scenario C, gate only for now). Every command below is meant to be pasted as-is after you fill the env vars and the captured addresses.
3
+
Copy-paste deploy of the demo's on-chain pieces to Arbitrum Sepolia (scenario A, Pendle yield swap) and Robinhood Chain testnet (scenario C, x402-paid RWA buy). Both scenarios are live on both chains. Every command below is meant to be pasted as-is after you fill the env vars and the captured addresses.
4
4
5
-
Verified state at time of writing (2026-05-29): `forge build` + `forge test` green (20 tests: 15 AgentPolicyGate + 5 MockPendleRouter incl. an end-to-end gate->router integration test), app `tsc --noEmit` clean. The only thing standing between the repo and a live demo is this deploy, which needs a funded key you hold.
5
+
Verified state (2026-06-08): `forge build` + `forge test` green (25 tests: 15 AgentPolicyGate + 5 MockPendleRouter + 5 MockRwaRouter incl. end-to-end gate->router integration tests), app `tsc --noEmit`+ `next build` + 10 vitest clean. The deployed addresses + real tx hashes are in the README "Live on-chain" tables and `contracts/deployed.json`; this runbook reproduces them from a funded key you hold.
6
6
7
7
## What gets deployed
8
8
9
9
| Contract | Chain | Why | Verify on explorer |
10
10
|---|---|---|---|
11
-
|`AgentPolicyGate`| Arbitrum Sepolia (421614) | scenario A policy enforcement point | yes (Arbiscan) |
11
+
|`AgentPolicyGate`| Arbitrum Sepolia (421614) | scenario A + C policy enforcement point | yes (Arbiscan) |
|`AgentPolicyGate`| Robinhood Chain testnet (46630) | scenario A + C gate (sponsor chain) | no (explorer verifier API not published) |
15
+
|`MockPendleRouter`| Robinhood Chain testnet (46630) | scenario A inner target (proof) | no |
16
+
|`MockRwaRouter`| Robinhood Chain testnet (46630) | scenario C inner buy target (live /flow-c) | no |
14
17
15
-
Scenario C (RWA on Robinhood) does NOT need a router yet: `buildRwaEnvelope`still throws "not implemented" (lands Phase 2 Day 10), and `buildPendleEnvelope` hardcodes the router on Arbitrum Sepolia only. Deploy the Robinhood gate now purely for the "deployed on both chains" claim.
18
+
Both scenarios are live: `buildPendleEnvelope` targets Arbitrum Sepolia (`/flow-a`), `buildRwaEnvelope`targets Robinhood Chain (`/flow-c`, x402-gated). The RWA router was also deployed on Arbitrum as a bonus proof. See section 3d for the Robinhood RWA deploy and the Orbit gas gotcha.
16
19
17
20
## 0. Prerequisites
18
21
@@ -39,8 +42,8 @@ export AGENT_SIGNER_ADDRESS=0x... # address the gate will trust
39
42
export AGENT_SIGNER_PRIVATE_KEY=0x... # its private key (used by /api/agent)
## 3. Deploy to Robinhood Chain testnet (sponsor bonus - real tx on a second chain)
124
127
125
-
Same shape as step 2 but on chainId 46630, no `--verify` (explorer verifier API not published as of 2026-05-26). Deploying the router here too lets `SmokeExecuteEnvelope` (step 7) land a real `executeEnvelope` tx on Robinhood - the only way to get a Robinhood tx hash while scenario C has no UI flow.
128
+
Same shape as step 2 but on chainId 46630, no `--verify` (explorer verifier API not published).
129
+
130
+
**IMPORTANT - Orbit gas gotcha.** Robinhood's `eth_estimateGas` under-reports CREATE + L1-data cost, and `forge script` does NOT honour `--gas-estimate-multiplier` or `--gas-limit` here, so CREATE txs OOG at the raw estimate (observed gasUsed == gasLimit, status 0x0). Use `forge create --gas-limit` for contract deploys and `cast send --gas-limit` for state-changing calls; both honour the explicit limit (you only pay gasUsed). If a script-based deploy in 3a/3b OOGs, redo that contract with `forge create ... --gas-limit 3000000`.
Bonus: the same `forge create` against `--rpc-url arbitrum_sepolia --verify --etherscan-api-key $ARBISCAN_API_KEY` deploys + verifies the RWA router on Arbitrum too (Arbitrum honours normal gas estimation; the explicit `--gas-limit` is harmless there). Capture it as `RWA_ROUTER_ARB` and allow-list on `GATE_ARB`.
181
+
159
182
## 4. Wire the addresses into the app
160
183
161
184
Three files carry `0x__PENDING__` / `0x000...0` placeholders. The app throws a clear "not deployed yet" error until they hold real addresses (the regex gate is `^0x[a-fA-F0-9]{40}$` with no "PENDING" substring).
Also create `decoder-data/mock-rwa-router.json` (mirror `mock-pendle-router.json`: a `buy(address,bytes32,uint256)` descriptor with a `RwaPurchased` event + clear-signing labels) for both chains so the RWA inner call decodes as "Buy 5 TSLA" in the preview.
The tx hash prints in the broadcast output and is saved to `broadcast/SmokeExecuteEnvelope.s.sol/<chainId>/run-latest.json` under `transactions[0].hash`. Paste both contract addresses and the tx hashes into the "Live on-chain" tables in `examples/arbitrum-london/README.md` - that is the verifiable proof judges check.
286
+
RWA buy (scenario C). On Robinhood, `forge script --broadcast` OOGs (Orbit gas gotcha), so dry-run to compute the signed calldata, then send it with `cast` (which honours `--gas-limit`). On Arbitrum the script broadcast is fine.
The tx hash prints in the broadcast output and is saved to `broadcast/<Script>.s.sol/<chainId>/run-latest.json` under `transactions[0].hash` (for the cast-sent Robinhood RWA buy, the hash is in the `cast send` output). Paste both contract addresses and the tx hashes into the "Live on-chain" tables in `examples/arbitrum-london/README.md` - that is the verifiable proof judges check.
261
301
262
302
The gate enforces the prerequisites on-chain: a signer-pair mismatch reverts `InvalidSignature`, a missing allow-list reverts `RecipientNotAllowed`. If the script succeeds, the demo path is sound.
263
303
@@ -267,3 +307,5 @@ The gate enforces the prerequisites on-chain: a signer-pair mismatch reverts `In
267
307
- The allow-list step (2c) is the single easiest thing to forget - the gate compiles and deploys fine without it, then reverts only at execute time.
268
308
- Signer-pair mismatch (step 1) fails the same way: silent until execute. Check it before you spend gas.
269
309
- Robinhood verify is intentionally skipped; do not pass `--verify` there or the broadcast errors out on a missing verifier.
310
+
- Orbit gas gotcha (Robinhood): `forge script` ignores `--gas-estimate-multiplier` and `--gas-limit` in Foundry 1.7.1, and `eth_estimateGas` under-reports CREATE/L1-data, so script-broadcast deploys OOG at the raw estimate. Fix: `forge create --gas-limit 3000000` for deploys, and for executeEnvelope-style calls run the smoke script as a dry-run (no `--broadcast`) then `cast send <gate> <calldata> --gas-limit 1500000`. `cast` honours the explicit limit.
311
+
- Robinhood RPC host is `rpc.testnet.chain.robinhood.com` (not `testnet.rpc...`). The public RPC is rate-limited; an Alchemy Robinhood key is more reliable for repeated calls.
0 commit comments