@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 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. 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
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 https://nickeljoke.vercel.app/api/joke with JSON body {\"topic\":\"sdk integration\",\"tone\":\"dry\",\"audience\":\"platform engineers\"}"
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. Use the full evaluation harness only when you need scenarios, transcripts, or repeated eval runs.
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