@agirails/sdk 4.0.0-beta.9 → 4.1.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 (71) hide show
  1. package/README.md +24 -0
  2. package/dist/abi/ACTPKernel.json +461 -47
  3. package/dist/adapters/BaseAdapter.d.ts +1 -1
  4. package/dist/adapters/BaseAdapter.js +1 -1
  5. package/dist/builders/CounterOfferBuilder.d.ts +2 -2
  6. package/dist/cli/commands/init.d.ts.map +1 -1
  7. package/dist/cli/commands/init.js +11 -1
  8. package/dist/cli/commands/init.js.map +1 -1
  9. package/dist/cli/commands/publish.d.ts.map +1 -1
  10. package/dist/cli/commands/publish.js +14 -2
  11. package/dist/cli/commands/publish.js.map +1 -1
  12. package/dist/cli/commands/test.d.ts.map +1 -1
  13. package/dist/cli/commands/test.js +8 -0
  14. package/dist/cli/commands/test.js.map +1 -1
  15. package/dist/cli/lib/runRequest.d.ts +12 -0
  16. package/dist/cli/lib/runRequest.d.ts.map +1 -1
  17. package/dist/cli/lib/runRequest.js +55 -0
  18. package/dist/cli/lib/runRequest.js.map +1 -1
  19. package/dist/cli/utils/config.d.ts +11 -0
  20. package/dist/cli/utils/config.d.ts.map +1 -1
  21. package/dist/cli/utils/config.js +60 -8
  22. package/dist/cli/utils/config.js.map +1 -1
  23. package/dist/config/agirailsmd.d.ts +2 -1
  24. package/dist/config/agirailsmd.d.ts.map +1 -1
  25. package/dist/config/agirailsmd.js +33 -2
  26. package/dist/config/agirailsmd.js.map +1 -1
  27. package/dist/config/networks.d.ts.map +1 -1
  28. package/dist/config/networks.js +13 -13
  29. package/dist/config/networks.js.map +1 -1
  30. package/dist/errors/X402Errors.d.ts +37 -1
  31. package/dist/errors/X402Errors.d.ts.map +1 -1
  32. package/dist/errors/X402Errors.js +37 -1
  33. package/dist/errors/X402Errors.js.map +1 -1
  34. package/dist/errors/index.d.ts +86 -9
  35. package/dist/errors/index.d.ts.map +1 -1
  36. package/dist/errors/index.js +86 -9
  37. package/dist/errors/index.js.map +1 -1
  38. package/dist/index.js +1 -1
  39. package/dist/index.js.map +1 -1
  40. package/dist/level0/index.d.ts +1 -1
  41. package/dist/level0/index.js +1 -1
  42. package/dist/level0/provide.d.ts +1 -1
  43. package/dist/level0/provide.js +1 -1
  44. package/dist/level0/request.d.ts +1 -1
  45. package/dist/level0/request.js +1 -1
  46. package/dist/level1/Agent.js +2 -2
  47. package/dist/level1/Agent.js.map +1 -1
  48. package/dist/level1/types/Options.d.ts +2 -2
  49. package/dist/negotiation/BuyerOrchestrator.d.ts +3 -3
  50. package/dist/negotiation/BuyerOrchestrator.d.ts.map +1 -1
  51. package/dist/negotiation/NegotiationChannel.d.ts +1 -1
  52. package/dist/negotiation/ProviderPolicy.d.ts +1 -1
  53. package/dist/negotiation/RelayChannel.d.ts +7 -0
  54. package/dist/negotiation/RelayChannel.d.ts.map +1 -1
  55. package/dist/negotiation/RelayChannel.js +8 -0
  56. package/dist/negotiation/RelayChannel.js.map +1 -1
  57. package/dist/negotiation/verifyQuoteOnChain.d.ts +7 -7
  58. package/dist/negotiation/verifyQuoteOnChain.js +7 -7
  59. package/dist/protocol/EASHelper.d.ts.map +1 -1
  60. package/dist/protocol/EASHelper.js +11 -2
  61. package/dist/protocol/EASHelper.js.map +1 -1
  62. package/dist/receipts/push.d.ts +88 -0
  63. package/dist/receipts/push.d.ts.map +1 -0
  64. package/dist/receipts/push.js +167 -0
  65. package/dist/receipts/push.js.map +1 -0
  66. package/dist/wallet/IWalletProvider.d.ts +1 -1
  67. package/package.json +11 -3
  68. package/dist/__tests__/helpers/mockX402Server.d.ts +0 -67
  69. package/dist/__tests__/helpers/mockX402Server.d.ts.map +0 -1
  70. package/dist/__tests__/helpers/mockX402Server.js +0 -121
  71. package/dist/__tests__/helpers/mockX402Server.js.map +0 -1
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ /**
3
+ * Buyer-visible settlement receipt — SDK push path.
4
+ *
5
+ * On SETTLED state transition, the SDK posts a V2-signed receipt to the
6
+ * AGIRAILS Platform. The response includes a clickable receipt URL which the
7
+ * CLI prints to the terminal — the wow moment.
8
+ *
9
+ * Integration points (sdk-js team):
10
+ * 1. Import this module from wherever lifecycle reaches SETTLED
11
+ * (likely src/api/level1/Agent.ts or src/runtime/BlockchainRuntime.ts).
12
+ * 2. After the on-chain state advances to SETTLED, call:
13
+ * const { receiptUrl } = await pushReceiptOnSettled({...});
14
+ * 3. Surface receiptUrl on the public RequestResult and to CLI commands
15
+ * (pay, test, serve) so they print it.
16
+ *
17
+ * Non-goals:
18
+ * - This module does NOT change the lifecycle itself.
19
+ * - Failure is non-fatal: settlement already happened on-chain; the Platform
20
+ * indexer cron is the backstop for cases where this POST fails.
21
+ *
22
+ * Auth: V2 EIP-712 signature, requester wallet (when SDK acts as requester) or
23
+ * provider wallet (when SDK acts as provider). The Platform's POST handler
24
+ * verifies the signer matches participantRole, AND independently verifies
25
+ * on-chain that the tx really exists with claimed values. Forgery is not
26
+ * possible without on-chain truth.
27
+ */
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.formatSettledLine = exports.pushReceiptOnSettled = exports.RECEIPT_WRITE_TYPES_V2 = exports.RECEIPT_WRITE_DOMAIN_V2 = void 0;
30
+ // ──────────────────────────────────────────────────────────────────────────
31
+ // EIP-712 V2 — must match Platform/agirails.app/web/lib/receipts/eip712.ts
32
+ // ──────────────────────────────────────────────────────────────────────────
33
+ exports.RECEIPT_WRITE_DOMAIN_V2 = {
34
+ name: "AGIRAILS Receipts",
35
+ version: "2",
36
+ };
37
+ exports.RECEIPT_WRITE_TYPES_V2 = {
38
+ ReceiptWriteV2: [
39
+ { name: "signerAddress", type: "address" },
40
+ { name: "participantRole", type: "string" },
41
+ { name: "providerAddress", type: "address" },
42
+ { name: "requesterAddress", type: "address" },
43
+ { name: "kernelAddress", type: "address" },
44
+ { name: "txId", type: "bytes32" },
45
+ { name: "network", type: "string" },
46
+ { name: "amountWei", type: "uint256" },
47
+ { name: "feeWei", type: "uint256" },
48
+ { name: "netWei", type: "uint256" },
49
+ { name: "serviceHash", type: "bytes32" },
50
+ { name: "nonce", type: "string" },
51
+ { name: "issuedAt", type: "uint64" },
52
+ ],
53
+ };
54
+ const ZERO_BYTES32 = "0x" + "0".repeat(64);
55
+ function chainIdForNetwork(network) {
56
+ return network === "base-mainnet" ? 8453 : 84532;
57
+ }
58
+ async function pushReceiptOnSettled(args) {
59
+ // Resolution priority: explicit arg > AGIRAILS_BASE_URL env > prod default.
60
+ // Matches the env-driven origin convention already used by cli/receiptUpload.ts.
61
+ const apiBase = (args.apiBase ?? process.env.AGIRAILS_BASE_URL ?? "https://agirails.app").replace(/\/+$/, "");
62
+ const signerAddress = await args.signer.getAddress();
63
+ try {
64
+ // 1) Fetch a single-use nonce bound to the signer wallet.
65
+ const prepRes = await fetch(`${apiBase}/api/v1/receipts/prepare`, {
66
+ method: "POST",
67
+ headers: { "Content-Type": "application/json" },
68
+ body: JSON.stringify({ signerAddress }),
69
+ });
70
+ if (!prepRes.ok)
71
+ throw new Error(`prepare_failed:${prepRes.status}`);
72
+ const { nonce } = (await prepRes.json());
73
+ const issuedAt = Math.floor(Date.now() / 1000);
74
+ const payload = {
75
+ signerAddress,
76
+ participantRole: args.participantRole,
77
+ providerAddress: args.providerAddress,
78
+ requesterAddress: args.requesterAddress,
79
+ kernelAddress: args.kernelAddress,
80
+ txId: args.txId,
81
+ network: args.network,
82
+ amountWei: args.amountWei,
83
+ feeWei: args.feeWei,
84
+ netWei: args.netWei,
85
+ serviceHash: args.serviceHash ?? ZERO_BYTES32,
86
+ nonce,
87
+ issuedAt,
88
+ };
89
+ // 2) EIP-712 V2 sign — domain chainId is part of the binding.
90
+ const domain = {
91
+ ...exports.RECEIPT_WRITE_DOMAIN_V2,
92
+ chainId: chainIdForNetwork(args.network),
93
+ };
94
+ const signature = await args.signer.signTypedData(domain, exports.RECEIPT_WRITE_TYPES_V2, payload);
95
+ // 3) POST receipt. Body fields match the payload; server reconstructs
96
+ // and verifies them against the signature.
97
+ const postRes = await fetch(`${apiBase}/api/v1/receipts`, {
98
+ method: "POST",
99
+ headers: {
100
+ "X-Agent-Address": signerAddress,
101
+ "X-Agent-Signature": signature,
102
+ "Content-Type": "application/json",
103
+ },
104
+ body: JSON.stringify({
105
+ participantRole: args.participantRole,
106
+ signerAddress,
107
+ agentAddress: args.providerAddress,
108
+ requesterAddress: args.requesterAddress,
109
+ kernelAddress: args.kernelAddress,
110
+ txId: args.txId,
111
+ network: args.network,
112
+ amountWei: args.amountWei,
113
+ feeWei: args.feeWei,
114
+ netWei: args.netWei,
115
+ serviceHash: args.serviceHash,
116
+ ethTxHash: args.ethTxHash,
117
+ blockNumber: args.blockNumber,
118
+ logIndex: args.logIndex,
119
+ service: args.service,
120
+ durationMs: args.durationMs,
121
+ agentSignature: signature,
122
+ agentSignatureAlgorithm: "EIP712-ReceiptV2",
123
+ nonce,
124
+ issuedAt,
125
+ }),
126
+ });
127
+ if (!postRes.ok) {
128
+ // Common failure modes documented for SDK error handler:
129
+ // 401 — signature / signer / nonce invalid (likely SDK bug)
130
+ // 403 — role / address mismatch (SDK is signing as wrong wallet)
131
+ // 404 — agent not registered (buyer-side fresh-wallet path; expected,
132
+ // caller should still log the txId for indexer fallback)
133
+ // 422 — on_chain_verification_failed (RPC desync; transient — retry)
134
+ // 429 — rate limited (back off)
135
+ throw new Error(`post_failed:${postRes.status}`);
136
+ }
137
+ const body = (await postRes.json());
138
+ return {
139
+ receiptUrl: body.url ?? null,
140
+ receiptId: body.id ?? null,
141
+ verifiedOnChain: !!body.verified_on_chain,
142
+ };
143
+ }
144
+ catch {
145
+ // Receipt POST failure is non-fatal — settlement already happened on-chain.
146
+ // Indexer cron at /api/cron/index-stats backfills receipt rows within ~5min.
147
+ // Surface null so the CLI knows not to print a URL.
148
+ return { receiptUrl: null, receiptId: null, verifiedOnChain: false };
149
+ }
150
+ }
151
+ exports.pushReceiptOnSettled = pushReceiptOnSettled;
152
+ /**
153
+ * Format the one-line CLI summary the buyer or provider sees at SETTLED.
154
+ * Returns the line as a string; the CLI prints it. URL is omitted if null
155
+ * (indexer backstop will eventually mint a receipt but we have no PK for it).
156
+ */
157
+ function formatSettledLine(args) {
158
+ const action = args.participantRole === "provider"
159
+ ? `Earned ${args.netDisplay} from ${args.counterpartyDisplay}`
160
+ : `Paid ${args.grossDisplay} to ${args.counterpartyDisplay}`;
161
+ if (args.receiptUrl) {
162
+ return `[SETTLED] ${action}\n Receipt: ${args.receiptUrl}`;
163
+ }
164
+ return `[SETTLED] ${action}`;
165
+ }
166
+ exports.formatSettledLine = formatSettledLine;
167
+ //# sourceMappingURL=push.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/receipts/push.ts"],"names":[],"mappings":"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"}
@@ -29,7 +29,7 @@ export interface TransactionReceipt {
29
29
  success: boolean;
30
30
  }
31
31
  /**
32
- * Wallet tier determines gas behavior.
32
+ * Wallet tier: determines gas behavior.
33
33
  */
34
34
  export type WalletTier = 'auto' | 'eoa';
35
35
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agirails/sdk",
3
- "version": "4.0.0-beta.9",
3
+ "version": "4.1.0",
4
4
  "description": "AGIRAILS SDK for the ACTP (Agent Commerce Transaction Protocol) - Unified mock + blockchain support",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -46,6 +46,10 @@
46
46
  "README.md",
47
47
  "LICENSE"
48
48
  ],
49
+ "publishConfig": {
50
+ "access": "public",
51
+ "provenance": true
52
+ },
49
53
  "scripts": {
50
54
  "build": "tsc",
51
55
  "test": "jest --runInBand",
@@ -84,7 +88,7 @@
84
88
  "homepage": "https://github.com/agirails/sdk-js#readme",
85
89
  "dependencies": {
86
90
  "@aws-sdk/client-s3": "^3.1030.0",
87
- "@ethereum-attestation-service/eas-sdk": "1.6.1",
91
+ "@ethereum-attestation-service/eas-sdk": "^2.9.0",
88
92
  "@irys/sdk": "0.2.11",
89
93
  "@x402/core": "~2.9.0",
90
94
  "@x402/evm": "~2.9.0",
@@ -125,6 +129,10 @@
125
129
  },
126
130
  "overrides": {
127
131
  "axios": "^1.15.0",
128
- "fast-xml-parser": "^5.3.5"
132
+ "fast-xml-parser": "^5.3.5",
133
+ "undici": "^6.25.0",
134
+ "serialize-javascript": "^7.0.5",
135
+ "mocha": "^11.0.0",
136
+ "uuid": "^9.0.1"
129
137
  }
130
138
  }
@@ -1,67 +0,0 @@
1
- /**
2
- * Raw node:http mock x402 v2 server for unit/integration tests.
3
- *
4
- * Returns a 402 `payment-required` response, verifies that the retry carries
5
- * a `payment-signature` header, and replies with a mock `payment-response`
6
- * header so tests can validate the buyer-side parse/sign/retry/map loop end
7
- * to end without touching a real facilitator or on-chain settlement.
8
- *
9
- * Design notes:
10
- * - Raw `node:http`, no Express dependency. Keeps the test surface small and
11
- * isolates "what we're testing" (our X402Adapter) from upstream middleware.
12
- * - Payload is Base64-encoded JSON matching the x402 v2 wire format.
13
- * - Factory signature supports both EIP-3009 (`extra.assetTransferMethod` omitted)
14
- * and Permit2 (`extra.assetTransferMethod = "permit2"`) scenarios via options.
15
- * - Server listens on a random port (port 0) so multiple tests can run in parallel.
16
- *
17
- * @module __tests__/helpers/mockX402Server
18
- */
19
- export interface MockX402ServerOptions {
20
- /** CAIP-2 network. Default: "eip155:84532" (Base Sepolia) */
21
- network?: string;
22
- /** USDC amount as string (6 decimals). Default: "10000" (0.01 USDC) */
23
- amount?: string;
24
- /** Token contract address. Default: Base Sepolia USDC */
25
- asset?: string;
26
- /** Payment destination. Default: test provider address */
27
- payTo?: string;
28
- /** Set Permit2 transfer method. Default: EIP-3009 */
29
- permit2?: boolean;
30
- /** maxTimeoutSeconds advertised in requirements. Default: 300 */
31
- maxTimeoutSeconds?: number;
32
- /** Settlement tx hash returned in payment-response. Default: "0xmockhash" */
33
- settlementTxHash?: string;
34
- /**
35
- * When true, the retry request will receive HTTP 200 but NO payment-response
36
- * header. Used to test X402SettlementProofMissingError handling.
37
- */
38
- omitPaymentResponse?: boolean;
39
- }
40
- export interface MockX402ServerHandle {
41
- url: string;
42
- port: number;
43
- close: () => Promise<void>;
44
- /** Count of initial 402 hits (useful for retry verification) */
45
- getInitialRequestCount: () => number;
46
- /** Count of retry requests (carrying payment-signature) */
47
- getRetryRequestCount: () => number;
48
- }
49
- /**
50
- * Start a mock x402 v2 server on a random localhost port.
51
- *
52
- * Returns a handle with `.url` (e.g., `http://localhost:54321`), `.close()`
53
- * to tear down, and counters for asserting the number of round-trips.
54
- *
55
- * @example
56
- * ```ts
57
- * const server = await startMockX402Server({ permit2: true });
58
- * try {
59
- * const res = await fetch(server.url);
60
- * expect(res.status).toBe(402);
61
- * } finally {
62
- * await server.close();
63
- * }
64
- * ```
65
- */
66
- export declare function startMockX402Server(options?: MockX402ServerOptions): Promise<MockX402ServerHandle>;
67
- //# sourceMappingURL=mockX402Server.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mockX402Server.d.ts","sourceRoot":"","sources":["../../../src/__tests__/helpers/mockX402Server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,MAAM,WAAW,qBAAqB;IACpC,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iEAAiE;IACjE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,gEAAgE;IAChE,sBAAsB,EAAE,MAAM,MAAM,CAAC;IACrC,2DAA2D;IAC3D,oBAAoB,EAAE,MAAM,MAAM,CAAC;CACpC;AAKD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,oBAAoB,CAAC,CA6D/B"}
@@ -1,121 +0,0 @@
1
- "use strict";
2
- /**
3
- * Raw node:http mock x402 v2 server for unit/integration tests.
4
- *
5
- * Returns a 402 `payment-required` response, verifies that the retry carries
6
- * a `payment-signature` header, and replies with a mock `payment-response`
7
- * header so tests can validate the buyer-side parse/sign/retry/map loop end
8
- * to end without touching a real facilitator or on-chain settlement.
9
- *
10
- * Design notes:
11
- * - Raw `node:http`, no Express dependency. Keeps the test surface small and
12
- * isolates "what we're testing" (our X402Adapter) from upstream middleware.
13
- * - Payload is Base64-encoded JSON matching the x402 v2 wire format.
14
- * - Factory signature supports both EIP-3009 (`extra.assetTransferMethod` omitted)
15
- * and Permit2 (`extra.assetTransferMethod = "permit2"`) scenarios via options.
16
- * - Server listens on a random port (port 0) so multiple tests can run in parallel.
17
- *
18
- * @module __tests__/helpers/mockX402Server
19
- */
20
- Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.startMockX402Server = void 0;
22
- const node_http_1 = require("node:http");
23
- const BASE_SEPOLIA_USDC = '0x036CbD53842c5426634e7929541eC2318f3dCF7e';
24
- const DEFAULT_PAY_TO = '0x0000000000000000000000000000000000000001';
25
- /**
26
- * Start a mock x402 v2 server on a random localhost port.
27
- *
28
- * Returns a handle with `.url` (e.g., `http://localhost:54321`), `.close()`
29
- * to tear down, and counters for asserting the number of round-trips.
30
- *
31
- * @example
32
- * ```ts
33
- * const server = await startMockX402Server({ permit2: true });
34
- * try {
35
- * const res = await fetch(server.url);
36
- * expect(res.status).toBe(402);
37
- * } finally {
38
- * await server.close();
39
- * }
40
- * ```
41
- */
42
- function startMockX402Server(options = {}) {
43
- const payload = buildPaymentRequiredPayload(options);
44
- const encodedPayload = Buffer.from(JSON.stringify(payload)).toString('base64');
45
- const settlementResponse = {
46
- transaction: options.settlementTxHash ?? '0xmockhash',
47
- network: options.network ?? 'eip155:84532',
48
- amount: options.amount ?? '10000',
49
- payer: '0xmockbuyer',
50
- payTo: options.payTo ?? DEFAULT_PAY_TO,
51
- };
52
- const encodedResponse = Buffer.from(JSON.stringify(settlementResponse)).toString('base64');
53
- let initialRequestCount = 0;
54
- let retryRequestCount = 0;
55
- return new Promise((resolve, reject) => {
56
- const server = (0, node_http_1.createServer)((req, res) => {
57
- const hasPaymentSignature = Boolean(req.headers['payment-signature']) ||
58
- Boolean(req.headers['x-payment']) ||
59
- Boolean(req.headers['PAYMENT-SIGNATURE']);
60
- if (!hasPaymentSignature) {
61
- // First hit — return 402 with payment-required
62
- initialRequestCount++;
63
- res.statusCode = 402;
64
- res.setHeader('content-type', 'application/json');
65
- res.setHeader('payment-required', encodedPayload);
66
- res.end('{}');
67
- return;
68
- }
69
- // Retry with signed payment — accept and return settlement proof
70
- retryRequestCount++;
71
- res.statusCode = 200;
72
- res.setHeader('content-type', 'application/json');
73
- if (!options.omitPaymentResponse) {
74
- res.setHeader('payment-response', encodedResponse);
75
- }
76
- res.end(JSON.stringify({ ok: true }));
77
- });
78
- server.on('error', (err) => reject(err));
79
- server.listen(0, '127.0.0.1', () => {
80
- const address = server.address();
81
- resolve({
82
- url: `http://127.0.0.1:${address.port}`,
83
- port: address.port,
84
- close: () => new Promise((r) => {
85
- server.close(() => r());
86
- }),
87
- getInitialRequestCount: () => initialRequestCount,
88
- getRetryRequestCount: () => retryRequestCount,
89
- });
90
- });
91
- });
92
- }
93
- exports.startMockX402Server = startMockX402Server;
94
- function buildPaymentRequiredPayload(options) {
95
- const network = options.network ?? 'eip155:84532';
96
- const extra = { name: 'USDC', version: '2' };
97
- if (options.permit2) {
98
- extra.assetTransferMethod = 'permit2';
99
- }
100
- return {
101
- x402Version: 2,
102
- error: 'Payment required',
103
- resource: {
104
- url: 'http://mock/x402',
105
- description: 'Mock x402 v2 test endpoint',
106
- mimeType: 'application/json',
107
- },
108
- accepts: [
109
- {
110
- scheme: 'exact',
111
- network,
112
- amount: options.amount ?? '10000',
113
- asset: options.asset ?? BASE_SEPOLIA_USDC,
114
- payTo: options.payTo ?? DEFAULT_PAY_TO,
115
- maxTimeoutSeconds: options.maxTimeoutSeconds ?? 300,
116
- extra,
117
- },
118
- ],
119
- };
120
- }
121
- //# sourceMappingURL=mockX402Server.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mockX402Server.js","sourceRoot":"","sources":["../../../src/__tests__/helpers/mockX402Server.ts"],"names":[],"mappings":"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"}