agentcash 0.3.4 → 0.3.6

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/dist/cjs/run-server.cjs +93839 -93640
  2. package/dist/esm/{chunk-FJSHGCIM.js → chunk-DZC5MTYY.js} +2 -2
  3. package/dist/esm/{chunk-GCS3RSLB.js → chunk-EVE4PTLY.js} +6 -6
  4. package/dist/esm/chunk-EVE4PTLY.js.map +1 -0
  5. package/dist/esm/chunk-FM2E2QVT.js +716 -0
  6. package/dist/esm/chunk-FM2E2QVT.js.map +1 -0
  7. package/dist/esm/{chunk-MOO4ZEGR.js → chunk-PCCYUD6X.js} +3 -3
  8. package/dist/esm/{chunk-KD2ZZXT7.js → chunk-PJFATGPH.js} +43 -2
  9. package/dist/esm/chunk-PJFATGPH.js.map +1 -0
  10. package/dist/esm/chunk-QCFNW6VN.js +22 -0
  11. package/dist/esm/chunk-QCFNW6VN.js.map +1 -0
  12. package/dist/esm/chunk-VVTMCXSK.js +309 -0
  13. package/dist/esm/chunk-VVTMCXSK.js.map +1 -0
  14. package/dist/esm/{commands-DUIGMEXV.js → commands-DE2RIAL5.js} +60 -111
  15. package/dist/esm/commands-DE2RIAL5.js.map +1 -0
  16. package/dist/esm/{fund-Y2STNDHA.js → fund-IALSHTLH.js} +4 -5
  17. package/dist/esm/{fund-Y2STNDHA.js.map → fund-IALSHTLH.js.map} +1 -1
  18. package/dist/esm/index.js +19 -13
  19. package/dist/esm/index.js.map +1 -1
  20. package/dist/esm/{install-GFY4JNNJ.js → install-Q4KN5XCP.js} +6 -8
  21. package/dist/esm/{install-GFY4JNNJ.js.map → install-Q4KN5XCP.js.map} +1 -1
  22. package/dist/esm/lib.d.ts +68 -3
  23. package/dist/esm/lib.js +6 -2
  24. package/dist/esm/{server-7D6YY3KG.js → server-WCNK52XR.js} +153 -531
  25. package/dist/esm/server-WCNK52XR.js.map +1 -0
  26. package/dist/esm/shared/operations/index.d.ts +12 -53
  27. package/dist/esm/shared/operations/index.js +6 -7
  28. package/package.json +3 -3
  29. package/dist/esm/chunk-CZBCIWYU.js +0 -48
  30. package/dist/esm/chunk-CZBCIWYU.js.map +0 -1
  31. package/dist/esm/chunk-GCS3RSLB.js.map +0 -1
  32. package/dist/esm/chunk-GIYROB7O.js +0 -210
  33. package/dist/esm/chunk-GIYROB7O.js.map +0 -1
  34. package/dist/esm/chunk-KD2ZZXT7.js.map +0 -1
  35. package/dist/esm/chunk-NQNMVKGY.js +0 -382
  36. package/dist/esm/chunk-NQNMVKGY.js.map +0 -1
  37. package/dist/esm/chunk-XXKBL2AC.js +0 -31
  38. package/dist/esm/chunk-XXKBL2AC.js.map +0 -1
  39. package/dist/esm/commands-DUIGMEXV.js.map +0 -1
  40. package/dist/esm/lib-DIhoN8bW.d.ts +0 -115
  41. package/dist/esm/server-7D6YY3KG.js.map +0 -1
  42. /package/dist/esm/{chunk-FJSHGCIM.js.map → chunk-DZC5MTYY.js.map} +0 -0
  43. /package/dist/esm/{chunk-MOO4ZEGR.js.map → chunk-PCCYUD6X.js.map} +0 -0
@@ -0,0 +1,309 @@
1
+ import {
2
+ detectPaymentProtocols,
3
+ getTempoBalance,
4
+ mppErr,
5
+ mppOk,
6
+ safeCreateMppCredential,
7
+ safeCreatePaymentPayload,
8
+ safeGetMppChallenge,
9
+ safeGetMppReceipt,
10
+ safeGetPaymentRequired,
11
+ safeGetPaymentSettlement,
12
+ tokenStringToNumber,
13
+ x402Err,
14
+ x402Ok
15
+ } from "./chunk-FM2E2QVT.js";
16
+ import {
17
+ fetchErr,
18
+ fetchOk,
19
+ getBalance,
20
+ log,
21
+ resultFromPromise,
22
+ safeFetch
23
+ } from "./chunk-PJFATGPH.js";
24
+
25
+ // src/server/tools/lib/request.ts
26
+ import z from "zod";
27
+ var requestSchema = z.object({
28
+ url: z.url().describe("The endpoint URL"),
29
+ method: z.enum(["GET", "POST", "PUT", "DELETE", "PATCH"]).optional().describe("HTTP method. Defaults to GET for fetch operations."),
30
+ body: z.unknown().optional().describe("Request body for POST/PUT/PATCH methods"),
31
+ headers: z.record(z.string(), z.string()).optional().describe("Additional headers to include").default({})
32
+ });
33
+ var buildRequest = ({
34
+ input,
35
+ address,
36
+ sessionId,
37
+ provider
38
+ }) => {
39
+ return new Request(input.url, {
40
+ method: input.method ?? "GET",
41
+ body: input.body ? typeof input.body === "string" ? input.body : JSON.stringify(input.body) : void 0,
42
+ headers: {
43
+ ...input.body ? { "Content-Type": "application/json" } : {},
44
+ ...input.headers,
45
+ ...address ? { "X-Wallet-Address": address, "X-Client-ID": provider } : {},
46
+ ...sessionId ? { "X-Session-ID": sessionId } : {}
47
+ }
48
+ });
49
+ };
50
+
51
+ // src/shared/operations/fetch-with-payment.ts
52
+ import { formatUnits } from "viem";
53
+ function createFetchWithPayment(options) {
54
+ const { surface, clients, paymentMethod, beforePayment } = options;
55
+ return async (request) => {
56
+ const clonedRequest = request.clone();
57
+ const fallbackRequest = request.clone();
58
+ const probeResult = await safeFetch(surface, request);
59
+ if (probeResult.isErr()) {
60
+ return fetchErr(surface, probeResult.error);
61
+ }
62
+ if (probeResult.value.status !== 402) {
63
+ return probeResult.andThen(
64
+ (response2) => fetchOk({ response: response2, paymentInfo: null })
65
+ );
66
+ }
67
+ const response = probeResult.value;
68
+ if (paymentMethod !== "auto") {
69
+ if (paymentMethod === "mpp") {
70
+ return handleMppPayment(surface, response, clonedRequest, options);
71
+ }
72
+ return handleX402Payment(
73
+ surface,
74
+ response,
75
+ clonedRequest,
76
+ clients.x402,
77
+ beforePayment
78
+ );
79
+ }
80
+ const available = detectPaymentProtocols(response);
81
+ let preferred;
82
+ if (available.length === 1) {
83
+ preferred = available[0];
84
+ } else {
85
+ preferred = await pickByBalance(surface, response, options);
86
+ }
87
+ const fallback = available.length > 1 ? preferred === "mpp" ? "x402" : "mpp" : null;
88
+ const result = preferred === "mpp" ? await handleMppPayment(surface, response, clonedRequest, options) : await handleX402Payment(
89
+ surface,
90
+ response,
91
+ clonedRequest,
92
+ clients.x402,
93
+ beforePayment
94
+ );
95
+ if (result.isErr() && fallback) {
96
+ return fallback === "mpp" ? handleMppPayment(surface, response, fallbackRequest, options) : handleX402Payment(
97
+ surface,
98
+ response,
99
+ fallbackRequest,
100
+ clients.x402,
101
+ beforePayment
102
+ );
103
+ }
104
+ return result;
105
+ };
106
+ }
107
+ async function pickByBalance(surface, response, options) {
108
+ const { account, flags } = options;
109
+ const x402BalanceResult = await resultFromPromise(
110
+ "balance",
111
+ surface,
112
+ getBalance({
113
+ address: account.address,
114
+ flags,
115
+ surface
116
+ }).then((r) => r.isOk() ? r.value.balance : 0),
117
+ () => ({
118
+ cause: "x402_balance",
119
+ message: "Failed to get x402 balance"
120
+ })
121
+ );
122
+ if (x402BalanceResult.isErr()) {
123
+ log.debug("Balance comparison failed, defaulting to mpp");
124
+ return "mpp";
125
+ }
126
+ const x402Balance = x402BalanceResult.value;
127
+ let mppBalance = 0;
128
+ const challengeResult = safeGetMppChallenge(surface, response);
129
+ if (challengeResult.isOk()) {
130
+ const currency = challengeResult.value.request.currency;
131
+ const decimals = challengeResult.value.request.decimals ?? 6;
132
+ if (currency) {
133
+ const tempoResult = await resultFromPromise(
134
+ "tempo",
135
+ surface,
136
+ getTempoBalance({
137
+ address: account.address,
138
+ tokenAddress: currency
139
+ }),
140
+ () => ({
141
+ cause: "tempo_balance",
142
+ message: "Tempo balance check failed"
143
+ })
144
+ );
145
+ if (tempoResult.isOk()) {
146
+ mppBalance = Number(formatUnits(tempoResult.value.balance, decimals));
147
+ }
148
+ }
149
+ }
150
+ log.info(`Protocol selection \u2014 x402: $${x402Balance}, mpp: $${mppBalance}`);
151
+ return x402Balance >= mppBalance ? "x402" : "mpp";
152
+ }
153
+ async function handleX402Payment(surface, response, clonedRequest, client, beforePayment) {
154
+ const paymentRequiredResult = await safeGetPaymentRequired(
155
+ surface,
156
+ client,
157
+ response
158
+ );
159
+ if (paymentRequiredResult.isErr()) {
160
+ return paymentRequiredResult;
161
+ }
162
+ const paymentRequired = paymentRequiredResult.value;
163
+ if (beforePayment) {
164
+ const accept = paymentRequired.accepts[0];
165
+ if (accept) {
166
+ const amount = tokenStringToNumber(accept.amount);
167
+ const hookResult = await resultFromPromise(
168
+ "x402",
169
+ surface,
170
+ beforePayment({
171
+ protocol: "x402",
172
+ amount,
173
+ currency: "USDC",
174
+ network: accept.network
175
+ }),
176
+ (e) => ({
177
+ cause: "payment_already_attempted",
178
+ message: e instanceof Error ? e.message : "Before-payment hook failed"
179
+ })
180
+ );
181
+ if (hookResult.isErr()) {
182
+ return x402Err(surface, hookResult.error);
183
+ }
184
+ }
185
+ }
186
+ const paymentPayloadResult = await safeCreatePaymentPayload(
187
+ surface,
188
+ client,
189
+ paymentRequired
190
+ );
191
+ if (paymentPayloadResult.isErr()) {
192
+ return paymentPayloadResult;
193
+ }
194
+ const paymentPayload = paymentPayloadResult.value;
195
+ const paymentHeaders = client.encodePaymentSignatureHeader(paymentPayload);
196
+ if (clonedRequest.headers.has("PAYMENT-SIGNATURE") || clonedRequest.headers.has("X-PAYMENT")) {
197
+ return x402Err(surface, {
198
+ cause: "payment_already_attempted",
199
+ message: "Payment already attempted"
200
+ });
201
+ }
202
+ for (const [key, value] of Object.entries(paymentHeaders)) {
203
+ clonedRequest.headers.set(key, value);
204
+ }
205
+ clonedRequest.headers.set(
206
+ "Access-Control-Expose-Headers",
207
+ "PAYMENT-RESPONSE,X-PAYMENT-RESPONSE"
208
+ );
209
+ return await safeFetch(surface, clonedRequest).andThen((paidResponse) => {
210
+ const settlementResult = safeGetPaymentSettlement(
211
+ surface,
212
+ client,
213
+ paidResponse
214
+ );
215
+ return x402Ok({
216
+ response: paidResponse,
217
+ paymentInfo: {
218
+ protocol: "x402",
219
+ price: tokenStringToNumber(
220
+ paymentPayload.accepted.amount
221
+ ).toLocaleString("en-US", {
222
+ style: "currency",
223
+ currency: "USD"
224
+ }),
225
+ ...settlementResult.isOk() ? {
226
+ payment: {
227
+ success: settlementResult.value.success,
228
+ transactionHash: settlementResult.value.transaction
229
+ }
230
+ } : {}
231
+ }
232
+ });
233
+ });
234
+ }
235
+ async function handleMppPayment(surface, response, clonedRequest, options) {
236
+ const { clients, beforePayment } = options;
237
+ const mpayClient = clients.mpp;
238
+ if (clonedRequest.headers.has("Authorization")) {
239
+ return mppErr(surface, {
240
+ cause: "mpp_payment_already_attempted",
241
+ message: "MPP payment already attempted"
242
+ });
243
+ }
244
+ const challengeResult = safeGetMppChallenge(surface, response);
245
+ if (challengeResult.isErr()) {
246
+ return challengeResult;
247
+ }
248
+ const challenge = challengeResult.value;
249
+ const amount = challenge.request.amount;
250
+ const decimals = challenge.request.decimals ?? 6;
251
+ const currency = challenge.request.currency;
252
+ if (beforePayment && amount && currency) {
253
+ const numericAmount = Number(formatUnits(BigInt(amount), decimals));
254
+ const hookResult = await resultFromPromise(
255
+ "mpp",
256
+ surface,
257
+ beforePayment({
258
+ protocol: "mpp",
259
+ amount: numericAmount,
260
+ currency,
261
+ network: `tempo:${challenge.method}`
262
+ }),
263
+ (e) => ({
264
+ cause: "mpp_payment_already_attempted",
265
+ message: e instanceof Error ? e.message : "Before-payment hook failed"
266
+ })
267
+ );
268
+ if (hookResult.isErr()) {
269
+ return mppErr(surface, hookResult.error);
270
+ }
271
+ }
272
+ const credentialResult = await safeCreateMppCredential(
273
+ surface,
274
+ mpayClient,
275
+ response
276
+ );
277
+ if (credentialResult.isErr()) {
278
+ return credentialResult;
279
+ }
280
+ const credential = credentialResult.value;
281
+ clonedRequest.headers.set("Authorization", credential);
282
+ return await safeFetch(surface, clonedRequest).andThen((paidResponse) => {
283
+ const receiptResult = safeGetMppReceipt(surface, paidResponse);
284
+ const priceDisplay = amount ? Number(formatUnits(BigInt(amount), decimals)).toLocaleString("en-US", {
285
+ style: "currency",
286
+ currency: "USD"
287
+ }) : void 0;
288
+ return mppOk({
289
+ response: paidResponse,
290
+ paymentInfo: {
291
+ protocol: "mpp",
292
+ ...priceDisplay ? { price: priceDisplay } : {},
293
+ ...receiptResult.isOk() ? {
294
+ payment: {
295
+ success: true,
296
+ transactionHash: receiptResult.value.reference
297
+ }
298
+ } : {}
299
+ }
300
+ });
301
+ });
302
+ }
303
+
304
+ export {
305
+ requestSchema,
306
+ buildRequest,
307
+ createFetchWithPayment
308
+ };
309
+ //# sourceMappingURL=chunk-VVTMCXSK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/server/tools/lib/request.ts","../../src/shared/operations/fetch-with-payment.ts"],"sourcesContent":["import z from 'zod';\n\nimport type { Address } from 'viem';\n\nexport const requestSchema = z.object({\n url: z.url().describe('The endpoint URL'),\n method: z\n .enum(['GET', 'POST', 'PUT', 'DELETE', 'PATCH'])\n .optional()\n .describe('HTTP method. Defaults to GET for fetch operations.'),\n body: z\n .unknown()\n .optional()\n .describe('Request body for POST/PUT/PATCH methods'),\n headers: z\n .record(z.string(), z.string())\n .optional()\n .describe('Additional headers to include')\n .default({}),\n});\n\ninterface BuildRequestProps {\n input: z.infer<typeof requestSchema>;\n address?: Address;\n sessionId?: string;\n provider?: string;\n}\n\nexport const buildRequest = ({\n input,\n address,\n sessionId,\n provider,\n}: BuildRequestProps) => {\n return new Request(input.url, {\n method: input.method ?? 'GET',\n body: input.body\n ? typeof input.body === 'string'\n ? input.body\n : JSON.stringify(input.body)\n : undefined,\n headers: {\n ...(input.body ? { 'Content-Type': 'application/json' } : {}),\n ...input.headers,\n ...(address\n ? { 'X-Wallet-Address': address, 'X-Client-ID': provider }\n : {}),\n ...(sessionId ? { 'X-Session-ID': sessionId } : {}),\n },\n });\n};\n","import { formatUnits } from 'viem';\n\nimport type { x402HTTPClient } from '@x402/core/client';\nimport type { Mpay } from 'mpay/client';\nimport type { Address } from 'viem';\nimport type { GlobalFlags } from '@/types';\n\nimport { resultFromPromise } from '@agentcash/neverthrow';\n\nimport { fetchErr, fetchOk, safeFetch } from '@/shared/neverthrow/fetch';\nimport {\n safeCreatePaymentPayload,\n safeGetPaymentRequired,\n safeGetPaymentSettlement,\n x402Err,\n x402Ok,\n} from '@/shared/neverthrow/x402';\nimport {\n safeGetMppChallenge,\n safeCreateMppCredential,\n safeGetMppReceipt,\n mppErr,\n mppOk,\n} from '@/shared/neverthrow/mpp';\n\nimport { log } from '@/shared/log';\nimport { detectPaymentProtocols } from '@/shared/protocol';\nimport { tokenStringToNumber } from '@/shared/token';\nimport { getBalance } from '@/shared/balance';\nimport { getTempoBalance } from '@/shared/tempo-balance';\n\n/**\n * Hook called before a payment is executed.\n * Throw to abort. Return to proceed.\n * Matches existing checkBalance/checkTempoBalance throw-to-abort behavior.\n */\nexport type BeforePaymentHook = (ctx: {\n protocol: 'x402' | 'mpp';\n amount: number;\n currency: string;\n network: string;\n}) => Promise<void>;\n\nexport interface PaymentClients {\n x402: x402HTTPClient;\n mpp: ReturnType<typeof Mpay.create>;\n}\n\nexport interface PaymentInfo {\n protocol: 'x402' | 'mpp';\n price?: string;\n payment?: {\n success: boolean;\n transactionHash?: string;\n };\n}\n\nexport interface FetchWithPaymentResult {\n response: Response;\n paymentInfo: PaymentInfo | null;\n}\n\nexport interface FetchWithPaymentOptions {\n surface: string;\n clients: PaymentClients;\n paymentMethod: 'x402' | 'mpp' | 'auto';\n account: { address: Address };\n flags: GlobalFlags;\n beforePayment?: BeforePaymentHook;\n}\n\n/**\n * Create a fetch function with automatic dual-protocol payment handling.\n *\n * 1. Makes initial request\n * 2. If 402 response, detects protocol(s)\n * 3. Calls beforePayment hook (for balance checks)\n * 4. Creates payment credential/payload\n * 5. Retries request with payment headers\n */\nexport function createFetchWithPayment(options: FetchWithPaymentOptions) {\n const { surface, clients, paymentMethod, beforePayment } = options;\n\n return async (request: Request) => {\n const clonedRequest = request.clone();\n const fallbackRequest = request.clone();\n\n const probeResult = await safeFetch(surface, request);\n\n if (probeResult.isErr()) {\n return fetchErr(surface, probeResult.error);\n }\n\n // Not a 402 response — return as-is\n if (probeResult.value.status !== 402) {\n return probeResult.andThen(response =>\n fetchOk<FetchWithPaymentResult>({ response, paymentInfo: null })\n );\n }\n\n const response = probeResult.value;\n\n // User explicitly chose a protocol — use that, no fallback\n if (paymentMethod !== 'auto') {\n if (paymentMethod === 'mpp') {\n return handleMppPayment(surface, response, clonedRequest, options);\n }\n return handleX402Payment(\n surface,\n response,\n clonedRequest,\n clients.x402,\n beforePayment\n );\n }\n\n // Auto: detect available protocols, pick by higher balance\n const available = detectPaymentProtocols(response);\n\n let preferred: 'x402' | 'mpp';\n\n if (available.length === 1) {\n preferred = available[0]!;\n } else {\n // Both protocols available — pick by balance\n preferred = await pickByBalance(surface, response, options);\n }\n\n const fallback =\n available.length > 1 ? (preferred === 'mpp' ? 'x402' : 'mpp') : null;\n\n const result =\n preferred === 'mpp'\n ? await handleMppPayment(surface, response, clonedRequest, options)\n : await handleX402Payment(\n surface,\n response,\n clonedRequest,\n clients.x402,\n beforePayment\n );\n\n if (result.isErr() && fallback) {\n // Preferred failed — try fallback with a fresh request clone\n return fallback === 'mpp'\n ? handleMppPayment(surface, response, fallbackRequest, options)\n : handleX402Payment(\n surface,\n response,\n fallbackRequest,\n clients.x402,\n beforePayment\n );\n }\n\n return result;\n };\n}\n\n/**\n * Pick the preferred protocol by comparing wallet balances.\n * Falls back to 'mpp' if both balances fail to fetch.\n */\nasync function pickByBalance(\n surface: string,\n response: Response,\n options: FetchWithPaymentOptions\n): Promise<'x402' | 'mpp'> {\n const { account, flags } = options;\n\n // Get x402 (USDC on Base) balance\n const x402BalanceResult = await resultFromPromise(\n 'balance',\n surface,\n getBalance({\n address: account.address,\n flags,\n surface,\n }).then(r => (r.isOk() ? r.value.balance : 0)),\n () => ({\n cause: 'x402_balance' as const,\n message: 'Failed to get x402 balance',\n })\n );\n\n if (x402BalanceResult.isErr()) {\n log.debug('Balance comparison failed, defaulting to mpp');\n return 'mpp';\n }\n\n const x402Balance = x402BalanceResult.value;\n\n // Get MPP (Tempo) balance — need token address from the challenge\n let mppBalance = 0;\n const challengeResult = safeGetMppChallenge(surface, response);\n if (challengeResult.isOk()) {\n const currency = challengeResult.value.request.currency as\n | string\n | undefined;\n const decimals =\n (challengeResult.value.request.decimals as number | undefined) ?? 6;\n if (currency) {\n const tempoResult = await resultFromPromise(\n 'tempo',\n surface,\n getTempoBalance({\n address: account.address,\n tokenAddress: currency as Address,\n }),\n () => ({\n cause: 'tempo_balance' as const,\n message: 'Tempo balance check failed',\n })\n );\n if (tempoResult.isOk()) {\n mppBalance = Number(formatUnits(tempoResult.value.balance, decimals));\n }\n }\n }\n\n log.info(`Protocol selection — x402: $${x402Balance}, mpp: $${mppBalance}`);\n return x402Balance >= mppBalance ? 'x402' : 'mpp';\n}\n\nasync function handleX402Payment(\n surface: string,\n response: Response,\n clonedRequest: Request,\n client: x402HTTPClient,\n beforePayment?: BeforePaymentHook\n) {\n const paymentRequiredResult = await safeGetPaymentRequired(\n surface,\n client,\n response\n );\n\n if (paymentRequiredResult.isErr()) {\n return paymentRequiredResult;\n }\n\n const paymentRequired = paymentRequiredResult.value;\n\n // Call beforePayment hook (e.g. balance check) before signing\n if (beforePayment) {\n const accept = paymentRequired.accepts[0];\n if (accept) {\n const amount = tokenStringToNumber(accept.amount);\n const hookResult = await resultFromPromise(\n 'x402',\n surface,\n beforePayment({\n protocol: 'x402',\n amount,\n currency: 'USDC',\n network: accept.network,\n }),\n e => ({\n cause: 'payment_already_attempted' as const,\n message:\n e instanceof Error ? e.message : 'Before-payment hook failed',\n })\n );\n if (hookResult.isErr()) {\n return x402Err(surface, hookResult.error);\n }\n }\n }\n\n const paymentPayloadResult = await safeCreatePaymentPayload(\n surface,\n client,\n paymentRequired\n );\n\n if (paymentPayloadResult.isErr()) {\n return paymentPayloadResult;\n }\n\n const paymentPayload = paymentPayloadResult.value;\n\n // Encode payment header\n const paymentHeaders = client.encodePaymentSignatureHeader(paymentPayload);\n\n // Check if this is already a retry to prevent infinite loops\n if (\n clonedRequest.headers.has('PAYMENT-SIGNATURE') ||\n clonedRequest.headers.has('X-PAYMENT')\n ) {\n return x402Err(surface, {\n cause: 'payment_already_attempted',\n message: 'Payment already attempted',\n });\n }\n\n // Add payment headers to cloned request\n for (const [key, value] of Object.entries(paymentHeaders)) {\n clonedRequest.headers.set(key, value);\n }\n clonedRequest.headers.set(\n 'Access-Control-Expose-Headers',\n 'PAYMENT-RESPONSE,X-PAYMENT-RESPONSE'\n );\n\n // Retry the request with payment\n return await safeFetch(surface, clonedRequest).andThen(paidResponse => {\n const settlementResult = safeGetPaymentSettlement(\n surface,\n client,\n paidResponse\n );\n\n return x402Ok<FetchWithPaymentResult>({\n response: paidResponse,\n paymentInfo: {\n protocol: 'x402',\n price: tokenStringToNumber(\n paymentPayload.accepted.amount\n ).toLocaleString('en-US', {\n style: 'currency',\n currency: 'USD',\n }),\n ...(settlementResult.isOk()\n ? {\n payment: {\n success: settlementResult.value.success,\n transactionHash: settlementResult.value.transaction,\n },\n }\n : {}),\n },\n });\n });\n}\n\nasync function handleMppPayment(\n surface: string,\n response: Response,\n clonedRequest: Request,\n options: FetchWithPaymentOptions\n) {\n const { clients, beforePayment } = options;\n const mpayClient = clients.mpp;\n\n // Prevent retry loops\n if (clonedRequest.headers.has('Authorization')) {\n return mppErr(surface, {\n cause: 'mpp_payment_already_attempted',\n message: 'MPP payment already attempted',\n });\n }\n\n // Parse the challenge from the WWW-Authenticate header\n const challengeResult = safeGetMppChallenge(surface, response);\n\n if (challengeResult.isErr()) {\n return challengeResult;\n }\n\n const challenge = challengeResult.value;\n\n // Extract payment info from challenge request\n const amount = challenge.request.amount as string | undefined;\n const decimals = (challenge.request.decimals as number | undefined) ?? 6;\n const currency = challenge.request.currency as string | undefined;\n\n // Call beforePayment hook (e.g. balance check)\n if (beforePayment && amount && currency) {\n const numericAmount = Number(formatUnits(BigInt(amount), decimals));\n const hookResult = await resultFromPromise(\n 'mpp',\n surface,\n beforePayment({\n protocol: 'mpp',\n amount: numericAmount,\n currency,\n network: `tempo:${challenge.method}`,\n }),\n e => ({\n cause: 'mpp_payment_already_attempted' as const,\n message: e instanceof Error ? e.message : 'Before-payment hook failed',\n })\n );\n if (hookResult.isErr()) {\n return mppErr(surface, hookResult.error);\n }\n }\n\n // Create credential (signs transaction on Tempo)\n const credentialResult = await safeCreateMppCredential(\n surface,\n mpayClient,\n response\n );\n\n if (credentialResult.isErr()) {\n return credentialResult;\n }\n\n const credential = credentialResult.value;\n\n // Set Authorization header on cloned request\n clonedRequest.headers.set('Authorization', credential);\n\n // Retry the fetch with the credential\n return await safeFetch(surface, clonedRequest).andThen(paidResponse => {\n // Parse the receipt for transaction hash\n const receiptResult = safeGetMppReceipt(surface, paidResponse);\n\n const priceDisplay = amount\n ? Number(formatUnits(BigInt(amount), decimals)).toLocaleString('en-US', {\n style: 'currency',\n currency: 'USD',\n })\n : undefined;\n\n return mppOk<FetchWithPaymentResult>({\n response: paidResponse,\n paymentInfo: {\n protocol: 'mpp',\n ...(priceDisplay ? { price: priceDisplay } : {}),\n ...(receiptResult.isOk()\n ? {\n payment: {\n success: true,\n transactionHash: receiptResult.value.reference,\n },\n }\n : {}),\n },\n });\n });\n}\n"],"mappings":"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","names":["response"]}
@@ -1,35 +1,34 @@
1
1
  import {
2
2
  buildRequest,
3
- requestSchema
4
- } from "./chunk-XXKBL2AC.js";
5
- import {
6
3
  createFetchWithPayment,
7
- getWalletInfo,
8
- submitErrorReport
9
- } from "./chunk-GIYROB7O.js";
4
+ requestSchema
5
+ } from "./chunk-VVTMCXSK.js";
10
6
  import {
7
+ TEMPO_RPC_URL,
11
8
  checkEndpoint,
12
9
  discoverResources,
13
- safeGetPaymentSettlement,
14
- tokenStringToNumber
15
- } from "./chunk-NQNMVKGY.js";
16
- import "./chunk-FJSHGCIM.js";
10
+ getWalletInfo,
11
+ submitErrorReport
12
+ } from "./chunk-FM2E2QVT.js";
13
+ import "./chunk-DZC5MTYY.js";
17
14
  import {
18
15
  DEFAULT_NETWORK,
19
16
  getWallet,
20
17
  redeemInviteCode,
21
- safeParseJson
22
- } from "./chunk-GCS3RSLB.js";
23
- import "./chunk-CZBCIWYU.js";
18
+ safeParseJson,
19
+ toJsonObject
20
+ } from "./chunk-EVE4PTLY.js";
24
21
  import {
25
22
  safeParseResponse
26
- } from "./chunk-KD2ZZXT7.js";
23
+ } from "./chunk-PJFATGPH.js";
27
24
  import "./chunk-ISR6DJ53.js";
28
25
 
29
26
  // src/cli/commands/fetch.ts
30
27
  import { randomBytes } from "crypto";
31
28
  import { x402Client, x402HTTPClient } from "@x402/core/client";
32
29
  import { ExactEvmScheme } from "@x402/evm/exact/client";
30
+ import { Mpay, tempo as tempoMethod } from "mpay/client";
31
+ import { tempo } from "viem/chains";
33
32
 
34
33
  // src/cli/output/types.ts
35
34
  var errorCodeToExitCode = {
@@ -233,7 +232,7 @@ function parseRequestInput(surface, args, flags) {
233
232
  }
234
233
  const inputResult = requestSchema.safeParse({
235
234
  url: args.url,
236
- method: args.method ?? "GET",
235
+ method: args.method,
237
236
  body: parsedBody,
238
237
  headers: parsedHeaders ?? {}
239
238
  });
@@ -262,20 +261,34 @@ async function fetchCommand(args, flags) {
262
261
  { network: DEFAULT_NETWORK, client: new ExactEvmScheme(account) }
263
262
  ]
264
263
  });
265
- const client = new x402HTTPClient(coreClient);
264
+ const x402HttpClient = new x402HTTPClient(coreClient);
265
+ const mpayClient = Mpay.create({
266
+ methods: [
267
+ tempoMethod({
268
+ account,
269
+ rpcUrl: { [tempo.id]: TEMPO_RPC_URL }
270
+ })
271
+ ]
272
+ });
266
273
  const provider = flags.provider ?? account.address;
274
+ const paymentMethod = args.paymentMethod ?? "auto";
267
275
  const request = buildRequest({
268
276
  input,
269
277
  address: account.address,
270
278
  sessionId,
271
279
  provider
272
280
  });
273
- const fetchWithPay = createFetchWithPayment(SURFACE, client);
274
- const fetchResult = await fetchWithPay(request);
281
+ const fetchResult = await createFetchWithPayment({
282
+ surface: SURFACE,
283
+ clients: { x402: x402HttpClient, mpp: mpayClient },
284
+ paymentMethod,
285
+ account,
286
+ flags
287
+ })(request);
275
288
  if (fetchResult.isErr()) {
276
289
  return outputAndExit(fromNeverthrowError(fetchResult), flags);
277
290
  }
278
- const { response, paymentPayload } = fetchResult.value;
291
+ const { response, paymentInfo } = fetchResult.value;
279
292
  if (!response.ok) {
280
293
  const parseResult = await safeParseResponse(SURFACE, response);
281
294
  const details = { statusCode: response.status };
@@ -304,23 +317,11 @@ async function fetchCommand(args, flags) {
304
317
  if (parseResponseResult.isErr()) {
305
318
  return outputAndExit(fromNeverthrowError(parseResponseResult), flags);
306
319
  }
307
- const settlementResult = safeGetPaymentSettlement(SURFACE, client, response);
308
320
  const data = parseResponseResult.value.type === "json" ? parseResponseResult.value.data : parseResponseResult.value.type === "text" ? parseResponseResult.value.data : { type: parseResponseResult.value.type };
309
- const metadata = settlementResult.isOk() || paymentPayload !== void 0 ? {
310
- ...paymentPayload !== void 0 ? {
311
- price: tokenStringToNumber(
312
- paymentPayload.accepted.amount
313
- ).toLocaleString("en-US", {
314
- style: "currency",
315
- currency: "USD"
316
- })
317
- } : {},
318
- ...settlementResult.isOk() ? {
319
- payment: {
320
- success: settlementResult.value.success,
321
- transactionHash: settlementResult.value.transaction
322
- }
323
- } : {}
321
+ const metadata = paymentInfo ? {
322
+ protocol: paymentInfo.protocol,
323
+ ...paymentInfo.price ? { price: paymentInfo.price } : {},
324
+ ...paymentInfo.payment ? { payment: paymentInfo.payment } : {}
324
325
  } : void 0;
325
326
  outputAndExit(successResponse(data, metadata), flags);
326
327
  }
@@ -332,96 +333,44 @@ async function checkCommand(args, flags) {
332
333
  const { account } = await getWalletOrExit(flags);
333
334
  const sessionId = randomBytes2(16).toString("hex");
334
335
  const input = parseRequestInput(SURFACE2, args, flags);
335
- const request = buildRequest({
336
- input,
337
- address: account.address,
338
- sessionId
336
+ const result = await checkEndpoint({
337
+ surface: SURFACE2,
338
+ url: input.url,
339
+ methods: input.method ? [input.method] : void 0,
340
+ body: input.body,
341
+ headers: {
342
+ ...input.headers ?? {},
343
+ "X-Wallet-Address": account.address,
344
+ "X-Session-ID": sessionId
345
+ },
346
+ includeMethodErrors: !!input.method
339
347
  });
340
- const result = await checkEndpoint(SURFACE2, request);
341
- if (result.isErr()) {
342
- return outputAndExit(fromNeverthrowError(result), flags);
343
- }
344
- const value = result.value;
345
- if (value instanceof Response) {
346
- const response = value;
347
- const parseResult = await safeParseResponse(SURFACE2, response);
348
- const details = { statusCode: response.status };
349
- if (parseResult.isOk()) {
350
- const { type } = parseResult.value;
351
- if (type === "json") {
352
- details.body = parseResult.value.data;
353
- } else if (type === "text") {
354
- details.body = parseResult.value.data;
355
- } else {
356
- details.bodyType = type;
357
- }
358
- }
359
- return outputAndExit(
360
- errorResponse({
361
- code: "HTTP_ERROR",
362
- message: `HTTP ${response.status}: ${response.statusText}`,
363
- surface: SURFACE2,
364
- cause: "http",
365
- details
366
- }),
367
- flags
368
- );
369
- }
370
- if ("requiresPayment" in value && value.requiresPayment) {
371
- return outputAndExit(
372
- successResponse({
373
- requiresPayment: true,
374
- statusCode: value.statusCode,
375
- routeDetails: value.routeDetails
376
- }),
377
- flags
378
- );
379
- }
380
- if ("parsedResponse" in value) {
381
- const { parsedResponse } = value;
382
- const data = parsedResponse.type === "json" ? parsedResponse.data : parsedResponse.type === "text" ? parsedResponse.data : { type: parsedResponse.type };
383
- return outputAndExit(
384
- successResponse({
385
- requiresPayment: false,
386
- statusCode: value.statusCode,
387
- data
388
- }),
389
- flags
390
- );
391
- }
392
- return outputAndExit(
393
- errorResponse({
394
- code: "GENERAL_ERROR",
395
- message: "Unexpected response format",
396
- surface: SURFACE2,
397
- cause: "unknown"
398
- }),
399
- flags
400
- );
348
+ return outputAndExit(successResponse(toJsonObject(result)), flags);
401
349
  }
402
350
 
403
351
  // src/cli/commands/discover.ts
404
352
  async function discoverCommand(args, flags) {
405
353
  const result = await discoverResources("cli:discover", args.url);
406
- if (result.isOk()) {
354
+ if (result) {
407
355
  return outputAndExit(
408
356
  successResponse({
409
357
  found: true,
410
- origin: result.value.origin,
411
- source: result.value.source,
412
- endpoints: result.value.endpoints.map((e) => ({ ...e })),
413
- ...result.value.instructions ? { instructions: result.value.instructions } : {}
358
+ origin: result.origin,
359
+ source: result.source,
360
+ endpoints: result.endpoints.map((e) => ({ ...e })),
361
+ ...result.instructions ? { instructions: result.instructions } : {}
414
362
  }),
415
363
  flags
416
364
  );
417
365
  }
366
+ const origin = URL.canParse(args.url) ? new URL(args.url).origin : args.url;
418
367
  return outputAndExit(
419
368
  errorResponse({
420
369
  code: "GENERAL_ERROR",
421
- message: result.error.message,
422
- surface: result.error.surface,
423
- cause: result.error.cause,
424
- details: { origin: result.error.origin }
370
+ message: `No OpenAPI spec found for ${origin}. Tried: /openapi.json, /.well-known/openapi.json, /.well-known/x402, /.well-known/mpp`,
371
+ surface: "cli:discover",
372
+ cause: "not_found",
373
+ details: { origin }
425
374
  }),
426
375
  flags
427
376
  );
@@ -503,7 +452,7 @@ async function reportErrorCommand(args, flags) {
503
452
 
504
453
  // src/cli/commands/server.ts
505
454
  async function serverCommand(flags) {
506
- const { startServer } = await import("./server-7D6YY3KG.js");
455
+ const { startServer } = await import("./server-WCNK52XR.js");
507
456
  await startServer(flags);
508
457
  }
509
458
  export {
@@ -515,4 +464,4 @@ export {
515
464
  walletInfoCommand,
516
465
  walletRedeemCommand
517
466
  };
518
- //# sourceMappingURL=commands-DUIGMEXV.js.map
467
+ //# sourceMappingURL=commands-DE2RIAL5.js.map