@402flow/sdk 0.1.0-alpha.21 → 0.1.0-alpha.23
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/README.md +85 -3
- package/dist/contracts.d.ts +241 -117
- package/dist/contracts.js +27 -1
- package/dist/contracts.js.map +1 -1
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -132,6 +132,46 @@ If the merchant does not require payment for that exact request, the SDK returns
|
|
|
132
132
|
|
|
133
133
|
`result.response` is always the merchant HTTP response. SDK-owned payment metadata such as `paidRequestId`, `paymentAttemptId`, `receiptId`, and `receipt` stays on the SDK result instead of being injected into the merchant JSON body.
|
|
134
134
|
|
|
135
|
+
### Optional Attribution
|
|
136
|
+
|
|
137
|
+
Most SDK users do not need to send attribution at all.
|
|
138
|
+
|
|
139
|
+
The optional `attribution` field is for callers that already know where this paid endpoint came from and want that provenance to survive into control-plane audit, reporting, and later policy analysis.
|
|
140
|
+
|
|
141
|
+
Common cases:
|
|
142
|
+
|
|
143
|
+
1. your app found the endpoint through your own registry or catalog
|
|
144
|
+
2. your app imported the endpoint from a saved workspace config
|
|
145
|
+
3. your agent is calling a merchant directly and you want to mark that path as `direct`
|
|
146
|
+
4. your host selected the endpoint from a discovery surface such as Bazaar, Dexter, pay.sh, x402scan, or another catalog
|
|
147
|
+
|
|
148
|
+
This field does not make payment execution work. It improves lifecycle explainability.
|
|
149
|
+
|
|
150
|
+
If you do not already know the endpoint provenance, omit it.
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
const result = await client.fetchPaid(
|
|
154
|
+
'https://merchant.example.com/reports/daily',
|
|
155
|
+
{
|
|
156
|
+
method: 'POST',
|
|
157
|
+
headers: {
|
|
158
|
+
'content-type': 'application/json',
|
|
159
|
+
},
|
|
160
|
+
body: createJsonRequestBody({
|
|
161
|
+
date: '2026-03-25',
|
|
162
|
+
}),
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
description: 'sync daily paid report',
|
|
166
|
+
attribution: {
|
|
167
|
+
discoverySource: 'direct',
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
For the first attribution slice, `discoverySource` is the main field callers should set when they have a clear answer. The control plane derives an early endpoint-level `resourceIdentity` from the request method and URL, so callers do not need to compute that themselves.
|
|
174
|
+
|
|
135
175
|
### Interpreting Merchant Responses
|
|
136
176
|
|
|
137
177
|
The SDK gives you a stable place for payment metadata, but it does not invent a universal fulfilled-response schema for merchant content.
|
|
@@ -228,6 +268,13 @@ const prepared = await client.preparePaidRequest(
|
|
|
228
268
|
|
|
229
269
|
`externalMetadata` is optional caller context. It improves preparation when the caller already has structured endpoint knowledge, but it is not required for normal SDK use.
|
|
230
270
|
|
|
271
|
+
`attribution` is separate from `externalMetadata`.
|
|
272
|
+
|
|
273
|
+
1. `externalMetadata` helps the SDK understand request shape before execution
|
|
274
|
+
2. `attribution` helps the control plane explain where the paid endpoint came from after execution
|
|
275
|
+
|
|
276
|
+
Use `externalMetadata` for request hints. Use `attribution` for provenance. Either may be omitted.
|
|
277
|
+
|
|
231
278
|
### What `ready` Means
|
|
232
279
|
|
|
233
280
|
`ready` means this exact request can proceed through governed paid execution as-is; it does not mean the SDK has inferred the best task parameters for you.
|
|
@@ -256,6 +303,13 @@ const prepared = await client.preparePaidRequest(
|
|
|
256
303
|
prompt: 'foggy coastline',
|
|
257
304
|
}),
|
|
258
305
|
},
|
|
306
|
+
|
|
307
|
+
const result = await client.executePreparedRequest(prepared, {
|
|
308
|
+
description: 'generate paid image',
|
|
309
|
+
attribution: {
|
|
310
|
+
discoverySource: 'manual',
|
|
311
|
+
},
|
|
312
|
+
});
|
|
259
313
|
);
|
|
260
314
|
|
|
261
315
|
if (prepared.kind === 'ready') {
|
|
@@ -308,7 +362,10 @@ Receipt notes:
|
|
|
308
362
|
1. `receipt.status = 'confirmed'` means the control plane has chain-backed settlement attribution for the paid attempt
|
|
309
363
|
2. `receipt.status = 'provisional'` means the paid outcome was supportable by merchant-provided evidence, but final settlement attribution is still pending reconciliation
|
|
310
364
|
3. callers should treat provisional receipts as payment-attempt evidence, not as proof of final settlement
|
|
311
|
-
4.
|
|
365
|
+
4. `idempotencyKey` is optional for normal SDK use, which keeps low-value one-off integrations simple
|
|
366
|
+
5. if you safely retry the same logical paid request with the same `idempotencyKey`, the SDK returns the same durable paid outcome instead of creating a second paid attempt
|
|
367
|
+
6. if you omit `idempotencyKey`, the request still works, but you should not assume replay-safe duplicate suppression across retries
|
|
368
|
+
7. use `idempotencyKey` for retrying callers, automation loops, and higher-load integrations where duplicate suppression matters
|
|
312
369
|
|
|
313
370
|
## Receipt Lookup
|
|
314
371
|
|
|
@@ -370,10 +427,10 @@ export X402FLOW_AGENT="reporting-worker"
|
|
|
370
427
|
export X402FLOW_BOOTSTRAP_KEY="..."
|
|
371
428
|
|
|
372
429
|
npm run example:openai-tools-quickstart -- \
|
|
373
|
-
"Prepare and execute a paid POST request to
|
|
430
|
+
"Prepare and execute a paid POST request to http://127.0.0.1:4123/demo-merchant/research-brief/solana-devnet with JSON body {\"topic\":\"sdk integration rollout\",\"audience\":\"platform engineers\",\"format\":\"bullets\"}"
|
|
374
431
|
```
|
|
375
432
|
|
|
376
|
-
Use this when you want the shortest real host integration path.
|
|
433
|
+
Use this when you want the shortest real host integration path. For now, this quickstart defaults to the self-hosted first-party demo merchant in `agent-pay` so SDK adoption starts from the canonical proving ground. Switch the merchant URL to the public AWS demo-merchant host once that deployment is live.
|
|
377
434
|
|
|
378
435
|
## Optional `AgentHarness`
|
|
379
436
|
|
|
@@ -392,6 +449,31 @@ For harness usage, presets, transcripts, and scenario packs, see:
|
|
|
392
449
|
1. [docs/evaluation-harness.md](docs/evaluation-harness.md)
|
|
393
450
|
2. [docs/harness-scenarios.md](docs/harness-scenarios.md)
|
|
394
451
|
|
|
452
|
+
For the canonical cross-repo core proving sweep (first-party + mock), run:
|
|
453
|
+
|
|
454
|
+
```bash
|
|
455
|
+
pnpm scenario:core
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
`pnpm scenario:core` runs first-party + mock in a single pass and keeps one combined artifact set under `tmp/`.
|
|
459
|
+
|
|
460
|
+
Additional scenario commands:
|
|
461
|
+
|
|
462
|
+
1. `pnpm scenario:core`: core proving sweep (first-party + mock)
|
|
463
|
+
2. `pnpm scenario:first-party`: first-party self-hosted demo-merchant scenarios only
|
|
464
|
+
3. `pnpm scenario:third-party`: third-party merchant compatibility scenarios only
|
|
465
|
+
4. `pnpm scenario:mock`: fixture-only mock outcomes, no live merchant required
|
|
466
|
+
|
|
467
|
+
`pnpm scenario:all` now literally runs all scenarios (first-party + third-party + mock).
|
|
468
|
+
|
|
469
|
+
As the public AWS demo-merchant host comes online, keep these command boundaries and flip first-party scenario fixtures with one env variable:
|
|
470
|
+
|
|
471
|
+
```bash
|
|
472
|
+
export X402FLOW_FIRST_PARTY_MERCHANT_BASE_URL="https://demo-merchant.402flow.ai"
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
When unset, first-party fixtures default to the self-hosted demo merchant at `http://127.0.0.1:4123`.
|
|
476
|
+
|
|
395
477
|
## Publish
|
|
396
478
|
|
|
397
479
|
```bash
|