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.
@@ -0,0 +1,357 @@
1
+ # MPP Step 2 Demo Plan
2
+
3
+ **Status:** Agreed plan
4
+ **Date locked:** March 31, 2026
5
+ **Audience:** Stripe-facing MPP demo only
6
+ **Goal:** Prove that agents can avoid per-request bridging by paying locally on Arbitrum, while the merchant still settles treasury to Tempo via hourly batching.
7
+
8
+ ---
9
+
10
+ ## Locked Decisions
11
+
12
+ - Keep the `MPP` Step 2 demo code **separate** from `x402`.
13
+ - Buyer starts with funds on **Arbitrum**.
14
+ - Merchant's preferred settlement chain is **Tempo**.
15
+ - Token can be **USDC** or **USDC.e**, whichever is simplest in the implementation.
16
+ - Receiver is **predeployed** before the demo.
17
+ - Verifier is **run by us**.
18
+ - Each paid request is **$0.02**.
19
+ - Demo shows **3 successful payments**.
20
+ - Merchant serves after **each** successful payment.
21
+ - After payment 3, the demo shows a live **manual trigger of the hourly sweep**.
22
+ - Step 1 comparison is explained **verbally**, not shown as a second live path.
23
+ - Buyer UX should still feel like an **MPP flow**, even though the buyer is Step 2-aware under the hood.
24
+ - Buyer retry should send **`reference + txHash`** back to the merchant.
25
+ - Do **not** retrofit the existing `src/dev/server.ts`; build a **new Step 2 server**.
26
+
27
+ ---
28
+
29
+ ## Demo Story
30
+
31
+ This is the exact story we are telling:
32
+
33
+ 1. Merchant wants final settlement on **Tempo**.
34
+ 2. Agent only has funds on **Arbitrum**.
35
+ 3. Merchant returns an MPP-facing 402 challenge.
36
+ 4. Buyer derives the merchant's deterministic Arbitrum receiver and proves it exists.
37
+ 5. Buyer pays the receiver locally on Arbitrum.
38
+ 6. Merchant verifies the Arbitrum payment and serves immediately.
39
+ 7. This happens three times.
40
+ 8. After the third payment, the operator triggers the scheduled hourly sweep.
41
+ 9. Accumulated funds move from the Arbitrum receiver to the merchant's Tempo settlement address.
42
+
43
+ **Headline:** the user got three successful paid responses without three separate bridge operations.
44
+
45
+ ---
46
+
47
+ ## What "MPP Step 2" Means
48
+
49
+ This is **not** the current Step 1 flow in `tempo-with-across.ts`.
50
+
51
+ Step 1 today:
52
+
53
+ - buyer gets Tempo challenge
54
+ - if buyer lacks Tempo funds, Across bridges to the buyer on Tempo
55
+ - buyer completes a normal Tempo payment
56
+
57
+ Step 2 for this demo:
58
+
59
+ - buyer gets an MPP-facing challenge
60
+ - buyer checks whether the merchant has a deployed receiver on **Arbitrum**
61
+ - if yes, buyer pays that receiver locally on Arbitrum
62
+ - merchant verifies the local payment and serves
63
+ - treasury moves to Tempo later on an hourly schedule
64
+
65
+ That is why this demo needs a separate server and a separate buyer path.
66
+
67
+ ---
68
+
69
+ ## Current Code We Keep As Reference
70
+
71
+ - Buyer Step 1 wrapper: `src/buyer/tempo-with-across.ts`
72
+ - Current local MPP seller: `src/dev/server.ts`
73
+ - Current demo entrypoints: `src/demo/local.ts`, `src/demo/external.ts`
74
+
75
+ We should **not** try to mutate those into Step 2. They remain the Step 1 baseline.
76
+
77
+ ---
78
+
79
+ ## New Modules To Add
80
+
81
+ Create a new `src/step2/` area for the demo-specific code.
82
+
83
+ ### 1. Merchant server
84
+
85
+ `src/step2/server.ts`
86
+
87
+ Responsibilities:
88
+
89
+ - issue the MPP-facing 402 challenge
90
+ - create a unique `reference` per challenge
91
+ - store challenge state
92
+ - accept retry requests containing `reference + txHash`
93
+ - call the verifier
94
+ - serve the paid response after successful verification
95
+ - expose a manual "run hourly sweep now" action for the demo
96
+
97
+ ### 2. Challenge store
98
+
99
+ `src/step2/challenges.ts`
100
+
101
+ Responsibilities:
102
+
103
+ - create challenge records
104
+ - store:
105
+ - `reference`
106
+ - `amount`
107
+ - `payer` if known
108
+ - `createdAt`
109
+ - `expiresAt`
110
+ - `consumedAt`
111
+ - `txHash`
112
+ - verification status
113
+ - mark one-time consumption after serving
114
+
115
+ For the demo, in-memory storage is acceptable.
116
+
117
+ ### 3. Verifier service
118
+
119
+ `src/step2/verifier.ts`
120
+
121
+ Responsibilities:
122
+
123
+ - read Arbitrum transaction receipts
124
+ - decode `PaymentReceived`
125
+ - confirm:
126
+ - event emitter is the expected receiver
127
+ - `reference` matches
128
+ - amount matches
129
+ - token matches
130
+ - confirmations threshold is met
131
+ - return a compact decision to the merchant server
132
+
133
+ Recommended demo default:
134
+
135
+ - `CONFIRMATIONS_REQUIRED=1`
136
+ - keep it configurable
137
+
138
+ ### 4. Buyer Step 2 path
139
+
140
+ `src/step2/buyer.ts`
141
+
142
+ Responsibilities:
143
+
144
+ - request the protected resource
145
+ - parse the MPP-facing challenge
146
+ - derive the deterministic Arbitrum receiver from merchant identity
147
+ - check `eth_getCode(receiver)` on Arbitrum
148
+ - log clearly that the buyer discovered the correct receiver
149
+ - pay the receiver locally
150
+ - retry the original request with `reference + txHash`
151
+
152
+ Important:
153
+
154
+ - this is a **custom Step 2-aware buyer**
155
+ - the audience should still experience it as an MPP flow
156
+
157
+ ### 5. Receiver address derivation helper
158
+
159
+ `src/step2/receiver.ts`
160
+
161
+ Responsibilities:
162
+
163
+ - compute deterministic receiver address
164
+ - share the same derivation logic between buyer, merchant server, and verifier
165
+
166
+ ### 6. Sweep trigger
167
+
168
+ `src/step2/sweep.ts`
169
+
170
+ Responsibilities:
171
+
172
+ - run the manual demo sweep
173
+ - log that this represents the scheduled hourly sweep policy
174
+ - show source balance, destination chain, and completion
175
+
176
+ ### 7. Demo runner
177
+
178
+ `src/step2/demo.ts`
179
+
180
+ Responsibilities:
181
+
182
+ - execute the three-payment script
183
+ - show:
184
+ - payment 1 verified
185
+ - payment 2 verified
186
+ - payment 3 verified
187
+ - receiver balance accumulated to `$0.06`
188
+ - hourly sweep triggered
189
+ - Tempo settlement observed
190
+
191
+ ---
192
+
193
+ ## HTTP Contract For The Demo
194
+
195
+ ### First request
196
+
197
+ `GET /api/premium`
198
+
199
+ Expected result:
200
+
201
+ - merchant returns `402`
202
+ - challenge includes enough identity for the buyer to derive the receiver
203
+
204
+ ### Retry after local payment
205
+
206
+ `GET /api/premium`
207
+
208
+ Headers:
209
+
210
+ - `X-Step2-Reference: <reference>`
211
+ - `X-Step2-Tx-Hash: <txHash>`
212
+
213
+ Merchant flow:
214
+
215
+ - load challenge by `reference`
216
+ - call verifier with `reference + txHash`
217
+ - if verified and not consumed, serve content
218
+
219
+ The buyer should make this obvious in logs:
220
+
221
+ - `Derived receiver`
222
+ - `Receiver deployed: yes`
223
+ - `Paid locally on Arbitrum`
224
+ - `Retrying with reference + txHash`
225
+
226
+ ---
227
+
228
+ ## Event Contract
229
+
230
+ The receiver needs one event:
231
+
232
+ ```solidity
233
+ event PaymentReceived(
234
+ address indexed payer,
235
+ address indexed token,
236
+ uint256 amount,
237
+ bytes32 indexed reference
238
+ );
239
+ ```
240
+
241
+ That is enough for the verifier to bind the Arbitrum payment to the original merchant challenge.
242
+
243
+ If we want easier demo logging, add a non-indexed string or bytes field later, but the default should stay compact.
244
+
245
+ ---
246
+
247
+ ## Demo UX Requirements
248
+
249
+ Minimal but explicit.
250
+
251
+ The demo must show:
252
+
253
+ 1. Buyer got a payment challenge.
254
+ 2. Buyer derived the correct Arbitrum receiver.
255
+ 3. Buyer found deployed code at that address.
256
+ 4. Buyer paid locally on Arbitrum.
257
+ 5. Merchant served immediately after verification.
258
+ 6. Three payments accumulated on the receiver.
259
+ 7. One live "hourly sweep" moved the balance to Tempo.
260
+
261
+ We do **not** need a polished dashboard.
262
+ We do need logs or a minimal operator view that makes the batching story visually obvious.
263
+
264
+ ---
265
+
266
+ ## Operator View
267
+
268
+ Minimal output is enough.
269
+
270
+ Show these fields:
271
+
272
+ - `reference`
273
+ - `payment count`
274
+ - `receiver address`
275
+ - `receiver balance`
276
+ - `last verified tx`
277
+ - `sweep status`
278
+ - `Tempo settlement tx`
279
+
280
+ A single terminal + one minimal status page is enough.
281
+
282
+ ---
283
+
284
+ ## Sweep Policy
285
+
286
+ Real policy:
287
+
288
+ - sweep **every hour**
289
+
290
+ Demo behavior:
291
+
292
+ - after payment 3, manually trigger the "hourly sweep now" action
293
+
294
+ What we say out loud:
295
+
296
+ - "In production, this runs on the hourly policy."
297
+ - "For the demo, we're forcing the scheduled action to happen now."
298
+
299
+ ---
300
+
301
+ ## Success Criteria
302
+
303
+ The demo succeeds if all of the following are true:
304
+
305
+ 1. Buyer makes **3** paid requests from Arbitrum.
306
+ 2. Merchant serves after each one.
307
+ 3. Buyer never bridges three separate payments to Tempo.
308
+ 4. Receiver balance visibly accumulates to roughly **$0.06** before sweep.
309
+ 5. One sweep moves the accumulated balance to Tempo.
310
+ 6. The audience can plainly see that Step 2 replaced per-request bridging with hourly batching.
311
+
312
+ ---
313
+
314
+ ## Non-Goals
315
+
316
+ - shared code with x402
317
+ - retrofitting the current Step 1 demo surface
318
+ - undeployed counterfactual receive
319
+ - automatic scheduler infrastructure
320
+ - polished production dashboard
321
+ - live Step 1 comparison path in the same demo
322
+
323
+ ---
324
+
325
+ ## Build Order
326
+
327
+ ### Phase 1
328
+
329
+ - receiver address derivation helper
330
+ - challenge store
331
+ - merchant Step 2 server shell
332
+
333
+ ### Phase 2
334
+
335
+ - verifier service
336
+ - buyer Step 2 path
337
+ - retry contract with `reference + txHash`
338
+
339
+ ### Phase 3
340
+
341
+ - manual sweep action
342
+ - minimal operator view / logs
343
+ - scripted three-payment demo runner
344
+
345
+ ---
346
+
347
+ ## Open Implementation Details
348
+
349
+ These do **not** block the architecture, but they need to be decided during build:
350
+
351
+ - exact receiver contract ABI
352
+ - exact `reference` type (`bytes32` vs string encoded to bytes32)
353
+ - whether Tempo settlement target is plain `USDC` or `USDC.e`
354
+ - exact verifier response schema
355
+ - whether the status view is terminal-only or terminal + tiny web page
356
+
357
+ None of those change the agreed demo story.