across-pay-mpp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.env ADDED
@@ -0,0 +1,3 @@
1
+ TEMPO_WALLET_PRIVATE_KEY=0xe9fad02b3b0c226929ef15ae8ec790c0ddc110ab9f652f0575eedc3f085de00e
2
+ MERCHANT_KEY=0x9593f890cb5779da1817bd921712d8446e7468f84b887a342fe5bf8795ce2f8b
3
+ PORT=3000
package/.env.example ADDED
@@ -0,0 +1,5 @@
1
+ TEMPO_WALLET_PRIVATE_KEY=0xyour_tempo_demo_private_key
2
+ # Legacy fallback still accepted by the demo wallet adapter:
3
+ # AGENT_PRIVATE_KEY=0xyour_agent_private_key
4
+ MERCHANT_KEY=0xyour_merchant_private_key
5
+ PORT=3000
@@ -0,0 +1,7 @@
1
+ {
2
+ "publishes": {
3
+ "frosty-plume-fvac": {
4
+ "siteUrl": "https://frosty-plume-fvac.here.now/"
5
+ }
6
+ }
7
+ }
package/PRD.md ADDED
@@ -0,0 +1,236 @@
1
+ # Across MPP Skill
2
+ Enable agents to pay for MPP-protected resources from any chain using Across as a transparent crosschain funding layer.
3
+
4
+ **Team:** Across Protocol
5
+ **Contributors:** Hart Lambur (Product), Bobby Bola (Engineering)
6
+ **Resources:** [Hart/Bobby Call Notes](https://docs.google.com/document/d/1XerVgt6PDbJJiqmjs5cxpH1TrX9NKTzjNIup4QMEON0/edit), [MPP Docs](https://mpp.dev), [Across Docs](https://docs.across.to), [Tempo Docs](https://docs.tempo.xyz)
7
+ **Status:** Draft
8
+ **Last Updated:** Monday, March 24, 2026
9
+
10
+ ---
11
+
12
+ ## Problem Alignment
13
+
14
+ **Agents receiving a 402 Payment Required response cannot pay if their funds are on a different chain than the one the merchant expects.** MPP (Machine Payments Protocol) tells agents exactly where and how to pay, but if the agent holds USDC on Base and the merchant wants USDC on Tempo, the payment fails. There is no fallback.
15
+
16
+ **Why does this matter to our customers and business?**
17
+
18
+ - MPP is the emerging standard for machine-to-machine payments (co-developed by Tempo and Stripe). As adoption grows, agents will encounter 402 payment gates across hundreds of services, each potentially on a different chain. An agent that can only pay on one chain is severely limited.
19
+ - Across is the leading crosschain intents protocol. If Across can transparently solve the "wrong chain" problem inside MPP, it becomes critical infrastructure for every agent making payments. This positions Across as the default crosschain rail for the entire MPP ecosystem.
20
+ - Strategic partnerships with Tempo, Stripe, Coinbase, and Solana Foundation all benefit from Across making it easy to accept payments on any chain. Each partner can promote "accept payments everywhere, settle on your preferred chain" powered by Across.
21
+
22
+ **What evidence or insights do we have?**
23
+
24
+ - MPP is live and functional. Bobby has a working MPP implementation on testnet with Tempo charge and session payments.
25
+ - Hart validated with Dan (Tempo/Paradigm) that MPP commoditizing payment chains is a world Across should push for — it increases Across's utility as the universal settlement layer.
26
+ - The MPP SDK (`mppx`) has an async `createCredential` hook that allows arbitrary logic before payment signing, making the integration technically clean.
27
+
28
+ ---
29
+
30
+ ## High Level Approach
31
+
32
+ Wrap the existing Tempo payment method with an Across pre-funding step. When an agent gets a 402 and doesn't have funds on the destination chain, Across bridges the shortfall to the agent's own address on that chain, then the standard payment completes as normal. The merchant never knows Across was involved. No protocol changes required.
33
+
34
+ ---
35
+
36
+ ## Goals
37
+
38
+ 1. **Agent can pay any Tempo MPP merchant from any Across-supported chain** — the core product promise. Agent has funds on Base, merchant wants Tempo, payment succeeds.
39
+ 2. **Zero merchant-side changes** — works with the existing Tempo/Stripe payment flow. Tempo and Stripe don't change a thing.
40
+ 3. **Transparent to the protocol** — the credential the merchant receives is a standard Tempo credential. Across is invisible middleware on the agent side.
41
+ 4. **Demoable end-to-end flow** — a working demo that shows: agent on Base -> 402 -> Across bridge -> Tempo charge -> resource unlocked. Something we can show Tempo, Stripe, and partners.
42
+ 5. **Foundation for Step 2** — the architecture should inform the merchant-side multi-chain acceptance + sweep story without blocking on it.
43
+
44
+ **Immeasurable goals:**
45
+ - An agent developer should feel like crosschain payments "just work" — no extra config, no new methods to learn.
46
+ - Hart, Dan, and partners should look at the demo and immediately see how this plugs into their ecosystem.
47
+
48
+ ## Non-goals
49
+
50
+ - **Building a new MPP payment method** — we are not creating an "across" payment method alongside "tempo". We are augmenting the existing tempo method. Creating a new method would require merchant adoption and fragment the ecosystem.
51
+ - **Merchant-side multi-chain sweep (Step 2)** — deploying contracts on every chain, accepting payments everywhere, and periodically rebalancing to a preferred chain via Across. This is the next phase, not this one.
52
+ - **Virtual addresses (Step 3)** — Tempo's virtual address concept (sub-addresses with encoded crosschain instructions) is interesting but premature. Deferred until Tempo ships the feature.
53
+ - **x402 compatibility** — Coinbase's x402 is a separate but similar protocol. We should build for both eventually, but this PRD focuses on MPP/Tempo. The architecture should be portable.
54
+ - **Production key management** — for this phase, a private key in an env var is sufficient. WebAuthn/passkey/KMS integration is a production concern for later.
55
+ - **Gas optimization** — for 2-cent micropayments, per-request bridging doesn't make economic sense (bridging costs may exceed payment). That's exactly what Step 2 solves. Step 1 targets payments where the bridge cost is acceptable relative to the payment amount.
56
+
57
+ ---
58
+
59
+ ## Solution Alignment
60
+
61
+ ### Key Features
62
+
63
+ **Plan of record:**
64
+
65
+ 1. **Working MPP/Tempo baseline** — standard mppx client with Tempo payment method, tested against `mpp.dev/api/ping/paid`. This validates the payment flow works before adding Across.
66
+
67
+ 2. **Across pre-funding wrapper** — the core feature. Wraps `tempo()` client method's `createCredential` with balance-check-and-bridge logic. If the agent has funds on the destination chain, the wrapper is a no-op. If not, it bridges the shortfall via Across to the agent's own address on the destination chain, then delegates to the standard Tempo signing.
68
+
69
+ 3. **Across API integration layer** — helpers for quote fetching (`GET /swap/approval`), transaction execution, and deposit status polling. Thin wrapper around the Across Swap API.
70
+
71
+ 4. **Demo surface (Agent Shop)** — simple server with a premium endpoint behind a standard Tempo payment gate. The server is vanilla mppx — no custom verifier, no awareness of Across. Proves the wrapper works transparently.
72
+
73
+ 5. **402 challenge documentation** — captured and documented real 402 response shape, decoded challenge fields, credential format. Serves as the internal protocol reference.
74
+
75
+ **Future considerations:**
76
+
77
+ - **Step 2: Merchant multi-chain acceptance + Across sweep** — merchants deploy lightweight contracts on multiple chains, accept payments natively, and Across rebalances to their preferred chain hourly/daily. This is the pitch to Stripe, Tempo, Coinbase, and Solana. Architecture from Step 1 informs but doesn't block this.
78
+ - **Step 2: x402 support** — same Across pre-funding wrapper pattern applied to Coinbase's x402 protocol. Portable architecture.
79
+ - **Step 3: Virtual addresses** — Tempo's upcoming feature where sub-addresses encode crosschain routing instructions. Could eliminate the need for agent-side bridging entirely.
80
+ - **Session (pay-as-you-go) support** — Step 1 targets `charge` (one-time payments). Extending to `session` (streaming micropayments) where the agent pre-funds a payment channel on Tempo.
81
+ - **Multi-chain balance detection** — automatically detect which chain the agent has funds on, rather than hardcoding an origin chain. Could query balances across all Across-supported chains and pick the cheapest/fastest route.
82
+
83
+ ### Key Flows
84
+
85
+ **Flow 1: Agent pays Tempo merchant from a different chain (primary flow)**
86
+
87
+ ```
88
+ Agent (funds on Base) Across Merchant (Tempo)
89
+ | | |
90
+ |--- GET /premium-resource ------------------------------------->|
91
+ |<-- 402 Payment Required + WWW-Authenticate: tempo charge ------|
92
+ | (amount: "100000", currency: "USDC", recipient: "0xMerch") |
93
+ | | |
94
+ | [createCredential fires] | |
95
+ | [check USDC balance on Tempo: $0]| |
96
+ | [need $1 USDC, bridge shortfall] | |
97
+ | | |
98
+ |--- GET /swap/approval ---------->| |
99
+ | originChainId: 8453 (Base) | |
100
+ | destChainId: 4217 (Tempo) | |
101
+ | amount: "100000" | |
102
+ | recipient: agent's own addr | |
103
+ | tradeType: exactOutput | |
104
+ |<-- quote + swap tx data ---------| |
105
+ | | |
106
+ |--- sign + send swap tx -------->| |
107
+ | (1 tx on Base) | |
108
+ | |--- relayer fills ------->|
109
+ | | (USDC to agent addr) |
110
+ |<-- fill confirmed (~5-15s) -----| |
111
+ | | |
112
+ | [agent now has USDC on Tempo] | |
113
+ | [sign standard EIP-3009 TransferWithAuthorization] |
114
+ | | |
115
+ |--- GET /premium-resource (retry) + Tempo credential ------->|
116
+ |<-- 200 + premium content ----------------------------------------|
117
+ ```
118
+
119
+ **Flow 2: Agent already has funds on destination chain (pass-through)**
120
+
121
+ ```
122
+ Agent (funds on Tempo) Merchant (Tempo)
123
+ | |
124
+ |--- GET /premium-resource --------------------------------->|
125
+ |<-- 402 + WWW-Authenticate: tempo charge ------------------|
126
+ | |
127
+ | [createCredential fires] |
128
+ | [check USDC balance on Tempo: sufficient] |
129
+ | [skip bridge — no-op] |
130
+ | [sign standard Tempo charge] |
131
+ | |
132
+ |--- GET /premium-resource (retry) + Tempo credential --->|
133
+ |<-- 200 + premium content -------------------------------|
134
+ ```
135
+
136
+ **Flow 3: Bridge completes but challenge expired (graceful retry)**
137
+
138
+ ```
139
+ Agent (funds on Base) Across Merchant (Tempo)
140
+ | | |
141
+ |--- GET /resource ------------------------------------------>|
142
+ |<-- 402 + challenge (expires in 30s) -----------------------|
143
+ | | |
144
+ | [bridge takes 25s...] | |
145
+ | [challenge expired during bridge]| |
146
+ | [but funds are now on Tempo!] | |
147
+ | | |
148
+ |--- GET /resource (new request) ----------------------------->|
149
+ |<-- 402 + fresh challenge -----------------------------------|
150
+ | | |
151
+ | [have funds on Tempo now] | |
152
+ | [sign immediately — instant] | |
153
+ | | |
154
+ |--- GET /resource (retry) + Tempo credential --------------->|
155
+ |<-- 200 + resource ------------------------------------------|
156
+ ```
157
+
158
+ ### Key Logic
159
+
160
+ | Rule | Detail |
161
+ |------|--------|
162
+ | **Bridge to self, never to merchant** | Across always bridges to the agent's own address on the destination chain. The agent retains control of funds if anything goes wrong downstream. The standard Tempo charge handles the merchant payment. |
163
+ | **Bridge only the shortfall** | If the agent has $0.50 on Tempo and needs $1.00, bridge $0.50, not $1.00. Use `tradeType: exactOutput` for precise amounts. |
164
+ | **No-op when funded** | If balance >= needed amount, skip the bridge entirely. The wrapper adds zero latency to the happy path. |
165
+ | **Challenge expiry is recoverable** | If the bridge takes longer than the challenge allows, the agent simply makes a new request. Funds are already on Tempo, so the retry is instant. This is not a failure — it's the expected flow for slow bridges. |
166
+ | **One origin-chain transaction** | The agent executes one tx (the bridge swap on Base). The Tempo charge is an off-chain signature. With server fee sponsorship, the agent needs zero gas on Tempo. |
167
+ | **Token address mapping** | USDC has different contract addresses per chain. The wrapper needs a mapping from the challenge's token (on Tempo) to the equivalent token on the origin chain. Across's discovery endpoint provides this. |
168
+ | **Gas on Tempo** | Not required for the agent. The Tempo charge is an EIP-3009 off-chain signature. The server/facilitator broadcasts the on-chain tx and can sponsor gas via Tempo's `feePayer` feature. |
169
+
170
+ ---
171
+
172
+ ## Launch Plan
173
+
174
+ ### Key Milestones
175
+
176
+ | Target Date | Milestone | Description | Exit Criteria |
177
+ |-------------|-----------|-------------|---------------|
178
+ | 2026-03-25 | Phase 1: Tempo Baseline | Basic mppx client with Tempo payments working | Successfully pay `mpp.dev/api/ping/paid`, 402 challenge shape documented |
179
+ | 2026-03-27 | Phase 2: Across Wrapper | Pre-funding wrapper around tempo() with Across bridge | Agent on Base successfully pays a Tempo merchant end-to-end |
180
+ | 2026-03-28 | Phase 3: Demo Surface | Agent Shop with standard Tempo payment gate | Demoable end-to-end flow: agent on Base -> 402 -> bridge -> pay -> resource |
181
+ | 2026-03-31 | Review with Hart | Demo the working flow, discuss Step 2 | Hart validates direction, agrees on Step 2 scope |
182
+
183
+ **Risks and dependencies:**
184
+
185
+ | Risk | Impact | Mitigation |
186
+ |------|--------|------------|
187
+ | `mppx` tempo() method's `createCredential` may not be wrappable | Blocks the wrapper approach | Fallback: use `Method.toClient` with the same Tempo method definition and implement signing manually |
188
+ | Across fill times may exceed typical challenge expiry | Agent needs two requests instead of one | Acceptable — second request is instant since funds are already on Tempo. Document this as expected behavior. |
189
+ | Tempo testnet may have reliability issues | Blocks testing | Use `mpp.dev/api/ping/paid` as primary test surface; fall back to local demo server |
190
+ | Agent needs a funded wallet on Base (testnet) for testing | Blocks end-to-end demo | Fund a test wallet via Base Sepolia faucet or Across testnet |
191
+
192
+ ### Operational Checklist
193
+
194
+ | Team | Prompt | Y/N | Action |
195
+ |------|--------|-----|--------|
196
+ | Partners | Will this impact Tempo or Stripe? | No | Agent-side only. No partner changes needed for Step 1. |
197
+ | Partners | Should we coordinate with Dan/Tempo? | Yes | Share demo with Dan after Phase 3. Discuss promoting Across skill on Tempo docs. |
198
+ | Risk | Does this expose a risk vector? | Yes | Agent funds are at risk during bridge. Mitigated by bridge-to-self (agent retains control). Never bridge directly to merchant. |
199
+ | Legal | Are there potential legal ramifications? | No | Standard crosschain bridge usage. No custody of user funds. |
200
+
201
+ ---
202
+
203
+ ## Appendix
204
+
205
+ ### Changelog
206
+
207
+ | Date | Description |
208
+ |------|-------------|
209
+ | 2026-03-24 | Initial PRD drafted from Hart/Bobby call notes and architecture review. Key decision: Across integrates INTO the existing Tempo flow (wrapping `tempo()` createCredential), not as a separate payment method. |
210
+
211
+ ### Open Questions
212
+
213
+ | # | Question | Status | Answer |
214
+ |---|----------|--------|--------|
215
+ | 1 | Can we wrap `tempo()` return value's `createCredential` directly, or do we need to use `Method.toClient`? | Open | Need to inspect mppx source or test empirically |
216
+ | 2 | What is the actual challenge expiry time for Tempo merchants? | Open | Will capture from real 402 in Phase 1 |
217
+ | 3 | Which testnet should we use for end-to-end testing? | Open | Tempo testnet + Base Sepolia likely |
218
+ | 4 | Should we support multiple origin chains in Step 1, or just Base? | Open | Recommend Base only for Step 1, multi-chain in Step 2 |
219
+ | 5 | How does the Across Swap API handle Tempo (chain 4217)? Is it supported? | Open | Need to verify via Across API discovery endpoint |
220
+
221
+ ### FAQs
222
+
223
+ **Q: Why not create a separate "across" payment method?**
224
+ A: Because it would require every merchant to explicitly add the "across" method to their server. Hart's constraint is clear: Tempo and Stripe change nothing. By wrapping the existing Tempo method, every Tempo merchant automatically works with Across-powered agents.
225
+
226
+ **Q: What happens if the bridge fails?**
227
+ A: The agent's funds stay on the origin chain (the bridge tx reverts or never completes). The `createCredential` function throws an error, and the mppx client returns a payment failure. No money is lost because we bridge to the agent's own address, not to the merchant.
228
+
229
+ **Q: Isn't per-request bridging expensive for micropayments?**
230
+ A: Yes. For 2-cent payments, bridge gas costs may exceed the payment itself. That's exactly what Step 2 solves: merchants accept payments on multiple chains natively, and Across sweeps balances back to their preferred chain periodically. Step 1 targets payments where the amount justifies the bridge cost.
231
+
232
+ **Q: How is this different from x402?**
233
+ A: x402 is Coinbase's version of the same concept (HTTP 402 payment protocol). MPP is Stripe/Tempo's version. They're architecturally similar. The Across pre-funding wrapper pattern is portable to x402 — we'd just wrap the x402 payment method instead of the Tempo one. We start with MPP because of the Dan/Tempo relationship.
234
+
235
+ **Q: Can the agent pre-sign the Tempo charge before the bridge completes?**
236
+ A: No. The EIP-3009 `TransferWithAuthorization` requires the signer to have a sufficient token balance at execution time. The server verifies this when broadcasting. The bridge must complete first.
@@ -0,0 +1,214 @@
1
+ # Across MPP Progress Update
2
+
3
+ ## Latest: March 25, 2026 — Real Merchant Test Passed
4
+
5
+ **The full Across + MPP flow works against a real production merchant.** An agent with USDC on Base scraped the Across homepage via Firecrawl, paying $0.002 on Tempo after bridging funds crosschain via Across. Firecrawl had no idea Across was involved — it saw a standard Tempo charge.
6
+
7
+ ### The Proof: Firecrawl Scrape via Across Bridge
8
+
9
+ | Field | Value |
10
+ |-------|-------|
11
+ | Time | 2026-03-25T09:04:59 UTC |
12
+ | Merchant | Firecrawl (production) |
13
+ | Result | **SUCCESS (via Across bridge)** |
14
+ | Total time | 27.9 seconds |
15
+ | Payment | $0.002 USDC.e to Firecrawl |
16
+ | Bridge cost | ~$0.025 (Base USDC → Tempo USDC.e) |
17
+ | Content received | "Fast, Cheap, Secure Crosschain Bridge for ETH, WBTC, USDC & USDT" — 4821 chars |
18
+ | Proof file | `firecrawl-response.json` |
19
+
20
+ ### Transaction Trail
21
+
22
+ | Step | Explorer Link |
23
+ |------|--------------|
24
+ | Bridge deposit (Base) | [basescan.org/tx/0x345470...](https://basescan.org/tx/0x3454709c2725aa34d29dbd353bef3088c94d8138832871c073569d8ccb3a5483) |
25
+ | Across transfer | [app.across.to/transfer/0x345470...](https://app.across.to/transfer/0x3454709c2725aa34d29dbd353bef3088c94d8138832871c073569d8ccb3a5483) |
26
+ | Bridge fill (Tempo) | [explore.tempo.xyz/tx/0x36f2d0...](https://explore.tempo.xyz/tx/0x36f2d0ac16078be1278f6edaee4b52d4b12c5eae53ea8dd3f40b2f4305a0b16a) |
27
+ | Tempo payment | [explore.tempo.xyz/tx/0x9e3685...](https://explore.tempo.xyz/tx/0x9e368560c6505687b3b36c1496be7c3ea3a78c4f9ecf778ccf3a2f5fa70da8df) |
28
+ | Firecrawl recipient | [explore.tempo.xyz/address/0xca4e83...](https://explore.tempo.xyz/address/0xca4e835F803cB0b7C428222B3A3B98518d4779Fe) |
29
+
30
+ ### Also tested: Direct Tempo charge (no bridge)
31
+
32
+ When the agent already had USDC.e on Tempo, the bridge was skipped and the charge went through directly in 20.7 seconds. This validates both paths:
33
+ - **With Across:** agent has no Tempo funds → bridge from Base → pay → get content
34
+ - **Without Across:** agent has Tempo funds → pay directly → get content
35
+
36
+ ---
37
+
38
+ ## Previous: March 24, 2026 — Local Server Test Passed
39
+
40
+ First successful Across bridge + Tempo charge against our own demo server on mainnet.
41
+
42
+ | Field | Value |
43
+ |-------|-------|
44
+ | Time | 2026-03-24T23:14:28 UTC |
45
+ | Merchant | Local demo server (localhost:3000) |
46
+ | Result | **SUCCESS (via Across bridge)** |
47
+ | Total time | 13.8 seconds |
48
+ | Payment | $0.15 USDC.e to merchant |
49
+
50
+ ### Transaction Trail (March 24)
51
+
52
+ | Step | Explorer Link |
53
+ |------|--------------|
54
+ | Bridge deposit (Base) | [basescan.org/tx/0x6a39cc...](https://basescan.org/tx/0x6a39cc1087066ea00f2b878565d9cdaee76d821489d7f094a10293d461da40f4) |
55
+ | Across transfer | [app.across.to/transfer/0x6a39cc...](https://app.across.to/transfer/0x6a39cc1087066ea00f2b878565d9cdaee76d821489d7f094a10293d461da40f4) |
56
+ | Bridge fill (Tempo) | [explore.tempo.xyz/tx/0x547d9c...](https://explore.tempo.xyz/tx/0x547d9ca9e4560ffc2cdb5bce8dc5ce6ca557f62b878d418f4e2e32d1041b812b) |
57
+ | Tempo payment | [explore.tempo.xyz/tx/0xa7d784...](https://explore.tempo.xyz/tx/0xa7d784057eddee97b3459a2f21b54daec356c4e597a0472ccdf4f503d29b45fa) |
58
+
59
+ ---
60
+
61
+ ## What We Built
62
+
63
+ ### Architecture
64
+
65
+ ```
66
+ Agent (Base USDC) → Across Bridge (~2-5s fill) → Tempo USDC.e → Tempo Charge → Merchant paid
67
+ ```
68
+
69
+ Across is wrapped INSIDE the existing Tempo payment method via mppx's `onChallenge` hook. The merchant sees a standard Tempo credential. No protocol changes, no new payment methods, no server-side modifications.
70
+
71
+ ### Components
72
+
73
+ | File | Purpose |
74
+ |------|---------|
75
+ | `src/buyer/tempo-with-across.ts` | **Core wrapper** — `onChallenge` hook checks Tempo balance, bridges via Across if needed, then delegates to standard Tempo charge |
76
+ | `src/buyer/across.ts` | Across API helpers — quote fetching, deposit status polling, chain/token config |
77
+ | `src/buyer/balance.ts` | Token balance checker for Tempo mainnet and origin chains |
78
+ | `src/dev/server.ts` | Demo MPP server on Tempo mainnet with separate merchant address |
79
+ | `src/demo/external.ts` | Test against real MPP merchants (Firecrawl) with proof-of-access logging |
80
+ | `src/demo/local.ts` | Test against local demo server with full logging |
81
+ | `src/dev/preflight.ts` | Pre-test validation (free, no transactions) |
82
+ | `src/capture-402.ts` | Raw 402 challenge inspection tool |
83
+
84
+ ### How the onChallenge Hook Works
85
+
86
+ ```ts
87
+ // Inside Mppx.create({ onChallenge: ... })
88
+
89
+ 1. Parse 402 challenge (amount, currency, recipient, chain)
90
+ 2. Check USDC.e balance at agent's key address on Tempo
91
+ 3. If sufficient → skip bridge → standard Tempo charge proceeds
92
+ 4. If insufficient → calculate shortfall + gas buffer (0.01 USDC.e)
93
+ 5. Get Across quote (exactOutput, Base USDC → Tempo USDC.e)
94
+ 6. Send approval tx on Base → wait for confirmation
95
+ 7. Send bridge tx on Base → wait for confirmation
96
+ 8. Poll Across deposit status → wait for fill on Tempo (~2-5s)
97
+ 9. Return undefined → standard Tempo charge proceeds with new balance
98
+ ```
99
+
100
+ ---
101
+
102
+ ## Addresses
103
+
104
+ | Role | Address | Explorer |
105
+ |------|---------|----------|
106
+ | Agent (buyer) | `0x8d2FD2173f5d40Ef4691cE8009D788950F843EBc` | [Base](https://basescan.org/address/0x8d2FD2173f5d40Ef4691cE8009D788950F843EBc) / [Tempo](https://explore.tempo.xyz/address/0x8d2FD2173f5d40Ef4691cE8009D788950F843EBc) |
107
+ | Demo merchant | `0x530F217b0E9EC0a782613857BFFB26D09DE317Fd` | [Tempo](https://explore.tempo.xyz/address/0x530F217b0E9EC0a782613857BFFB26D09DE317Fd) |
108
+ | Firecrawl merchant | `0xca4e835F803cB0b7C428222B3A3B98518d4779Fe` | [Tempo](https://explore.tempo.xyz/address/0xca4e835F803cB0b7C428222B3A3B98518d4779Fe) |
109
+
110
+ ## Current Wallet State (March 25)
111
+
112
+ | Chain | Asset | Balance | Address |
113
+ |-------|-------|---------|---------|
114
+ | Base | USDC | ~5.99 | `0x8d2F...3EBc` (agent) |
115
+ | Base | ETH | ~0.0004 | `0x8d2F...3EBc` (agent) |
116
+ | Tempo (SCW) | USDC.e | ~10.5 | `0xbceb...c435` (wallet) |
117
+ | Tempo (key) | USDC.e | ~0.01 | `0x8d2F...3EBc` (agent, leftover from bridge buffer) |
118
+
119
+ ---
120
+
121
+ ## What We Learned
122
+
123
+ ### Tempo Networks
124
+ - **Mainnet** (chain 4217, `rpc.tempo.xyz`) — production MPP services (Firecrawl, Browserbase, Tavily), Across bridges here
125
+ - **Moderato/Testnet** (chain 42431, `rpc.moderato.tempo.xyz`) — `mpp.dev/api/ping/paid` lives here, Across does NOT support this
126
+ - mppx auto-selects network based on the challenge's `chainId`
127
+
128
+ ### Tempo Account Model
129
+ - Smart contract wallets (SCW) hold funds; keys are authorized signers
130
+ - mppx checks balance at the key address, not the wallet
131
+ - Across deposits directly to the key address, bypassing the SCW
132
+ - `tempo wallet transfer` moves funds within the wallet system, not to key's EOA balance
133
+
134
+ ### Token Types
135
+ - **pathUSD** (`0x20c...0000`) — testnet default
136
+ - **USDC.e** (`0x20c...b9537d`) — mainnet default, what Across delivers and merchants charge
137
+
138
+ ### Bugs Fixed (March 24)
139
+ 1. Approval tx not confirmed before bridge tx → added `waitForTransactionReceipt`
140
+ 2. No gas buffer → added 0.01 USDC.e buffer to shortfall
141
+ 3. Wrong network (testnet vs mainnet) → switched to mainnet services
142
+ 4. Fee sponsorship failed (empty merchant) → enabled after merchant received funds
143
+
144
+ ---
145
+
146
+ ## Full Test History
147
+
148
+ | # | Date | Time | Target | Result | Across | Issue |
149
+ |---|------|------|--------|--------|--------|-------|
150
+ | 1 | Mar 24 | 19:41 | mpp.dev (testnet) | ERROR | No | Wrong token (pathUSD vs USDC.e) |
151
+ | 2 | Mar 24 | 19:41 | mpp.dev (testnet) | ERROR | Attempted | Approval tx not confirmed |
152
+ | 3 | Mar 24 | 22:22 | mpp.dev (testnet) | ERROR | No | Same token issue |
153
+ | 4 | Mar 24 | 22:24 | mpp.dev (testnet) | ERROR | Yes (bridge worked!) | Bridge to mainnet, merchant on testnet |
154
+ | 5 | Mar 24 | 22:48 | localhost (mainnet) | ERROR | No | Fee sponsor empty |
155
+ | 6 | Mar 24 | 22:51 | localhost (mainnet) | **SUCCESS** | No (had balance) | Direct charge, no bridge needed |
156
+ | 7 | Mar 24 | 23:06 | localhost (mainnet) | ERROR | Yes (bridge worked!) | No gas buffer |
157
+ | 8 | Mar 24 | 23:14 | localhost (mainnet) | **SUCCESS** | **Yes** | Full Across bridge + charge |
158
+ | 9 | Mar 25 | 08:59 | Firecrawl (mainnet) | **SUCCESS** | No (had balance) | Direct charge to real merchant |
159
+ | 10 | Mar 25 | 09:04 | Firecrawl (mainnet) | **SUCCESS** | **Yes** | **Full flow: Across bridge → real merchant** |
160
+
161
+ ---
162
+
163
+ ## March 25, 2026 (afternoon) — Skill Packaged & Tested on Fresh Instance
164
+
165
+ **The Across MPP Bridge skill works end-to-end on a completely fresh Claude Code instance** — no prior context, no memory, no existing code. A cold agent picked up the skill, wrote the code, connected to Firecrawl, and successfully scraped content via crosschain payment.
166
+
167
+ ### Skill evolution (4 iterations)
168
+
169
+ | Version | Change | Result |
170
+ |---------|--------|--------|
171
+ | v0.1 | Initial — 3 files, hardcoded Tempo, dotenv setup | Worked but agent hardcoded origin chain, top-level await broke |
172
+ | v0.2 | Removed dotenv, wrapped in `async main()`, better triggers | Fixed breakage, agent still over-specified config |
173
+ | v0.3 | Chain-agnostic (dynamic routes), auto-detect origin, accept any payment methods | Generic — works with any merchant on any Across-supported chain |
174
+ | v0.4 | **Single file**, graceful RPC failure handling, removed `originChainIds` hint from example | Clean. Fresh agent used it successfully without over-specializing |
175
+
176
+ ### What the skill does
177
+
178
+ One file (`src/mpp-with-across.ts`, ~150 lines) that wraps any mppx payment method with Across bridging:
179
+ - Reads destination chain from the 402 challenge (`methodDetails.chainId`)
180
+ - Auto-detects which origin chain the agent has funds on
181
+ - Dynamically discovers Across routes via `GET /available-routes`
182
+ - Bridges shortfall + gas buffer, waits for fill
183
+ - Standard payment charge proceeds — merchant sees normal credential
184
+ - Stripe/Lightning/Card pass through untouched (no `chainId` = no bridge)
185
+
186
+ ### Skill location
187
+
188
+ `/Users/bobbybola/agentmpp/across-mpp-bridge/SKILL.md`
189
+
190
+ ### Key learnings from skill testing
191
+
192
+ 1. **Don't hint at hardcoding** — showing `originChainIds: [8453]` even as a comment caused the agent to hardcode it
193
+ 2. **Single file > multiple files** — 3 files for 200 lines was over-modularized. Fresh agents create unnecessary helper files
194
+ 3. **Wrap in `async main()`** — top-level await breaks under tsx/CJS, the most common way people run .ts
195
+ 4. **Graceful RPC failures** — silently skip chains with bad RPCs instead of crashing the whole auto-detect loop
196
+ 5. **Trigger description matters** — vague descriptions don't activate the skill. Needs explicit coding keywords like "set up", "add", "handle 402", "crosschain integration"
197
+
198
+ ---
199
+
200
+ ## Next Steps
201
+
202
+ ### Immediate
203
+ 1. **Publish skill to GitHub** — host at `across-protocol/skills` or separate repo, installable via `npx skills add`
204
+ 2. **Test with more merchants** — Browserbase ($0.01), Tavily ($0.09) to verify chain-agnostic behavior
205
+ 3. **Test with non-Base origin** — verify auto-detect picks Arbitrum/Optimism when funds are there
206
+
207
+ ### Step 2 (Hart's roadmap)
208
+ 4. **Merchant multi-chain acceptance** — merchants accept payments on multiple chains, Across sweeps to preferred chain periodically
209
+ 5. **Pitch to Tempo/Stripe** — "accept payments from any chain, settle on your preferred chain"
210
+ 6. **x402 support** — same Across wrapper pattern for Coinbase's protocol
211
+
212
+ ### Step 3 (future)
213
+ 7. **Solana origin chain support** — needs `@solana/web3.js` for signing (currently Solana is destination-only)
214
+ 8. **Virtual addresses** — Tempo's upcoming feature for sub-address routing
package/README.md ADDED
@@ -0,0 +1,35 @@
1
+ # MPP Tempo Buyer Demo
2
+
3
+ Tempo-first MPP buyer demo with Across pre-funding.
4
+
5
+ ## What Lives Here
6
+
7
+ - `src/buyer/` contains the MPP buyer flow and Across funding logic.
8
+ - `src/demo/` contains runnable demo entrypoints.
9
+ - `src/dev/` contains local-only dev helpers and the local seller.
10
+ - `STEP2-DEMO-PLAN.md` is the agreed build plan for the separate MPP Step 2 batching demo.
11
+
12
+ ## Wallet Surface
13
+
14
+ The demo uses a **Tempo-native smart account** via `Account.fromSecp256k1()` from `viem/tempo`. This gives the buyer proper Tempo signature envelopes, access key support, and fee sponsorship capability — unlike a plain viem EOA.
15
+
16
+ The wallet is resolved through `src/buyer/tempo-wallet.ts`:
17
+
18
+ - Preferred env: `TEMPO_WALLET_PRIVATE_KEY`
19
+ - Backward-compatible fallback: `AGENT_PRIVATE_KEY`
20
+
21
+ ## Commands
22
+
23
+ ```bash
24
+ npm install
25
+ npm run preflight
26
+ npm run demo:local
27
+ npm run demo:external
28
+ npm run dev:server
29
+ ```
30
+
31
+ ## Notes
32
+
33
+ - `demo:local` targets the local MPP dev seller by default.
34
+ - `demo:external` targets Firecrawl on Tempo mainnet.
35
+ - The local dev server remains here for smoke testing and workflow demos, but the product-facing story is buyer-first.
package/SESSION-LOG.md ADDED
@@ -0,0 +1,122 @@
1
+ # Session Log — March 24, 2026
2
+
3
+ ## What We Built
4
+
5
+ An Across-powered crosschain payment layer for MPP (Machine Payments Protocol). When an agent gets a 402 Payment Required and doesn't have funds on the merchant's chain, Across bridges funds transparently before completing the standard Tempo charge.
6
+
7
+ ## Key Decisions
8
+
9
+ 1. **Across wraps INSIDE the existing Tempo flow** — not a separate payment method. The merchant sees a standard Tempo credential and never knows Across was involved. This was Hart's core requirement: "Tempo and Stripe don't change a thing."
10
+
11
+ 2. **`onChallenge` hook is the integration point** — mppx's `Mppx.create()` accepts an `onChallenge` callback that fires before credential creation. This is where the Across pre-funding logic lives. It checks Tempo balance, bridges if needed, then returns `undefined` to let the standard Tempo charge proceed.
12
+
13
+ 3. **`autoSwap: true` solves the token mismatch** — Tempo has two stablecoins: USDC.e (`0x20c...b9537d`) and pathUSD (`0x20c...0000`). Merchants price in pathUSD. mppx's `tempo()` has a built-in `autoSwap` parameter that swaps USDC.e → pathUSD via Tempo's DEX automatically.
14
+
15
+ ## What We Discovered
16
+
17
+ ### Tempo Account Model
18
+ - Tempo uses **smart contract wallets** (SCW), not plain EOAs
19
+ - **Wallet** (`0xbceb415b...`) — holds funds, is a smart contract
20
+ - **Key** (`0x8d2fd217...`) — an authorized signing key with $100 spending limit, expires 2026-04-23
21
+ - The key signs on behalf of the wallet via Tempo's custom tx type (`0x76`)
22
+ - `privateKeyToAccount()` from viem works — mppx handles the Tempo-specific routing
23
+
24
+ ### The Real 402 Challenge (from mpp.dev/api/ping/paid)
25
+ ```
26
+ WWW-Authenticate: Payment
27
+ id="...",
28
+ realm="mpp.sh",
29
+ method="tempo",
30
+ intent="charge",
31
+ request=base64({
32
+ "amount": "100000", // 0.10 USDC (6 decimals)
33
+ "currency": "0x20c0...0000", // pathUSD on Tempo
34
+ "methodDetails": {
35
+ "chainId": 42431, // Tempo chain ID (RPC)
36
+ "feePayer": true // Server pays gas!
37
+ },
38
+ "recipient": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
39
+ }),
40
+ description="Ping endpoint access",
41
+ expires="2026-03-24T18:39:14.613Z" // 5 min expiry
42
+ ```
43
+
44
+ ### Across Routes to Tempo
45
+ - Across uses chain ID **4217** for Tempo (not 42431 from the RPC)
46
+ - Routes from 15+ chains including Base, Arbitrum, Ethereum, Optimism, Polygon, Solana
47
+ - Can bridge to **pathUSD** (`0x20c...0000`) or **USDC.e** (`0x20c...b9537d`)
48
+ - Base USDC → Tempo pathUSD: ~2 second fill, ~$0.012 fees for a $0.10 payment
49
+ - Quote example: $0.10 output costs $0.112 input (fees are mostly destination gas)
50
+
51
+ ### Bridge Economics (Hart's concern validated)
52
+ For $0.10 micropayment: bridge fees ($0.012) are ~12% of the payment. This confirms Step 2 (merchant multi-chain acceptance + periodic sweep) is needed for micropayments. Step 1 works for payments where bridge cost is acceptable.
53
+
54
+ ## Current Wallet State
55
+
56
+ | Chain | Asset | Balance | Address |
57
+ |-------|-------|---------|---------|
58
+ | Tempo (SCW) | USDC.e | ~12.59 | `0xbceb415b64e057f2fc4018921e0480ca49e7c435` |
59
+ | Base | USDC | 6.37 | `0x8d2FD2173f5d40Ef4691cE8009D788950F843EBc` |
60
+ | Base | ETH | 0.0004 | `0x8d2FD2173f5d40Ef4691cE8009D788950F843EBc` |
61
+
62
+ Private key: `0xe9fad02b3b0c226929ef15ae8ec790c0ddc110ab9f652f0575eedc3f085de00e`
63
+ (Also imported in Rabby wallet)
64
+
65
+ ## Project Files
66
+
67
+ ```
68
+ agentmpp/
69
+ ├── PRD.md # Full product requirements doc
70
+ ├── across-mpp-step1-plan.md # Original plan (from before this session)
71
+ ├── SESSION-LOG.md # This file
72
+ ├── package.json # mppx, viem, tsx, typescript
73
+ ├── tsconfig.json
74
+ └── src/
75
+ ├── across.ts # Across API helpers (getQuote, waitForFill, chain config)
76
+ ├── balance.ts # Token balance checker (Tempo + origin chains)
77
+ ├── capture-402.ts # Raw 402 inspection tool (no wallet needed)
78
+ ├── client.ts # Basic mppx client with tempo + autoSwap
79
+ ├── tempo-with-across.ts # THE CORE: onChallenge hook with Across pre-funding
80
+ ├── test-across.ts # End-to-end Across test script
81
+ └── test-ping.ts # Basic Tempo-only test script
82
+ ```
83
+
84
+ ## What's Working
85
+
86
+ - [x] Tempo CLI installed and authenticated (v1.5.0)
87
+ - [x] mppx v0.4.9 + viem installed
88
+ - [x] 402 challenge captured and fully decoded
89
+ - [x] Basic Tempo client created with `autoSwap: true`
90
+ - [x] Across API confirmed working (quote for Base → Tempo)
91
+ - [x] Across wrapper code complete (`tempo-with-across.ts`)
92
+
93
+ ## What's NOT Tested Yet
94
+
95
+ - [ ] **Basic Tempo charge with `autoSwap`** — should swap USDC.e → pathUSD and pay. Run:
96
+ ```
97
+ AGENT_PRIVATE_KEY=0xe9fad02b3b0c226929ef15ae8ec790c0ddc110ab9f652f0575eedc3f085de00e npx tsx src/test-ping.ts
98
+ ```
99
+ - [ ] **Across end-to-end flow** — Base USDC → Across → Tempo pathUSD → charge. Run:
100
+ ```
101
+ AGENT_PRIVATE_KEY=0xe9fad02b3b0c226929ef15ae8ec790c0ddc110ab9f652f0575eedc3f085de00e npx tsx src/test-across.ts
102
+ ```
103
+ - [ ] Demo server (Phase 3)
104
+
105
+ ## Next Session: Pick Up Here
106
+
107
+ 1. Run `test-ping.ts` — validates basic Tempo charge with autoSwap
108
+ 2. Run `test-across.ts` — validates full Across crosschain flow
109
+ 3. If both pass, build the demo server (Phase 3)
110
+ 4. Then review with Hart
111
+
112
+ ## Reference Links
113
+
114
+ - [MPP Docs](https://mpp.dev)
115
+ - [MPP Full LLM Context](https://mpp.dev/llms-full.txt)
116
+ - [mppx Client Quickstart](https://mpp.dev/quickstart/client)
117
+ - [Custom Payment Methods](https://mpp.dev/payment-methods/custom)
118
+ - [Across Skills](https://skills.across.to/)
119
+ - [Across MCP Server](https://mcp.across.to/mcp)
120
+ - [Tempo SKILL.md](https://tempo.xyz/SKILL.md)
121
+ - [Tempo Docs](https://docs.tempo.xyz)
122
+ - [Hart/Bobby Call Notes](https://docs.google.com/document/d/1XerVgt6PDbJJiqmjs5cxpH1TrX9NKTzjNIup4QMEON0/edit)