thebuyside-x402-agent 0.4.2 → 0.5.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.
Files changed (43) hide show
  1. package/README.md +20 -15
  2. package/dist/chains/solana-usdc.d.ts +13 -0
  3. package/dist/chains/solana-usdc.d.ts.map +1 -1
  4. package/dist/chains/solana-usdc.js +87 -19
  5. package/dist/chains/solana-usdc.js.map +1 -1
  6. package/dist/mpp/auth-header.d.ts +47 -0
  7. package/dist/mpp/auth-header.d.ts.map +1 -0
  8. package/dist/mpp/auth-header.js +135 -0
  9. package/dist/mpp/auth-header.js.map +1 -0
  10. package/dist/mpp/client.d.ts +64 -0
  11. package/dist/mpp/client.d.ts.map +1 -0
  12. package/dist/mpp/client.js +208 -0
  13. package/dist/mpp/client.js.map +1 -0
  14. package/dist/mpp/jcs.d.ts +25 -0
  15. package/dist/mpp/jcs.d.ts.map +1 -0
  16. package/dist/mpp/jcs.js +74 -0
  17. package/dist/mpp/jcs.js.map +1 -0
  18. package/dist/mpp/types.d.ts +96 -0
  19. package/dist/mpp/types.d.ts.map +1 -0
  20. package/dist/mpp/types.js +20 -0
  21. package/dist/mpp/types.js.map +1 -0
  22. package/dist/registry/seed.candidates.json +17 -0
  23. package/dist/registry/types.d.ts +8 -0
  24. package/dist/registry/types.d.ts.map +1 -1
  25. package/dist/server.js +1 -1
  26. package/dist/server.js.map +1 -1
  27. package/dist/tools/discover.d.ts +4 -2
  28. package/dist/tools/discover.d.ts.map +1 -1
  29. package/dist/tools/discover.js +14 -10
  30. package/dist/tools/discover.js.map +1 -1
  31. package/dist/tools/fetch.d.ts +12 -8
  32. package/dist/tools/fetch.d.ts.map +1 -1
  33. package/dist/tools/fetch.js +124 -35
  34. package/dist/tools/fetch.js.map +1 -1
  35. package/dist/tools/wallet_status.d.ts +3 -2
  36. package/dist/tools/wallet_status.d.ts.map +1 -1
  37. package/dist/tools/wallet_status.js +4 -3
  38. package/dist/tools/wallet_status.js.map +1 -1
  39. package/dist/x402/client.d.ts +7 -0
  40. package/dist/x402/client.d.ts.map +1 -1
  41. package/dist/x402/client.js +4 -2
  42. package/dist/x402/client.js.map +1 -1
  43. package/package.json +5 -2
package/README.md CHANGED
@@ -1,28 +1,33 @@
1
1
  # thebuyside-x402-agent
2
2
 
3
- The MCP gateway that lets any AI agent discover and pay x402-priced APIs on Base or Solana — without the user wiring payments themselves.
3
+ The MCP gateway that lets any AI agent discover and pay metered APIs on Base or Solana — without the user wiring payments themselves.
4
4
 
5
- `thebuyside-x402-agent` is the canonical buyer-side reference implementation for [x402](https://x402.org), the HTTP 402 payment standard stewarded by the Linux Foundation. Drop it into Claude Code, Claude Desktop, Cursor, or any MCP client, and your agent gains three tools:
5
+ `thebuyside-x402-agent` is the canonical buyer-side reference implementation for two open agent-payment protocols:
6
6
 
7
- - **`x402.discover`**search the curated registry plus three federated indexes (CDP Bazaar, agentic.market, x402watch) for x402-priced APIs
8
- - **`x402.fetch`**call one (the gateway pays the 402 challenge automatically, on whichever chain you have a key for)
9
- - **`x402.wallet_status`** — show the gateway's wallet(s), today's spend, and caps
7
+ - **[x402](https://x402.org)** — the HTTP 402 payment standard stewarded by the Linux Foundation. EVM (Base) and SVM (Solana) via the `exact` scheme.
8
+ - **MPP**[Machine Payments Protocol](https://paymentauth.org/draft-solana-charge-00.html), the new RFC-7235-style protocol behind [pay.sh](https://pay.sh) (Solana Foundation × Google Cloud, launched May 2026). Solana mainnet USDC.
9
+
10
+ Drop it into Claude Code, Claude Desktop, Cursor, or any MCP client, and your agent gains three tools:
11
+
12
+ - **`pay.discover`** — search the curated registry plus three federated indexes (CDP Bazaar, agentic.market, x402watch) for paid APIs
13
+ - **`pay.fetch`** — call one (the gateway pays the 402 challenge automatically, on whichever chain you have a key for, speaking whichever protocol the seller uses)
14
+ - **`pay.wallet_status`** — show the gateway's wallet(s), today's spend, and caps
10
15
 
11
16
  The agent never sees the 402, never sees a wallet, never holds a private key.
12
17
 
13
18
  ## Status
14
19
 
15
- **v0.4.1 published to npm 2026-05-10.** Validated end-to-end on both supported chains:
20
+ **v0.5.0 MPP support landed 2026-05-10.** Previously validated end-to-end on both supported chains via x402:
16
21
 
17
22
  > Base mainnet · `$0.005 USDC` · tx [`0xd0917b35…`](https://basescan.org/tx/0xd0917b35d8b778cf8d0249cc1b107a48ff7125b9fcaf7b4b257d823f73cc6aac)
18
23
  >
19
24
  > Solana mainnet · `$0.005 USDC` · tx [`4DYWUMEx…`](https://solscan.io/tx/4DYWUMExSrMNxYLjUuH9G8feN4fmYXm4ToCx7gGaAEjJRf2QNrE8LsvoFSGhXwQJrchhgrnGpUFwjxrci9PRLF71)
20
25
 
21
- - 122 unit tests + MCP smoke test, all green
22
- - x402 v1 + v2 dual wire support (handles both transports)
26
+ - 154 unit tests + MCP smoke test, all green
27
+ - **Dual-protocol**: speaks x402 v1 + v2 *and* MPP (`solana`/`charge` intent). `pay.fetch` peeks at the 402 and dispatches transparently — agents never know which protocol the seller uses.
23
28
  - Multi-chain: configure either Base (EVM/EIP-3009) or Solana (SVM/SPL-TransferChecked) — or both. Sellers offering multiple chains are routed to whichever you have a signer for. On Solana, the seller's facilitator covers SOL gas — buyer wallet only needs USDC.
24
- - Federated discovery: `x402.discover` queries the curated `seed.json` + CDP Bazaar + agentic.market + x402watch in parallel and dedupes by canonical endpoint URL
25
- - Spend caps, host allowlist, receipts log, self-transfer guard
29
+ - Federated discovery: `pay.discover` queries the curated `seed.json` + CDP Bazaar + agentic.market + x402watch in parallel and dedupes by canonical endpoint URL
30
+ - Spend caps, host allowlist, receipts log, self-transfer guard — protocol-agnostic
26
31
  - Confirm-before-pay via MCP elicitation, with graceful fallback for clients lacking task-creation support (Claude Code)
27
32
  - Apache 2.0, DCO not CLA
28
33
 
@@ -60,7 +65,7 @@ Use a fresh wallet, not your main one. (You can also pass these via your MCP cli
60
65
  claude mcp add x402-pay -- npx -y thebuyside-x402-agent
61
66
  ```
62
67
 
63
- Open a session, type `/mcp` to verify, then ask: *"Use x402.wallet_status to show my wallet."*
68
+ Open a session, type `/mcp` to verify, then ask: *"Use pay.wallet_status to show my wallet."*
64
69
 
65
70
  **Claude Desktop:**
66
71
 
@@ -72,13 +77,13 @@ See [docs/install-claude-desktop.md](docs/install-claude-desktop.md).
72
77
 
73
78
  Once connected, ask the model:
74
79
 
75
- > *"Use x402.discover to find APIs about news."*
80
+ > *"Use pay.discover to find APIs about news."*
76
81
 
77
- > *"Use x402.fetch to get https://news-ep.com/api/v1/stories?market=houston&limit=5"*
82
+ > *"Use pay.fetch to get https://news-ep.com/api/v1/stories?market=houston&limit=5"*
78
83
 
79
84
  The first returns the registry plus federated matches from CDP Bazaar, agentic.market, and x402watch (each result tagged with its `source`). The second pays `$0.005 USDC` and returns Houston news. news-ep advertises both Base and Solana — the gateway picks whichever chain you have a key for.
80
85
 
81
- After a successful call, ask `x402.wallet_status` and you'll see today's spend reflected (and which chains have signers configured).
86
+ After a successful call, ask `pay.wallet_status` and you'll see today's spend reflected (and which chains have signers configured).
82
87
 
83
88
  ## Configuration
84
89
 
@@ -104,7 +109,7 @@ Spend controls have safe defaults. Override via env if needed.
104
109
  | `X402_CONFIRM_STRICT` | *(off)* | `1` refuses payment when the client lacks elicitation OR advertises elicitation but lacks tasks/create (e.g. Claude Code as of 2026-05). Default: log a one-time warning and proceed |
105
110
  | `X402_RECEIPTS_PATH` | `.local/receipts.jsonl` | Where the receipts log is written |
106
111
 
107
- **Federated discovery** (`x402.discover` queries these in parallel and merges with the local `seed.json`):
112
+ **Federated discovery** (`pay.discover` queries these in parallel and merges with the local `seed.json`):
108
113
 
109
114
  | Var | Default | What it does |
110
115
  | --- | --- | --- |
@@ -28,6 +28,7 @@
28
28
  * and an x402 round trip typically fits well inside that.
29
29
  */
30
30
  import { VersionedTransaction } from '@solana/web3.js';
31
+ import type { ChargeRequest } from '../mpp/types.js';
31
32
  import type { PaymentRequirements } from '../x402/types.js';
32
33
  import type { SolanaChainAdapter } from './adapter.js';
33
34
  export type SolanaUsdcAdapterOptions = {
@@ -46,6 +47,18 @@ export declare class SolanaUsdcAdapter implements SolanaChainAdapter {
46
47
  buildPayment(reqs: PaymentRequirements, payerPubkey: string): Promise<{
47
48
  tx: VersionedTransaction;
48
49
  }>;
50
+ /**
51
+ * MPP-flavored payment build. Mirrors `buildPayment` but reads the inputs
52
+ * from an MPP `ChargeRequest` (paymentauth.org/draft-solana-charge-00) and
53
+ * uses the seller-supplied `recentBlockhash` instead of fetching one.
54
+ *
55
+ * Scope: USDC mainnet, pull mode (server is feePayer), standard SPL Token
56
+ * program. Push mode (`feePayer: false`) is not supported here — the buyer
57
+ * would need its own SOL balance and gas-pricing logic.
58
+ */
59
+ buildPaymentMpp(charge: ChargeRequest, payerPubkey: string): Promise<{
60
+ tx: VersionedTransaction;
61
+ }>;
49
62
  private fetchBlockhash;
50
63
  }
51
64
  //# sourceMappingURL=solana-usdc.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"solana-usdc.d.ts","sourceRoot":"","sources":["../../src/chains/solana-usdc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAGH,OAAO,EAML,oBAAoB,EACrB,MAAM,iBAAiB,CAAC;AAMzB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAavD,MAAM,MAAM,wBAAwB,GAAG;IACrC,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,gBAAgB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1C,CAAC;AAEF,qBAAa,iBAAkB,YAAW,kBAAkB;IAC1D,QAAQ,CAAC,EAAE,YAAY;IACvB,QAAQ,CAAC,IAAI,EAAG,KAAK,CAAU;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAwB;gBAE9C,IAAI,GAAE,wBAA6B;IAK/C,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAO3B,YAAY,CAChB,IAAI,EAAE,mBAAmB,EACzB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;QAAE,EAAE,EAAE,oBAAoB,CAAA;KAAE,CAAC;YA4E1B,cAAc;CAM7B"}
1
+ {"version":3,"file":"solana-usdc.d.ts","sourceRoot":"","sources":["../../src/chains/solana-usdc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAGH,OAAO,EAML,oBAAoB,EACrB,MAAM,iBAAiB,CAAC;AAMzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAavD,MAAM,MAAM,wBAAwB,GAAG;IACrC,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,gBAAgB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1C,CAAC;AAEF,qBAAa,iBAAkB,YAAW,kBAAkB;IAC1D,QAAQ,CAAC,EAAE,YAAY;IACvB,QAAQ,CAAC,IAAI,EAAG,KAAK,CAAU;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAwB;gBAE9C,IAAI,GAAE,wBAA6B;IAK/C,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAO3B,YAAY,CAChB,IAAI,EAAE,mBAAmB,EACzB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;QAAE,EAAE,EAAE,oBAAoB,CAAA;KAAE,CAAC;IA0DxC;;;;;;;;OAQG;IACG,eAAe,CACnB,MAAM,EAAE,aAAa,EACrB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;QAAE,EAAE,EAAE,oBAAoB,CAAA;KAAE,CAAC;YA0D1B,cAAc;CAM7B"}
@@ -74,32 +74,77 @@ export class SolanaUsdcAdapter {
74
74
  }
75
75
  const sourceAta = getAssociatedTokenAddressSync(mint, payer);
76
76
  const destAta = getAssociatedTokenAddressSync(mint, seller);
77
- // Spec: feePayer MUST NOT appear in any instruction's accounts.
77
+ // x402 SVM scheme: feePayer MUST NOT appear in any instruction's accounts.
78
+ // MPP relaxes this rule — see `buildPaymentMpp` below.
78
79
  if (feePayer.equals(sourceAta) || feePayer.equals(destAta) || feePayer.equals(seller) || feePayer.equals(mint)) {
79
80
  throw new Error('feePayer collides with an instruction account (source ATA, dest ATA, ' +
80
81
  'seller, or mint) — refusing to build tx. This violates the SVM scheme ' +
81
82
  'safety rule.');
82
83
  }
83
84
  const memoText = readMemo(reqs.extra) ?? randomHexNonce(16);
84
- const amount = BigInt(reqs.maxAmountRequired);
85
- const instructions = [
86
- ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNIT_LIMIT }),
87
- ComputeBudgetProgram.setComputeUnitPrice({ microLamports: COMPUTE_UNIT_PRICE }),
88
- createTransferCheckedInstruction(sourceAta, mint, destAta, payer, amount, USDC_DECIMALS, [], TOKEN_PROGRAM_ID),
89
- new TransactionInstruction({
90
- programId: MEMO_PROGRAM_ID,
91
- keys: [],
92
- data: Buffer.from(memoText, 'utf8'),
93
- }),
94
- ];
95
85
  const recentBlockhash = await this.fetchBlockhash();
96
- const messageV0 = new TransactionMessage({
97
- payerKey: feePayer,
98
- recentBlockhash,
99
- instructions,
100
- }).compileToV0Message();
101
- const tx = new VersionedTransaction(messageV0);
102
- return { tx };
86
+ return {
87
+ tx: buildTransferTx({
88
+ payer,
89
+ seller,
90
+ feePayer,
91
+ mint,
92
+ amount: BigInt(reqs.maxAmountRequired),
93
+ memo: memoText,
94
+ recentBlockhash,
95
+ }),
96
+ };
97
+ }
98
+ /**
99
+ * MPP-flavored payment build. Mirrors `buildPayment` but reads the inputs
100
+ * from an MPP `ChargeRequest` (paymentauth.org/draft-solana-charge-00) and
101
+ * uses the seller-supplied `recentBlockhash` instead of fetching one.
102
+ *
103
+ * Scope: USDC mainnet, pull mode (server is feePayer), standard SPL Token
104
+ * program. Push mode (`feePayer: false`) is not supported here — the buyer
105
+ * would need its own SOL balance and gas-pricing logic.
106
+ */
107
+ async buildPaymentMpp(charge, payerPubkey) {
108
+ if (charge.currency !== USDC_MAINNET_MINT) {
109
+ throw new Error(`solana-usdc adapter only handles the USDC mint (${USDC_MAINNET_MINT}); ` +
110
+ `MPP challenge asked for currency=${charge.currency}.`);
111
+ }
112
+ if (charge.methodDetails.tokenProgram !== TOKEN_PROGRAM_ID.toBase58()) {
113
+ throw new Error(`MPP challenge requires non-standard token program ${charge.methodDetails.tokenProgram}; ` +
114
+ `only the standard SPL Token program is supported in v0.5.0.`);
115
+ }
116
+ if (charge.methodDetails.decimals !== USDC_DECIMALS) {
117
+ throw new Error(`MPP challenge declares decimals=${charge.methodDetails.decimals}; ` +
118
+ `USDC requires decimals=${USDC_DECIMALS}.`);
119
+ }
120
+ if (!charge.methodDetails.feePayer) {
121
+ throw new Error('MPP push mode (`methodDetails.feePayer: false`) is not supported in ' +
122
+ 'v0.5.0 — the buyer cannot be the fee payer in this gateway.');
123
+ }
124
+ if (!charge.methodDetails.feePayerKey) {
125
+ throw new Error('MPP pull-mode challenge missing `methodDetails.feePayerKey` — required ' +
126
+ 'when `feePayer: true` so the buyer knows whose pubkey to record as ' +
127
+ 'the transaction fee payer.');
128
+ }
129
+ const payer = new PublicKey(payerPubkey);
130
+ const seller = new PublicKey(charge.recipient);
131
+ const feePayer = new PublicKey(charge.methodDetails.feePayerKey);
132
+ const mint = new PublicKey(charge.currency);
133
+ if (feePayer.equals(payer)) {
134
+ throw new Error('seller-declared feePayer equals the buyer pubkey — refusing to sign. ' +
135
+ 'Buyer must not appear as feePayer in pull mode.');
136
+ }
137
+ return {
138
+ tx: buildTransferTx({
139
+ payer,
140
+ seller,
141
+ feePayer,
142
+ mint,
143
+ amount: BigInt(charge.amount),
144
+ memo: null,
145
+ recentBlockhash: charge.methodDetails.recentBlockhash,
146
+ }),
147
+ };
103
148
  }
104
149
  async fetchBlockhash() {
105
150
  if (this.blockhashFetcher)
@@ -109,6 +154,29 @@ export class SolanaUsdcAdapter {
109
154
  return blockhash;
110
155
  }
111
156
  }
157
+ /** Build the 4-instruction USDC transferChecked tx shared by x402 and MPP. */
158
+ function buildTransferTx(args) {
159
+ const sourceAta = getAssociatedTokenAddressSync(args.mint, args.payer);
160
+ const destAta = getAssociatedTokenAddressSync(args.mint, args.seller);
161
+ const instructions = [
162
+ ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNIT_LIMIT }),
163
+ ComputeBudgetProgram.setComputeUnitPrice({ microLamports: COMPUTE_UNIT_PRICE }),
164
+ createTransferCheckedInstruction(sourceAta, args.mint, destAta, args.payer, args.amount, USDC_DECIMALS, [], TOKEN_PROGRAM_ID),
165
+ ];
166
+ if (args.memo !== null) {
167
+ instructions.push(new TransactionInstruction({
168
+ programId: MEMO_PROGRAM_ID,
169
+ keys: [],
170
+ data: Buffer.from(args.memo, 'utf8'),
171
+ }));
172
+ }
173
+ const messageV0 = new TransactionMessage({
174
+ payerKey: args.feePayer,
175
+ recentBlockhash: args.recentBlockhash,
176
+ instructions,
177
+ }).compileToV0Message();
178
+ return new VersionedTransaction(messageV0);
179
+ }
112
180
  function readFeePayer(extra) {
113
181
  if (extra && typeof extra === 'object' && 'feePayer' in extra) {
114
182
  const f = extra.feePayer;
@@ -1 +1 @@
1
- {"version":3,"file":"solana-usdc.js","sourceRoot":"","sources":["../../src/chains/solana-usdc.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"solana-usdc.js","sourceRoot":"","sources":["../../src/chains/solana-usdc.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * RFC 7235 HTTP Authentication header parser/builder, scoped to the
3
+ * `Payment` auth-scheme used by MPP (paymentauth.org/draft-solana-charge-00).
4
+ *
5
+ * Servers emit:
6
+ * WWW-Authenticate: Payment id="...", realm="...", method="solana",
7
+ * intent="charge", request="<b64url-JCS>", expires="<ISO-8601>",
8
+ * description="<optional human label>"
9
+ *
10
+ * Buyers reply with:
11
+ * Authorization: Payment <b64url-JCS credential>
12
+ *
13
+ * The `Payment` scheme does not use auth-params on the request side — the
14
+ * value after the scheme name is a single base64url token (the credential).
15
+ *
16
+ * Multi-challenge headers (RFC 7235 §4.1 allows several comma-separated
17
+ * challenges) are not handled here — we accept the first `Payment` challenge
18
+ * and throw if a non-Payment scheme appears before it. In practice MPP
19
+ * sellers emit a single-challenge header.
20
+ */
21
+ export type ParsedPaymentChallenge = {
22
+ scheme: 'Payment';
23
+ id: string;
24
+ realm: string;
25
+ /** Always `"solana"` in this spec, but parsed verbatim. */
26
+ method: string;
27
+ /** Always `"charge"` in this spec, but parsed verbatim. */
28
+ intent: string;
29
+ /** base64url(JCS(ChargeRequest)) — still encoded; decode separately. */
30
+ request: string;
31
+ /** ISO-8601 datetime string. Caller compares against current time. */
32
+ expires: string;
33
+ /** Optional human-readable label some sellers include. */
34
+ description?: string;
35
+ /** Any auth-params we don't recognize, lowercased. Surfaced for forward-compat. */
36
+ extras: Record<string, string>;
37
+ };
38
+ export declare function parsePaymentChallenge(header: string): ParsedPaymentChallenge;
39
+ /** Build the value of the `Authorization` header for an MPP credential. */
40
+ export declare function buildAuthorizationHeader(credentialBase64Url: string): string;
41
+ /**
42
+ * Test whether a `WWW-Authenticate` header value advertises an MPP challenge.
43
+ * Used by the unified fetch handler to decide between x402 and MPP routing.
44
+ * Cheap shape check only — full parsing happens in `parsePaymentChallenge`.
45
+ */
46
+ export declare function isMppChallengeHeader(header: string | null | undefined): boolean;
47
+ //# sourceMappingURL=auth-header.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-header.d.ts","sourceRoot":"","sources":["../../src/mpp/auth-header.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,EAAE,SAAS,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mFAAmF;IACnF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC,CAAC;AAMF,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,sBAAsB,CAmG5E;AAED,2EAA2E;AAC3E,wBAAgB,wBAAwB,CAAC,mBAAmB,EAAE,MAAM,GAAG,MAAM,CAE5E;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAG/E"}
@@ -0,0 +1,135 @@
1
+ /**
2
+ * RFC 7235 HTTP Authentication header parser/builder, scoped to the
3
+ * `Payment` auth-scheme used by MPP (paymentauth.org/draft-solana-charge-00).
4
+ *
5
+ * Servers emit:
6
+ * WWW-Authenticate: Payment id="...", realm="...", method="solana",
7
+ * intent="charge", request="<b64url-JCS>", expires="<ISO-8601>",
8
+ * description="<optional human label>"
9
+ *
10
+ * Buyers reply with:
11
+ * Authorization: Payment <b64url-JCS credential>
12
+ *
13
+ * The `Payment` scheme does not use auth-params on the request side — the
14
+ * value after the scheme name is a single base64url token (the credential).
15
+ *
16
+ * Multi-challenge headers (RFC 7235 §4.1 allows several comma-separated
17
+ * challenges) are not handled here — we accept the first `Payment` challenge
18
+ * and throw if a non-Payment scheme appears before it. In practice MPP
19
+ * sellers emit a single-challenge header.
20
+ */
21
+ const TOKEN_CHAR_RE = /[A-Za-z0-9!#$%&'*+\-.^_`|~]/;
22
+ /** Token + `/` (for slash-bearing base64url values used as bare tokens by some sellers). */
23
+ const TOKEN_VALUE_CHAR_RE = /[A-Za-z0-9!#$%&'*+\-.^_`|~/]/;
24
+ export function parsePaymentChallenge(header) {
25
+ let i = 0;
26
+ const len = header.length;
27
+ const skipWs = () => {
28
+ while (i < len && (header[i] === ' ' || header[i] === '\t'))
29
+ i++;
30
+ };
31
+ skipWs();
32
+ const schemeStart = i;
33
+ while (i < len && header[i] !== ' ' && header[i] !== '\t')
34
+ i++;
35
+ const scheme = header.slice(schemeStart, i);
36
+ if (scheme.toLowerCase() !== 'payment') {
37
+ throw new Error(`unexpected WWW-Authenticate scheme: "${scheme}" (expected "Payment")`);
38
+ }
39
+ skipWs();
40
+ const params = new Map();
41
+ while (i < len) {
42
+ const nameStart = i;
43
+ while (i < len && TOKEN_CHAR_RE.test(header[i]))
44
+ i++;
45
+ if (i === nameStart) {
46
+ throw new Error(`expected auth-param name at index ${i} of WWW-Authenticate header`);
47
+ }
48
+ const name = header.slice(nameStart, i).toLowerCase();
49
+ skipWs();
50
+ if (header[i] !== '=') {
51
+ throw new Error(`expected "=" after auth-param "${name}" at index ${i}`);
52
+ }
53
+ i++;
54
+ skipWs();
55
+ let value;
56
+ if (header[i] === '"') {
57
+ i++;
58
+ let v = '';
59
+ while (i < len && header[i] !== '"') {
60
+ if (header[i] === '\\') {
61
+ i++;
62
+ if (i >= len)
63
+ throw new Error('unterminated escape inside quoted-string');
64
+ v += header[i];
65
+ i++;
66
+ }
67
+ else {
68
+ v += header[i];
69
+ i++;
70
+ }
71
+ }
72
+ if (header[i] !== '"') {
73
+ throw new Error(`unterminated quoted-string for auth-param "${name}"`);
74
+ }
75
+ i++;
76
+ value = v;
77
+ }
78
+ else {
79
+ const valStart = i;
80
+ while (i < len && TOKEN_VALUE_CHAR_RE.test(header[i]))
81
+ i++;
82
+ if (i === valStart) {
83
+ throw new Error(`expected value for auth-param "${name}" at index ${i}`);
84
+ }
85
+ value = header.slice(valStart, i);
86
+ }
87
+ params.set(name, value);
88
+ skipWs();
89
+ if (i < len) {
90
+ if (header[i] !== ',') {
91
+ throw new Error(`expected "," between auth-params at index ${i}, found "${header[i]}"`);
92
+ }
93
+ i++;
94
+ skipWs();
95
+ }
96
+ }
97
+ const required = ['id', 'realm', 'method', 'intent', 'request', 'expires'];
98
+ for (const k of required) {
99
+ if (!params.has(k)) {
100
+ throw new Error(`MPP challenge missing required auth-param "${k}"`);
101
+ }
102
+ }
103
+ const known = new Set([...required, 'description']);
104
+ const extras = {};
105
+ for (const [k, v] of params) {
106
+ if (!known.has(k))
107
+ extras[k] = v;
108
+ }
109
+ return {
110
+ scheme: 'Payment',
111
+ id: params.get('id'),
112
+ realm: params.get('realm'),
113
+ method: params.get('method'),
114
+ intent: params.get('intent'),
115
+ request: params.get('request'),
116
+ expires: params.get('expires'),
117
+ description: params.get('description'),
118
+ extras,
119
+ };
120
+ }
121
+ /** Build the value of the `Authorization` header for an MPP credential. */
122
+ export function buildAuthorizationHeader(credentialBase64Url) {
123
+ return `Payment ${credentialBase64Url}`;
124
+ }
125
+ /**
126
+ * Test whether a `WWW-Authenticate` header value advertises an MPP challenge.
127
+ * Used by the unified fetch handler to decide between x402 and MPP routing.
128
+ * Cheap shape check only — full parsing happens in `parsePaymentChallenge`.
129
+ */
130
+ export function isMppChallengeHeader(header) {
131
+ if (!header)
132
+ return false;
133
+ return /^\s*payment\b/i.test(header);
134
+ }
135
+ //# sourceMappingURL=auth-header.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-header.js","sourceRoot":"","sources":["../../src/mpp/auth-header.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * MPP (Machine Payments Protocol) client — drives the full payment loop
3
+ * for the `solana`/`charge` intent per paymentauth.org/draft-solana-charge-00:
4
+ *
5
+ * 1. Make the initial request.
6
+ * 2. If 402 with `WWW-Authenticate: Payment ...`, parse the challenge and
7
+ * decode the base64url JCS `request` payload.
8
+ * 3. Validate scope (USDC mint, standard SPL Token, pull mode, network).
9
+ * 4. Have `SolanaUsdcAdapter.buildPaymentMpp` build the partially-signed tx.
10
+ * 5. Sign with the buyer's Solana key.
11
+ * 6. Wrap in a JCS-canonical credential JSON, base64url-encode, send as
12
+ * `Authorization: Payment <b64url>`.
13
+ * 7. On 200, decode the `Payment-Receipt` header.
14
+ *
15
+ * No spend-policy enforcement here — that lives in `src/policy/` and is wired
16
+ * by the calling fetch tool via the `beforePay` / `onPaid` hooks. Mirrors the
17
+ * shape of `src/x402/client.ts` so the two protocols feel symmetric.
18
+ */
19
+ import type { SolanaUsdcAdapter } from '../chains/solana-usdc.js';
20
+ import type { SolanaSigner } from '../signer/signer.js';
21
+ import type { ChargeRequest } from './types.js';
22
+ export type MppPayAndFetchOptions = {
23
+ url: string;
24
+ method?: 'GET' | 'POST';
25
+ body?: unknown;
26
+ signer: SolanaSigner;
27
+ adapter: SolanaUsdcAdapter;
28
+ /** Test-only: override the global `fetch`. */
29
+ fetchFn?: typeof fetch;
30
+ /**
31
+ * Optimization: the caller already fetched the initial response and
32
+ * confirmed it's a 402 with an MPP challenge. Skips the duplicate GET.
33
+ */
34
+ prefetchedResponse?: Response;
35
+ /**
36
+ * If true, accept non-mainnet networks (`devnet`, `testnet`, `localnet`).
37
+ * Off by default — production callers should only pay real money on
38
+ * mainnet. Used by integration tests and the pay.sh debugger probe.
39
+ */
40
+ allowNonMainnet?: boolean;
41
+ /** Pre-pay hook. Throw to abort before any signature is produced. */
42
+ beforePay?: (charge: ChargeRequest) => Promise<void> | void;
43
+ /** Post-pay hook. Called only on 200; receives the settle tx signature. */
44
+ onPaid?: (info: {
45
+ charge: ChargeRequest;
46
+ tx: string | undefined;
47
+ }) => Promise<void> | void;
48
+ };
49
+ export type MppPayAndFetchResult = {
50
+ status: number;
51
+ body: unknown;
52
+ paid: boolean;
53
+ /** The decoded MPP charge we paid against, if any. */
54
+ paidCharge?: ChargeRequest;
55
+ /** Solana tx signature from `Payment-Receipt`, if the server emitted one. */
56
+ settledTx?: string;
57
+ /** Populated when the retry returns non-200. */
58
+ failure?: {
59
+ status: number;
60
+ body: unknown;
61
+ };
62
+ };
63
+ export declare function payAndFetchMpp(opts: MppPayAndFetchOptions): Promise<MppPayAndFetchResult>;
64
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/mpp/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAOxD,OAAO,KAAK,EACV,aAAa,EAGd,MAAM,YAAY,CAAC;AAMpB,MAAM,MAAM,qBAAqB,GAAG;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,8CAA8C;IAC9C,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IACvB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,QAAQ,CAAC;IAC9B;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,qEAAqE;IACrE,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC5D,2EAA2E;IAC3E,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,aAAa,CAAC;QAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC5F,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,sDAAsD;IACtD,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,OAAO,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC;CAC7C,CAAC;AAEF,wBAAsB,cAAc,CAClC,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,oBAAoB,CAAC,CAgL/B"}