@xona-labs/xpay 0.2.26 → 0.2.27

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/CHANGELOG.md CHANGED
@@ -6,6 +6,47 @@ versioning follows [Semantic Versioning](https://semver.org/).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.2.27] – 2026-08-18
10
+
11
+ ### Added
12
+ - **Tempo wallet.** New `tempo` network (eip155:4217, Stripe/Paradigm
13
+ payments L1, `rpc.tempo.xyz`), settling USDC.e (TIP-20, 6 decimals,
14
+ `0x20C0...8b50`). Registered unconditionally from any profile like
15
+ Robinhood and Stable, so existing wallets get a Tempo address without
16
+ re-running `xpay init`; `xpay balance` includes it. Tempo has no native
17
+ gas token - fees are paid in stablecoins, and MPP challenges are
18
+ fee-sponsored by the server anyway.
19
+ - **MPP tempo/charge settlement.** `use()`/`useByUrl()` settle `tempo`
20
+ method challenges by signing a pull-mode Tempo transaction (TIP-20
21
+ `transferWithMemo` with the MPP attribution memo binding the challenge
22
+ id, expiring nonce, fee-payer sponsorship when offered) via viem's tempo
23
+ extensions - the server broadcasts, so no gas is needed client-side.
24
+ Verified end to end against mpp.dev's paid ping endpoint on Moderato:
25
+ a faucet-funded wallet paid through `useByUrl()` and got the settlement
26
+ tx hash back from the `Payment-Receipt` header. Adds `viem` as a
27
+ dependency (Tempo's transaction type needs it; ethers stays for
28
+ everything else).
29
+ - **MPP (Machine Payments Protocol) charge support.** `use()` and `useByUrl()`
30
+ now settle against MPP servers (the Stripe + Tempo open 402 standard,
31
+ mpp.dev) in addition to x402. When a 402 carries `WWW-Authenticate: Payment`
32
+ challenges, xpay picks a fundable option, signs an EIP-3009
33
+ `transferWithAuthorization` bound to the challenge id (gasless, server
34
+ broadcasts), retries with `Authorization: Payment <credential>`, and reads
35
+ the settlement tx hash from the `Payment-Receipt` header. Hybrid servers
36
+ fall back to the x402 flow for any method xpay cannot settle as MPP yet.
37
+ Settleable today: `evm`/`charge` paying a known EIP-3009 stablecoin (USDC
38
+ on Base, Ethereum, Arbitrum, Optimism, Base Sepolia). `tempo` and `solana`
39
+ methods land with their chain support. Wire format cross-validated against
40
+ the official `mppx` client: credentials deserialize cleanly and pass the
41
+ server-side HMAC challenge-id check.
42
+
43
+ ## [0.2.26] – 2026-08-12
44
+
45
+ ### Added
46
+ - **MCP tool annotations.** Every MCP tool now carries behavior hints
47
+ (`readOnlyHint`, `openWorldHint`, `destructiveHint`) for the ChatGPT Apps
48
+ submission and other MCP clients that surface them.
49
+
9
50
  ## [0.2.25] – 2026-08-07
10
51
 
11
52
  ### Changed
@@ -21,7 +21,7 @@ export async function runBalance(opts) {
21
21
  const configured = profile.config.networks;
22
22
  const networks = opts.network
23
23
  ? [opts.network]
24
- : [...configured, ...["robinhood", "stable"].filter((n) => !configured.includes(n))];
24
+ : [...configured, ...["robinhood", "stable", "tempo"].filter((n) => !configured.includes(n))];
25
25
  console.log("");
26
26
  console.log(chalk.bold(`Profile "${name}"`));
27
27
  console.log("");
@@ -1 +1 @@
1
- {"version":3,"file":"balance.js","sourceRoot":"","sources":["../../src/cli/balance.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"balance.js","sourceRoot":"","sources":["../../src/cli/balance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Parse MPP (Machine Payments Protocol) challenges from a 402 response.
3
+ *
4
+ * MPP is the Stripe + Tempo open standard for HTTP 402 (spec: mpp.dev /
5
+ * paymentauth.org). Unlike x402's custom headers, the challenge rides the
6
+ * standard auth header:
7
+ *
8
+ * WWW-Authenticate: Payment id="...", realm="...", method="evm",
9
+ * intent="charge", request="<base64url JSON>", expires="..."
10
+ *
11
+ * A server may offer several payment methods; fetch() merges the multiple
12
+ * WWW-Authenticate headers into one comma-separated value, so the parser
13
+ * splits on `Payment ` scheme boundaries outside quoted strings (RFC 9110
14
+ * 11.6.1), then reads auth-params with quoted-string escape handling.
15
+ *
16
+ * The raw base64url `request` and `opaque` values are kept verbatim: the
17
+ * server HMAC-binds the challenge `id` to their exact encoding, so the
18
+ * credential must echo them unmodified.
19
+ */
20
+ import type { PaymentRequirement } from "../types.js";
21
+ export interface MppChallenge {
22
+ id: string;
23
+ realm: string;
24
+ /** Payment method, e.g. "evm", "tempo", "solana", "stripe". */
25
+ method: string;
26
+ /** Intent, e.g. "charge", "session", "subscription". */
27
+ intent: string;
28
+ /** Decoded method-specific request payload. */
29
+ request: Record<string, unknown>;
30
+ /** Raw base64url `request` exactly as received - echo verbatim in the credential. */
31
+ requestRaw: string;
32
+ description?: string;
33
+ digest?: string;
34
+ expires?: string;
35
+ /** Raw base64url server correlation data - clients MUST NOT modify. */
36
+ opaque?: string;
37
+ }
38
+ /** One settleable payment option: the challenge plus its derived requirement. */
39
+ export interface MppOption {
40
+ challenge: MppChallenge;
41
+ requirement: PaymentRequirement;
42
+ }
43
+ /**
44
+ * Extract every MPP `Payment` challenge from a 402 response's headers.
45
+ * Returns [] when the header is absent or carries no Payment scheme, so
46
+ * callers can cheaply detect "is this an MPP server at all".
47
+ */
48
+ export declare function parseMppChallenges(headers: Headers): MppChallenge[];
49
+ /**
50
+ * Filter challenges down to the options this wallet stack can actually
51
+ * settle today, mapped into {@link PaymentRequirement} so balance-aware
52
+ * picking and the guardrail reuse the x402 machinery unchanged.
53
+ *
54
+ * Currently settleable:
55
+ * - `evm`/`charge` paying a known EIP-3009 token (signed
56
+ * transferWithAuthorization, server broadcasts)
57
+ * - `tempo`/`charge` (signed pull-mode Tempo transaction, server
58
+ * broadcasts; fee-sponsored when the challenge offers feePayer)
59
+ * `solana` uses signed-transaction payloads and lands with its chain
60
+ * support, not here.
61
+ */
62
+ export declare function settleableMppOptions(challenges: MppChallenge[]): MppOption[];
63
+ //# sourceMappingURL=challenge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"challenge.d.ts","sourceRoot":"","sources":["../../src/mpp/challenge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC;IACf,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,qFAAqF;IACrF,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,iFAAiF;AACjF,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,YAAY,CAAC;IACxB,WAAW,EAAE,kBAAkB,CAAC;CACjC;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,YAAY,EAAE,CAUnE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,YAAY,EAAE,GAAG,SAAS,EAAE,CAQ5E"}
@@ -0,0 +1,257 @@
1
+ /**
2
+ * Parse MPP (Machine Payments Protocol) challenges from a 402 response.
3
+ *
4
+ * MPP is the Stripe + Tempo open standard for HTTP 402 (spec: mpp.dev /
5
+ * paymentauth.org). Unlike x402's custom headers, the challenge rides the
6
+ * standard auth header:
7
+ *
8
+ * WWW-Authenticate: Payment id="...", realm="...", method="evm",
9
+ * intent="charge", request="<base64url JSON>", expires="..."
10
+ *
11
+ * A server may offer several payment methods; fetch() merges the multiple
12
+ * WWW-Authenticate headers into one comma-separated value, so the parser
13
+ * splits on `Payment ` scheme boundaries outside quoted strings (RFC 9110
14
+ * 11.6.1), then reads auth-params with quoted-string escape handling.
15
+ *
16
+ * The raw base64url `request` and `opaque` values are kept verbatim: the
17
+ * server HMAC-binds the challenge `id` to their exact encoding, so the
18
+ * credential must echo them unmodified.
19
+ */
20
+ /**
21
+ * Extract every MPP `Payment` challenge from a 402 response's headers.
22
+ * Returns [] when the header is absent or carries no Payment scheme, so
23
+ * callers can cheaply detect "is this an MPP server at all".
24
+ */
25
+ export function parseMppChallenges(headers) {
26
+ const header = headers.get("www-authenticate");
27
+ if (!header)
28
+ return [];
29
+ const out = [];
30
+ for (const chunk of splitPaymentSchemes(header)) {
31
+ const ch = parseOne(chunk);
32
+ if (ch)
33
+ out.push(ch);
34
+ }
35
+ return out;
36
+ }
37
+ /**
38
+ * Filter challenges down to the options this wallet stack can actually
39
+ * settle today, mapped into {@link PaymentRequirement} so balance-aware
40
+ * picking and the guardrail reuse the x402 machinery unchanged.
41
+ *
42
+ * Currently settleable:
43
+ * - `evm`/`charge` paying a known EIP-3009 token (signed
44
+ * transferWithAuthorization, server broadcasts)
45
+ * - `tempo`/`charge` (signed pull-mode Tempo transaction, server
46
+ * broadcasts; fee-sponsored when the challenge offers feePayer)
47
+ * `solana` uses signed-transaction payloads and lands with its chain
48
+ * support, not here.
49
+ */
50
+ export function settleableMppOptions(challenges) {
51
+ const out = [];
52
+ for (const ch of challenges) {
53
+ if (ch.intent !== "charge" || (ch.method !== "evm" && ch.method !== "tempo"))
54
+ continue;
55
+ const req = ch.method === "tempo" ? tempoChargeToRequirement(ch) : evmChargeToRequirement(ch);
56
+ if (req)
57
+ out.push({ challenge: ch, requirement: req });
58
+ }
59
+ return out;
60
+ }
61
+ /**
62
+ * Map an MPP tempo/charge request into our PaymentRequirement shape.
63
+ * Tempo requests look like EVM ones (amount/currency/recipient +
64
+ * methodDetails.chainId) but settle via signed Tempo transactions, and the
65
+ * chainId may be omitted (mainnet, 4217).
66
+ */
67
+ function tempoChargeToRequirement(ch) {
68
+ const r = ch.request;
69
+ const details = isObj(r.methodDetails) ? r.methodDetails : {};
70
+ const chainId = typeof details.chainId === "number" ? details.chainId : 4217;
71
+ if (typeof r.currency !== "string" || typeof r.recipient !== "string")
72
+ return null;
73
+ // xpay signs pull-mode (sign, server broadcasts) - skip push-only challenges.
74
+ const modes = details.supportedModes;
75
+ if (Array.isArray(modes) && !modes.includes("pull"))
76
+ return null;
77
+ return {
78
+ scheme: "exact",
79
+ network: `eip155:${chainId}`,
80
+ payTo: r.recipient,
81
+ asset: r.currency,
82
+ amount: typeof r.amount === "string" ? r.amount : undefined,
83
+ maxTimeoutSeconds: secondsUntil(ch.expires),
84
+ };
85
+ }
86
+ /** Map an MPP evm/charge request into our PaymentRequirement shape. */
87
+ function evmChargeToRequirement(ch) {
88
+ const r = ch.request;
89
+ const details = isObj(r.methodDetails) ? r.methodDetails : {};
90
+ const chainId = details.chainId;
91
+ if (typeof chainId !== "number" || !Number.isInteger(chainId) || chainId <= 0)
92
+ return null;
93
+ if (typeof r.currency !== "string" || typeof r.recipient !== "string")
94
+ return null;
95
+ // credentialTypes, when present, must include the one payload we sign.
96
+ const types = details.credentialTypes;
97
+ if (Array.isArray(types) && !types.includes("authorization"))
98
+ return null;
99
+ // Split payouts need multiple transfers - a single EIP-3009 signature can't.
100
+ if (Array.isArray(details.splits) && details.splits.length > 0)
101
+ return null;
102
+ return {
103
+ scheme: "exact",
104
+ network: `eip155:${chainId}`,
105
+ payTo: r.recipient,
106
+ asset: r.currency,
107
+ amount: typeof r.amount === "string" ? r.amount : undefined,
108
+ maxTimeoutSeconds: secondsUntil(ch.expires),
109
+ };
110
+ }
111
+ function secondsUntil(expires) {
112
+ if (!expires)
113
+ return undefined;
114
+ const ms = Date.parse(expires) - Date.now();
115
+ return Number.isFinite(ms) && ms > 0 ? Math.floor(ms / 1000) : undefined;
116
+ }
117
+ /**
118
+ * Split a (possibly merged) WWW-Authenticate value into `Payment ...` chunks,
119
+ * ignoring scheme-like tokens inside quoted strings. Non-Payment schemes
120
+ * (Bearer, Basic, ...) are dropped.
121
+ */
122
+ function splitPaymentSchemes(header) {
123
+ const starts = [];
124
+ let inQuotes = false;
125
+ let escaped = false;
126
+ for (let i = 0; i < header.length; i++) {
127
+ const c = header[i];
128
+ if (inQuotes) {
129
+ if (escaped)
130
+ escaped = false;
131
+ else if (c === "\\")
132
+ escaped = true;
133
+ else if (c === '"')
134
+ inQuotes = false;
135
+ continue;
136
+ }
137
+ if (c === '"') {
138
+ inQuotes = true;
139
+ continue;
140
+ }
141
+ if (!isPaymentSchemeAt(header, i))
142
+ continue;
143
+ // A scheme may only start at the beginning or after a comma (RFC 9110).
144
+ let b = i - 1;
145
+ while (b >= 0 && /\s/.test(header[b]))
146
+ b--;
147
+ if (b >= 0 && header[b] !== ",")
148
+ continue;
149
+ starts.push(i);
150
+ }
151
+ return starts.map((start, i) => {
152
+ const end = i + 1 < starts.length ? starts[i + 1] : header.length;
153
+ return header
154
+ .slice(start + "payment".length, end)
155
+ .replace(/,\s*$/, "")
156
+ .trim();
157
+ });
158
+ }
159
+ function isPaymentSchemeAt(header, i) {
160
+ if (header.slice(i, i + 7).toLowerCase() !== "payment")
161
+ return false;
162
+ const next = header[i + 7];
163
+ return Boolean(next && /\s/.test(next));
164
+ }
165
+ /** Parse one scheme chunk's auth-params into a challenge. null when malformed. */
166
+ function parseOne(chunk) {
167
+ let params;
168
+ try {
169
+ params = parseAuthParams(chunk);
170
+ }
171
+ catch {
172
+ return null;
173
+ }
174
+ const { id, realm, method, intent, request } = params;
175
+ if (!id || !realm || !method || !intent || !request)
176
+ return null;
177
+ let decoded;
178
+ try {
179
+ decoded = JSON.parse(Buffer.from(request, "base64url").toString("utf8"));
180
+ }
181
+ catch {
182
+ return null;
183
+ }
184
+ if (!isObj(decoded))
185
+ return null;
186
+ return {
187
+ id,
188
+ realm,
189
+ method,
190
+ intent,
191
+ request: decoded,
192
+ requestRaw: request,
193
+ description: params.description,
194
+ digest: params.digest,
195
+ expires: params.expires,
196
+ opaque: params.opaque,
197
+ };
198
+ }
199
+ /** Auth-param parser with escaped quoted-string support. */
200
+ function parseAuthParams(input) {
201
+ const result = {};
202
+ let i = 0;
203
+ while (i < input.length) {
204
+ while (i < input.length && /[\s,]/.test(input[i]))
205
+ i++;
206
+ if (i >= input.length)
207
+ break;
208
+ const keyStart = i;
209
+ while (i < input.length && /[A-Za-z0-9_-]/.test(input[i]))
210
+ i++;
211
+ const key = input.slice(keyStart, i);
212
+ if (!key)
213
+ throw new Error("malformed auth-param");
214
+ while (i < input.length && /\s/.test(input[i]))
215
+ i++;
216
+ if (input[i] !== "=")
217
+ break; // token without '=': likely another scheme
218
+ i++;
219
+ while (i < input.length && /\s/.test(input[i]))
220
+ i++;
221
+ let value;
222
+ if (input[i] === '"') {
223
+ [value, i] = readQuoted(input, i + 1);
224
+ }
225
+ else {
226
+ const start = i;
227
+ while (i < input.length && input[i] !== ",")
228
+ i++;
229
+ value = input.slice(start, i).trim();
230
+ }
231
+ result[key] = value;
232
+ }
233
+ return result;
234
+ }
235
+ function readQuoted(input, start) {
236
+ let out = "";
237
+ let i = start;
238
+ while (i < input.length) {
239
+ const c = input[i];
240
+ i++;
241
+ if (c === "\\") {
242
+ if (i >= input.length)
243
+ break;
244
+ out += input[i];
245
+ i++;
246
+ continue;
247
+ }
248
+ if (c === '"')
249
+ return [out, i];
250
+ out += c;
251
+ }
252
+ throw new Error("unterminated quoted-string");
253
+ }
254
+ function isObj(v) {
255
+ return Boolean(v) && typeof v === "object" && !Array.isArray(v);
256
+ }
257
+ //# sourceMappingURL=challenge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"challenge.js","sourceRoot":"","sources":["../../src/mpp/challenge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Build the MPP `Authorization: Payment <base64url JSON>` credential and read
3
+ * back the `Payment-Receipt` header.
4
+ *
5
+ * Credential wire shape (mirrors mppx's Credential.serialize):
6
+ *
7
+ * {
8
+ * "challenge": { id, realm, method, intent,
9
+ * request: "<raw base64url from the 402>",
10
+ * expires?, digest?, description?, opaque? },
11
+ * "payload": { ...method-specific proof... },
12
+ * "source": "did:pkh:eip155:8453:0x..." // payer identity, optional
13
+ * }
14
+ *
15
+ * The challenge fields (and especially the raw `request` / `opaque` strings)
16
+ * must round-trip byte-identical: the server recomputes the HMAC-bound `id`
17
+ * over them and rejects the credential on any drift.
18
+ */
19
+ import type { MppChallenge } from "./challenge.js";
20
+ export interface BuildCredentialArgs {
21
+ challenge: MppChallenge;
22
+ /** Method-specific proof, e.g. the signed EIP-3009 authorization. */
23
+ payload: Record<string, unknown>;
24
+ /** Payer identity (did:pkh form). */
25
+ source?: string;
26
+ }
27
+ /** Serialize a credential to the `Authorization` header value. */
28
+ export declare function buildMppAuthorizationHeader(args: BuildCredentialArgs): string;
29
+ /**
30
+ * Settlement receipt from the `Payment-Receipt` response header.
31
+ * `reference` is the method-specific settlement handle - for on-chain
32
+ * methods, the transaction hash.
33
+ */
34
+ export interface MppReceipt {
35
+ method: string;
36
+ reference: string;
37
+ /** Always "success" on the happy path - failures come back as 402 + Problem Details. */
38
+ status: string;
39
+ /** RFC 3339 settlement timestamp. */
40
+ timestamp?: string;
41
+ [key: string]: unknown;
42
+ }
43
+ /** Decode the Payment-Receipt header. undefined when absent or unparseable. */
44
+ export declare function extractMppReceipt(headers: Headers): MppReceipt | undefined;
45
+ //# sourceMappingURL=credential.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credential.d.ts","sourceRoot":"","sources":["../../src/mpp/credential.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,YAAY,CAAC;IACxB,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,kEAAkE;AAClE,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAmB7E;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,wFAAwF;IACxF,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,+EAA+E;AAC/E,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAgB1E"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Build the MPP `Authorization: Payment <base64url JSON>` credential and read
3
+ * back the `Payment-Receipt` header.
4
+ *
5
+ * Credential wire shape (mirrors mppx's Credential.serialize):
6
+ *
7
+ * {
8
+ * "challenge": { id, realm, method, intent,
9
+ * request: "<raw base64url from the 402>",
10
+ * expires?, digest?, description?, opaque? },
11
+ * "payload": { ...method-specific proof... },
12
+ * "source": "did:pkh:eip155:8453:0x..." // payer identity, optional
13
+ * }
14
+ *
15
+ * The challenge fields (and especially the raw `request` / `opaque` strings)
16
+ * must round-trip byte-identical: the server recomputes the HMAC-bound `id`
17
+ * over them and rejects the credential on any drift.
18
+ */
19
+ /** Serialize a credential to the `Authorization` header value. */
20
+ export function buildMppAuthorizationHeader(args) {
21
+ const c = args.challenge;
22
+ const wire = {
23
+ challenge: {
24
+ id: c.id,
25
+ realm: c.realm,
26
+ method: c.method,
27
+ intent: c.intent,
28
+ request: c.requestRaw,
29
+ ...(c.description !== undefined && { description: c.description }),
30
+ ...(c.digest !== undefined && { digest: c.digest }),
31
+ ...(c.expires !== undefined && { expires: c.expires }),
32
+ ...(c.opaque !== undefined && { opaque: c.opaque }),
33
+ },
34
+ payload: args.payload,
35
+ ...(args.source && { source: args.source }),
36
+ };
37
+ const encoded = Buffer.from(JSON.stringify(wire), "utf8").toString("base64url");
38
+ return `Payment ${encoded}`;
39
+ }
40
+ /** Decode the Payment-Receipt header. undefined when absent or unparseable. */
41
+ export function extractMppReceipt(headers) {
42
+ const raw = headers.get("payment-receipt");
43
+ if (!raw)
44
+ return undefined;
45
+ try {
46
+ const decoded = JSON.parse(Buffer.from(raw, "base64url").toString("utf8"));
47
+ if (decoded &&
48
+ typeof decoded === "object" &&
49
+ typeof decoded.reference === "string") {
50
+ return decoded;
51
+ }
52
+ }
53
+ catch {
54
+ /* tolerate junk headers */
55
+ }
56
+ return undefined;
57
+ }
58
+ //# sourceMappingURL=credential.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credential.js","sourceRoot":"","sources":["../../src/mpp/credential.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAYH,kEAAkE;AAClE,MAAM,UAAU,2BAA2B,CAAC,IAAyB;IACnE,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC;IACzB,MAAM,IAAI,GAAG;QACX,SAAS,EAAE;YACT,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,OAAO,EAAE,CAAC,CAAC,UAAU;YACrB,GAAG,CAAC,CAAC,CAAC,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;YAClE,GAAG,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;YACnD,GAAG,CAAC,CAAC,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;YACtD,GAAG,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;SACpD;QACD,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;KAC5C,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAChF,OAAO,WAAW,OAAO,EAAE,CAAC;AAC9B,CAAC;AAiBD,+EAA+E;AAC/E,MAAM,UAAU,iBAAiB,CAAC,OAAgB;IAChD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAC3C,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,OAAO,GAAY,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QACpF,IACE,OAAO;YACP,OAAO,OAAO,KAAK,QAAQ;YAC3B,OAAQ,OAAsB,CAAC,SAAS,KAAK,QAAQ,EACrD,CAAC;YACD,OAAO,OAAqB,CAAC;QAC/B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,2BAA2B;IAC7B,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * MPP evm/charge credential payload: a signed EIP-3009
3
+ * `TransferWithAuthorization` - the same gasless primitive our x402 v2 EVM
4
+ * path uses, with two MPP-specific twists (mirroring mppx's evm client):
5
+ *
6
+ * nonce = keccak256(utf8(challenge.id + challenge.realm))
7
+ * - binds the signature to this exact challenge, and makes
8
+ * replays collide on-chain (EIP-3009 nonces are single-use)
9
+ * validBefore = challenge.expires (epoch secs), falling back to now+300
10
+ *
11
+ * The EIP-712 domain name/version are NOT in the challenge - MPP assumes the
12
+ * client knows its tokens. We resolve them from a registry of known EIP-3009
13
+ * stablecoins on the chains xpay ships signers for.
14
+ */
15
+ import type { MppChallenge } from "./challenge.js";
16
+ export interface BuildMppEvmAuthorizationArgs {
17
+ /** Payer address (the EVM signer's wallet address). */
18
+ address: string;
19
+ /** EIP-712 typed-data signer - from `signer.signEvmTypedData`. */
20
+ signTypedData: (typedData: {
21
+ domain: Record<string, unknown>;
22
+ types: Record<string, Array<{
23
+ name: string;
24
+ type: string;
25
+ }>>;
26
+ message: Record<string, unknown>;
27
+ }) => Promise<string>;
28
+ challenge: MppChallenge;
29
+ }
30
+ export interface MppEvmAuthorization {
31
+ /** Credential `payload` - the signed authorization. */
32
+ payload: Record<string, unknown>;
33
+ /** Credential `source` - payer identity in did:pkh form. */
34
+ source: string;
35
+ }
36
+ export declare function buildMppEvmAuthorization(args: BuildMppEvmAuthorizationArgs): Promise<MppEvmAuthorization>;
37
+ //# sourceMappingURL=evm-charge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evm-charge.d.ts","sourceRoot":"","sources":["../../src/mpp/evm-charge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AA2BnD,MAAM,WAAW,4BAA4B;IAC3C,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,aAAa,EAAE,CAAC,SAAS,EAAE;QACzB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC,CAAC;QAC7D,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAClC,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACtB,SAAS,EAAE,YAAY,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,4BAA4B,GACjC,OAAO,CAAC,mBAAmB,CAAC,CAoD9B"}