@armory-sh/base 0.2.12 → 0.2.14

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/dist/index.js CHANGED
@@ -104,6 +104,52 @@ function legacyToPaymentPayload(legacy) {
104
104
  };
105
105
  }
106
106
 
107
+ // src/types/v2.ts
108
+ var V2_HEADERS = {
109
+ PAYMENT_SIGNATURE: "PAYMENT-SIGNATURE",
110
+ PAYMENT_REQUIRED: "PAYMENT-REQUIRED",
111
+ PAYMENT_RESPONSE: "PAYMENT-RESPONSE"
112
+ };
113
+ function isCAIP2ChainId(value) {
114
+ return /^eip155:\d+$/.test(value);
115
+ }
116
+ function isCAIPAssetId(value) {
117
+ return /^eip155:\d+\/erc20:0x[a-fA-F0-9]+$/.test(value);
118
+ }
119
+ function isAddress(value) {
120
+ return /^0x[a-fA-F0-9]{40}$/.test(value);
121
+ }
122
+ function isPaymentRequiredV2(obj) {
123
+ return typeof obj === "object" && obj !== null && "x402Version" in obj && obj.x402Version === 2 && "resource" in obj && "accepts" in obj && Array.isArray(obj.accepts);
124
+ }
125
+ function isPaymentPayloadV2(obj) {
126
+ return typeof obj === "object" && obj !== null && "x402Version" in obj && obj.x402Version === 2 && "scheme" in obj && "network" in obj && "payload" in obj;
127
+ }
128
+ function assetIdToAddress(assetId) {
129
+ const match = assetId.match(/\/erc20:(0x[a-fA-F0-9]{40})$/);
130
+ if (!match) throw new Error(`Invalid CAIP asset ID: ${assetId}`);
131
+ return match[1];
132
+ }
133
+ function addressToAssetId(address, chainId) {
134
+ const chain = typeof chainId === "number" ? `eip155:${chainId}` : chainId;
135
+ if (!isCAIP2ChainId(chain)) throw new Error(`Invalid chain ID: ${chain}`);
136
+ return `${chain}/erc20:${address}`;
137
+ }
138
+ function parseSignature(signature) {
139
+ const sig = signature.slice(2);
140
+ return {
141
+ r: `0x${sig.slice(0, 64)}`,
142
+ s: `0x${sig.slice(64, 128)}`,
143
+ v: parseInt(sig.slice(128, 130), 16)
144
+ };
145
+ }
146
+ function combineSignature(v, r, s) {
147
+ const rClean = r.startsWith("0x") ? r.slice(2) : r;
148
+ const sClean = s.startsWith("0x") ? s.slice(2) : s;
149
+ const vHex = v.toString(16).padStart(2, "0");
150
+ return `0x${rClean}${sClean}${vHex}`;
151
+ }
152
+
107
153
  // src/encoding/x402.ts
108
154
  function safeBase64Encode(str) {
109
155
  return Buffer.from(str).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
@@ -159,34 +205,14 @@ function decodeX402Response(encoded) {
159
205
  const decoded = safeBase64Decode(encoded);
160
206
  return JSON.parse(decoded);
161
207
  }
162
- var X402_HEADERS = {
163
- PAYMENT: "X-PAYMENT",
164
- PAYMENT_RESPONSE: "X-PAYMENT-RESPONSE",
165
- PAYMENT_REQUIRED: "X-PAYMENT-REQUIRED"
166
- };
167
208
  function detectPaymentVersion(headers) {
168
209
  if (headers.has("PAYMENT-SIGNATURE")) {
169
210
  return 2;
170
211
  }
171
- if (headers.has(X402_HEADERS.PAYMENT)) {
172
- const encoded = headers.get(X402_HEADERS.PAYMENT);
173
- if (encoded) {
174
- try {
175
- const decoded = decodePayment(encoded);
176
- if (isPaymentPayload(decoded) && "x402Version" in decoded) {
177
- return decoded.x402Version;
178
- }
179
- return 1;
180
- } catch {
181
- return 1;
182
- }
183
- }
184
- return 1;
185
- }
186
212
  return null;
187
213
  }
188
214
  function extractPaymentFromHeaders(headers) {
189
- const encoded = headers.get(X402_HEADERS.PAYMENT);
215
+ const encoded = headers.get("PAYMENT-SIGNATURE");
190
216
  if (!encoded) return null;
191
217
  try {
192
218
  return decodePayment(encoded);
@@ -197,21 +223,18 @@ function extractPaymentFromHeaders(headers) {
197
223
  function createPaymentRequiredHeaders(requirements) {
198
224
  const accepts = Array.isArray(requirements) ? requirements : [requirements];
199
225
  const response = {
200
- x402Version: 1,
226
+ x402Version: 2,
201
227
  accepts
202
228
  };
203
229
  return {
204
- [X402_HEADERS.PAYMENT_REQUIRED]: safeBase64Encode(JSON.stringify(response))
230
+ [V2_HEADERS.PAYMENT_REQUIRED]: safeBase64Encode(JSON.stringify(response))
205
231
  };
206
232
  }
207
233
  function createSettlementHeaders(settlement) {
208
234
  return {
209
- [X402_HEADERS.PAYMENT_RESPONSE]: encodeSettlementResponse(settlement)
235
+ [V2_HEADERS.PAYMENT_RESPONSE]: encodeSettlementResponse(settlement)
210
236
  };
211
237
  }
212
- function isLegacyV1(payload) {
213
- return typeof payload === "object" && payload !== null && "v" in payload && typeof payload.v === "number";
214
- }
215
238
  function isLegacyV2(payload) {
216
239
  return typeof payload === "object" && payload !== null && "signature" in payload && typeof payload.signature === "object";
217
240
  }
@@ -289,107 +312,9 @@ function normalizeAddress(address) {
289
312
  return address.toLowerCase();
290
313
  }
291
314
 
292
- // src/types/v1.ts
293
- var V1_HEADERS = {
294
- PAYMENT: "X-PAYMENT",
295
- PAYMENT_RESPONSE: "X-PAYMENT-RESPONSE",
296
- PAYMENT_REQUIRED: "X-PAYMENT-REQUIRED"
297
- };
298
- function encodeX402PaymentRequiredV1(data) {
299
- return Buffer.from(JSON.stringify(data)).toString("base64");
300
- }
301
- function decodeX402PaymentRequiredV1(encoded) {
302
- return JSON.parse(Buffer.from(encoded, "base64").toString("utf-8"));
303
- }
304
- function encodeX402PaymentPayloadV1(data) {
305
- return Buffer.from(JSON.stringify(data)).toString("base64");
306
- }
307
- function decodeX402PaymentPayloadV1(encoded) {
308
- return JSON.parse(Buffer.from(encoded, "base64").toString("utf-8"));
309
- }
310
- function encodeX402SettlementResponseV1(data) {
311
- return Buffer.from(JSON.stringify(data)).toString("base64");
312
- }
313
- function decodeX402SettlementResponseV1(encoded) {
314
- return JSON.parse(Buffer.from(encoded, "base64").toString("utf-8"));
315
- }
316
- function encodePaymentPayloadLegacy(payload) {
317
- return Buffer.from(JSON.stringify(payload)).toString("base64");
318
- }
319
- function decodePaymentPayloadLegacy(encoded) {
320
- return JSON.parse(Buffer.from(encoded, "base64").toString("utf-8"));
321
- }
322
- function encodeSettlementResponseLegacy(response) {
323
- return Buffer.from(JSON.stringify(response)).toString("base64");
324
- }
325
- function decodeSettlementResponseLegacy(encoded) {
326
- return JSON.parse(Buffer.from(encoded, "base64").toString("utf-8"));
327
- }
328
- function isX402PaymentRequiredV1(obj) {
329
- return typeof obj === "object" && obj !== null && "x402Version" in obj && obj.x402Version === 1 && "accepts" in obj && Array.isArray(obj.accepts);
330
- }
331
- function isX402PaymentPayloadV1(obj) {
332
- return typeof obj === "object" && obj !== null && "x402Version" in obj && obj.x402Version === 1 && "scheme" in obj && "network" in obj && "payload" in obj;
333
- }
334
- function isLegacyPaymentPayloadV1(obj) {
335
- return typeof obj === "object" && obj !== null && "v" in obj && "r" in obj && "s" in obj && "chainId" in obj && "contractAddress" in obj;
336
- }
337
-
338
- // src/types/v2.ts
339
- var V2_HEADERS = {
340
- PAYMENT_SIGNATURE: "PAYMENT-SIGNATURE",
341
- PAYMENT_REQUIRED: "PAYMENT-REQUIRED",
342
- PAYMENT_RESPONSE: "PAYMENT-RESPONSE"
343
- };
344
- function isCAIP2ChainId(value) {
345
- return /^eip155:\d+$/.test(value);
346
- }
347
- function isCAIPAssetId(value) {
348
- return /^eip155:\d+\/erc20:0x[a-fA-F0-9]+$/.test(value);
349
- }
350
- function isAddress(value) {
351
- return /^0x[a-fA-F0-9]{40}$/.test(value);
352
- }
353
- function isPaymentRequiredV2(obj) {
354
- return typeof obj === "object" && obj !== null && "x402Version" in obj && obj.x402Version === 2 && "resource" in obj && "accepts" in obj && Array.isArray(obj.accepts);
355
- }
356
- function isPaymentPayloadV2(obj) {
357
- return typeof obj === "object" && obj !== null && "x402Version" in obj && obj.x402Version === 2 && "accepted" in obj && "payload" in obj;
358
- }
359
- function assetIdToAddress(assetId) {
360
- const match = assetId.match(/\/erc20:(0x[a-fA-F0-9]{40})$/);
361
- if (!match) throw new Error(`Invalid CAIP asset ID: ${assetId}`);
362
- return match[1];
363
- }
364
- function addressToAssetId(address, chainId) {
365
- const chain = typeof chainId === "number" ? `eip155:${chainId}` : chainId;
366
- if (!isCAIP2ChainId(chain)) throw new Error(`Invalid chain ID: ${chain}`);
367
- return `${chain}/erc20:${address}`;
368
- }
369
- function parseSignature(signature) {
370
- const sig = signature.slice(2);
371
- return {
372
- r: `0x${sig.slice(0, 64)}`,
373
- s: `0x${sig.slice(64, 128)}`,
374
- v: parseInt(sig.slice(128, 130), 16)
375
- };
376
- }
377
- function combineSignature(v, r, s) {
378
- const rClean = r.startsWith("0x") ? r.slice(2) : r;
379
- const sClean = s.startsWith("0x") ? s.slice(2) : s;
380
- const vHex = v.toString(16).padStart(2, "0");
381
- return `0x${rClean}${sClean}${vHex}`;
382
- }
383
-
384
315
  // src/types/protocol.ts
385
- function isX402V1Payload(obj) {
386
- return typeof obj === "object" && obj !== null && "x402Version" in obj && obj.x402Version === 1 && "scheme" in obj && "network" in obj && "payload" in obj;
387
- }
388
316
  function isX402V2Payload(obj) {
389
- return typeof obj === "object" && obj !== null && "x402Version" in obj && obj.x402Version === 2 && "accepted" in obj && "payload" in obj;
390
- }
391
- function isLegacyV1Payload(obj) {
392
- return typeof obj === "object" && obj !== null && "v" in obj && "r" in obj && "s" in obj && "chainId" in obj && "contractAddress" in obj && !("x402Version" in obj);
317
+ return typeof obj === "object" && obj !== null && "x402Version" in obj && obj.x402Version === 2 && "signature" in obj && "chainId" in obj && "assetId" in obj;
393
318
  }
394
319
  function isLegacyV2Payload(obj) {
395
320
  if (typeof obj !== "object" || obj === null) return false;
@@ -397,71 +322,29 @@ function isLegacyV2Payload(obj) {
397
322
  const signature = record.signature;
398
323
  return "signature" in record && typeof signature === "object" && signature !== null && "v" in signature && "chainId" in record && typeof record.chainId === "string" && record.chainId.startsWith("eip155:") && "assetId" in record && !("x402Version" in record);
399
324
  }
400
- function getPaymentVersion(payload) {
401
- if (isX402V1Payload(payload)) return 1;
402
- if (isX402V2Payload(payload)) return 2;
403
- return 1;
404
- }
405
- function isX402V1Requirements(obj) {
406
- return typeof obj === "object" && obj !== null && "scheme" in obj && "network" in obj && typeof obj.network === "string" && !obj.network.includes(":") && // Not CAIP-2 format
407
- "maxAmountRequired" in obj;
408
- }
409
325
  function isX402V2Requirements(obj) {
410
- return typeof obj === "object" && obj !== null && "scheme" in obj && "network" in obj && typeof obj.network === "string" && obj.network.startsWith("eip155:") && // CAIP-2 format
411
- "amount" in obj;
412
- }
413
- function getRequirementsVersion(requirements) {
414
- if (isX402V1Requirements(requirements)) return 1;
415
- if (isX402V2Requirements(requirements)) return 2;
416
- return 1;
417
- }
418
- function isX402V1Settlement(obj) {
419
- return typeof obj === "object" && obj !== null && "success" in obj && "network" in obj && typeof obj.network === "string" && !obj.network.includes(":");
326
+ return typeof obj === "object" && obj !== null && "scheme" in obj && obj.scheme === "exact" && "network" in obj && typeof obj.network === "string" && obj.network.startsWith("eip155:") && // CAIP-2 format
327
+ "amount" in obj && "asset" in obj && "payTo" in obj && "maxTimeoutSeconds" in obj;
420
328
  }
421
329
  function isX402V2Settlement(obj) {
422
- return typeof obj === "object" && obj !== null && "success" in obj && "network" in obj && typeof obj.network === "string" && obj.network.startsWith("eip155:");
423
- }
424
- function getSettlementVersion(response) {
425
- if (isX402V1Settlement(response)) return 1;
426
- if (isX402V2Settlement(response)) return 2;
427
- return 1;
428
- }
429
- function isX402V1PaymentRequired(obj) {
430
- return typeof obj === "object" && obj !== null && "x402Version" in obj && obj.x402Version === 1 && "accepts" in obj;
330
+ return typeof obj === "object" && obj !== null && "success" in obj && typeof obj.success === "boolean" && "network" in obj && typeof obj.network === "string" && obj.network.startsWith("eip155:");
431
331
  }
432
332
  function isX402V2PaymentRequired(obj) {
433
333
  return typeof obj === "object" && obj !== null && "x402Version" in obj && obj.x402Version === 2 && "resource" in obj && "accepts" in obj;
434
334
  }
435
- function getPaymentRequiredVersion(obj) {
436
- if (isX402V1PaymentRequired(obj)) return 1;
437
- if (isX402V2PaymentRequired(obj)) return 2;
438
- return 1;
439
- }
440
- function getPaymentHeaderName(version) {
441
- return version === 1 ? "X-PAYMENT" : "PAYMENT-SIGNATURE";
442
- }
443
- function getPaymentResponseHeaderName(version) {
444
- return version === 1 ? "X-PAYMENT-RESPONSE" : "PAYMENT-RESPONSE";
445
- }
446
- function getPaymentRequiredHeaderName(version) {
447
- return version === 1 ? "X-PAYMENT-REQUIRED" : "PAYMENT-REQUIRED";
448
- }
335
+ var PAYMENT_SIGNATURE_HEADER = "PAYMENT-SIGNATURE";
336
+ var PAYMENT_RESPONSE_HEADER = "PAYMENT-RESPONSE";
337
+ var PAYMENT_REQUIRED_HEADER = "PAYMENT-REQUIRED";
449
338
  function isSettlementSuccessful(response) {
450
339
  return "success" in response ? response.success : false;
451
340
  }
452
341
  function getTxHash(response) {
453
342
  if ("transaction" in response) return response.transaction;
454
- if ("txHash" in response) return response.txHash;
455
343
  return void 0;
456
344
  }
457
- function isV1(obj) {
458
- return isX402V1Payload(obj) || isLegacyV1Payload(obj);
459
- }
460
- function isV2(obj) {
461
- return isX402V2Payload(obj) || isLegacyV2Payload(obj);
462
- }
463
345
 
464
346
  // src/types/networks.ts
347
+ var isEvmAddress = (value) => /^0x[a-fA-F0-9]{40}$/.test(value);
465
348
  var tokenRegistry = /* @__PURE__ */ new Map();
466
349
  var tokenKey = (chainId, contractAddress) => `${chainId}:${contractAddress.toLowerCase()}`;
467
350
  var NETWORKS = {
@@ -519,8 +402,38 @@ var getNetworkByChainId = (chainId) => Object.values(NETWORKS).find((c) => c.cha
519
402
  var getMainnets = () => Object.values(NETWORKS).filter((c) => !c.name.toLowerCase().includes("sepolia"));
520
403
  var getTestnets = () => Object.values(NETWORKS).filter((c) => c.name.toLowerCase().includes("sepolia"));
521
404
  var registerToken = (token) => {
522
- tokenRegistry.set(tokenKey(token.chainId, token.contractAddress), token);
523
- return token;
405
+ if (typeof token !== "object" || token === null) {
406
+ throw new Error("Invalid token: must be an object");
407
+ }
408
+ const t = token;
409
+ if (typeof t.symbol !== "string") {
410
+ throw new Error("Invalid token: symbol must be a string");
411
+ }
412
+ if (typeof t.name !== "string") {
413
+ throw new Error("Invalid token: name must be a string");
414
+ }
415
+ if (typeof t.version !== "string") {
416
+ throw new Error("Invalid token: version must be a string");
417
+ }
418
+ if (typeof t.contractAddress !== "string" || !isEvmAddress(t.contractAddress)) {
419
+ throw new Error("Invalid token: contractAddress must be a valid EVM address");
420
+ }
421
+ if (typeof t.chainId !== "number" || !Number.isInteger(t.chainId) || t.chainId <= 0) {
422
+ throw new Error("Invalid token: chainId must be a positive integer");
423
+ }
424
+ if (t.decimals !== void 0 && (typeof t.decimals !== "number" || !Number.isInteger(t.decimals) || t.decimals < 0)) {
425
+ throw new Error("Invalid token: decimals must be a non-negative integer");
426
+ }
427
+ const validated = {
428
+ symbol: t.symbol,
429
+ name: t.name,
430
+ version: t.version,
431
+ contractAddress: t.contractAddress,
432
+ chainId: t.chainId,
433
+ decimals: t.decimals
434
+ };
435
+ tokenRegistry.set(tokenKey(validated.chainId, validated.contractAddress), validated);
436
+ return validated;
524
437
  };
525
438
  var getCustomToken = (chainId, contractAddress) => tokenRegistry.get(tokenKey(chainId, contractAddress));
526
439
  var getAllCustomTokens = () => Array.from(tokenRegistry.values());
@@ -628,6 +541,7 @@ var validateTransferWithAuthorization = (message) => {
628
541
  };
629
542
 
630
543
  // src/validation.ts
544
+ var isEvmAddress2 = (value) => /^0x[a-fA-F0-9]{40}$/.test(value);
631
545
  var createError = (code, message, details) => ({
632
546
  code,
633
547
  message,
@@ -699,7 +613,6 @@ var resolveNetwork = (input) => {
699
613
  };
700
614
  var getAvailableNetworks = () => Object.keys(NETWORKS);
701
615
  var normalizeTokenSymbol = (symbol) => symbol.toUpperCase();
702
- var isEvmAddress = (value) => /^0x[a-fA-F0-9]{40}$/.test(value);
703
616
  var resolveToken = (input, network) => {
704
617
  if (typeof input === "object" && input !== null && "contractAddress" in input) {
705
618
  const config = input;
@@ -726,7 +639,7 @@ var resolveToken = (input, network) => {
726
639
  };
727
640
  }
728
641
  if (typeof input === "string") {
729
- if (isEvmAddress(input)) {
642
+ if (isEvmAddress2(input)) {
730
643
  const contractAddress = input;
731
644
  if (network) {
732
645
  const customToken = getCustomToken(network.config.chainId, contractAddress);
@@ -800,7 +713,7 @@ var resolveToken = (input, network) => {
800
713
  if (network) {
801
714
  const customTokens2 = getAllCustomTokens();
802
715
  const matchingToken2 = customTokens2.find(
803
- (t) => t.symbol.toUpperCase() === normalizedSymbol && t.chainId === network.config.chainId
716
+ (t) => t.symbol?.toUpperCase() === normalizedSymbol && t.chainId === network.config.chainId
804
717
  );
805
718
  if (matchingToken2) {
806
719
  return {
@@ -825,7 +738,7 @@ var resolveToken = (input, network) => {
825
738
  };
826
739
  }
827
740
  const customTokens = getAllCustomTokens();
828
- const matchingToken = customTokens.find((t) => t.symbol.toUpperCase() === normalizedSymbol);
741
+ const matchingToken = customTokens.find((t) => t.symbol?.toUpperCase() === normalizedSymbol);
829
742
  if (matchingToken) {
830
743
  const tokenNetwork = resolveNetwork(matchingToken.chainId);
831
744
  if ("code" in tokenNetwork) {
@@ -966,13 +879,13 @@ var validatePaymentConfig = (network, token, facilitators, payTo = "0x0000000000
966
879
  network: resolvedNetwork,
967
880
  token: resolvedToken,
968
881
  facilitators: resolvedFacilitators,
969
- version: "auto",
882
+ version: 2,
970
883
  payTo,
971
884
  amount
972
885
  };
973
886
  };
974
887
  var validateAcceptConfig = (options, payTo, amount) => {
975
- const { networks: networkInputs, tokens: tokenInputs, facilitators, version = "auto" } = options;
888
+ const { networks: networkInputs, tokens: tokenInputs, facilitators, version = 2 } = options;
976
889
  const networkIds = networkInputs?.length ? networkInputs : Object.keys(NETWORKS);
977
890
  const tokenIds = tokenInputs?.length ? tokenInputs : ["usdc"];
978
891
  const networks = [];
@@ -1043,53 +956,120 @@ var isResolvedToken = (value) => {
1043
956
  };
1044
957
 
1045
958
  // src/encoding.ts
1046
- var base64Encode = (data) => Buffer.from(JSON.stringify(data)).toString("base64");
1047
- var base64Decode = (encoded) => JSON.parse(Buffer.from(encoded, "base64").toString("utf-8"));
1048
959
  var jsonEncode = (data) => JSON.stringify(data);
1049
960
  var jsonDecode = (encoded) => JSON.parse(encoded);
1050
- var encodePaymentV1 = (payload) => base64Encode(payload);
1051
- var decodePaymentV1 = (encoded) => base64Decode(encoded);
1052
- var encodeSettlementV1 = (response) => base64Encode(response);
1053
- var decodeSettlementV1 = (encoded) => base64Decode(encoded);
1054
961
  var encodePaymentV2 = (payload) => jsonEncode(payload);
1055
962
  var decodePaymentV2 = (encoded) => jsonDecode(encoded);
1056
963
  var encodeSettlementV2 = (response) => jsonEncode(response);
1057
964
  var decodeSettlementV2 = (encoded) => jsonDecode(encoded);
1058
- var detectPaymentVersion2 = (headers) => {
1059
- if (headers.has(V1_HEADERS.PAYMENT)) return 1;
1060
- if (headers.has(V2_HEADERS.PAYMENT_SIGNATURE)) return 2;
1061
- return null;
1062
- };
1063
- var decodePayment2 = (headers) => {
1064
- const version = detectPaymentVersion2(headers);
1065
- if (version === null) {
1066
- throw new Error("No valid payment headers found. Expected X-PAYMENT (v1) or PAYMENT-SIGNATURE (v2)");
965
+ var isPaymentV2 = (payload) => "signature" in payload && typeof payload.signature === "object";
966
+ var isSettlementV2 = (response) => "status" in response;
967
+
968
+ // src/fixtures/payloads.ts
969
+ var TEST_PRIVATE_KEY = "0x0000000000000000000000000000000000000000000000000000000000000000001";
970
+ var TEST_PAYER_ADDRESS = "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1";
971
+ var TEST_PAY_TO_ADDRESS = "0x1234567890123456789012345678901234567890";
972
+ var TEST_CONTRACT_ADDRESS = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
973
+ var createV2Authorization = (nonce) => ({
974
+ from: TEST_PAYER_ADDRESS,
975
+ to: TEST_PAY_TO_ADDRESS,
976
+ value: "1000000",
977
+ validAfter: Math.floor(Date.now() / 1e3).toString(),
978
+ validBefore: (Math.floor(Date.now() / 1e3) + 3600).toString(),
979
+ nonce: `0x${Buffer.from(nonce).toString("hex").padStart(64, "0")}`
980
+ });
981
+ var createV2SchemePayload = (nonce) => ({
982
+ signature: `0x${"b".repeat(130)}`,
983
+ authorization: createV2Authorization(nonce)
984
+ });
985
+ var createX402V2Payload = (nonce) => ({
986
+ x402Version: 2,
987
+ scheme: "exact",
988
+ network: "eip155:84532",
989
+ payload: createV2SchemePayload(nonce ?? "test_v2_nonce"),
990
+ resource: {
991
+ url: "https://example.com/api/test",
992
+ description: "Test resource"
1067
993
  }
1068
- const headerName = version === 1 ? V1_HEADERS.PAYMENT : V2_HEADERS.PAYMENT_SIGNATURE;
1069
- const encoded = headers.get(headerName);
1070
- if (!encoded) throw new Error(`Header ${headerName} is empty`);
1071
- return version === 1 ? decodePaymentV1(encoded) : decodePaymentV2(encoded);
994
+ });
995
+ var createLegacyV2Payload = (nonce) => ({
996
+ from: TEST_PAYER_ADDRESS,
997
+ to: TEST_PAY_TO_ADDRESS,
998
+ amount: "1000000",
999
+ nonce: nonce ?? "test_legacy_v2_nonce",
1000
+ expiry: Math.floor(Date.now() / 1e3) + 3600,
1001
+ signature: {
1002
+ v: 27,
1003
+ r: `0x${"f".repeat(64)}`,
1004
+ s: `0x${"0".repeat(64)}`
1005
+ },
1006
+ chainId: "eip155:84532",
1007
+ assetId: `eip155:84532/erc20:${TEST_CONTRACT_ADDRESS.slice(2)}`
1008
+ });
1009
+ var INVALID_PAYLOADS = {
1010
+ missingFields: {},
1011
+ invalidAddress: {
1012
+ x402Version: 2,
1013
+ scheme: "exact",
1014
+ network: "eip155:84532",
1015
+ payload: {
1016
+ signature: `0x${"i".repeat(130)}`,
1017
+ authorization: {
1018
+ from: "not-an-address",
1019
+ to: TEST_PAY_TO_ADDRESS,
1020
+ value: "1000000",
1021
+ validAfter: Math.floor(Date.now() / 1e3).toString(),
1022
+ validBefore: (Math.floor(Date.now() / 1e3) + 3600).toString(),
1023
+ nonce: `0x${"1".repeat(64)}`
1024
+ }
1025
+ }
1026
+ },
1027
+ expired: (() => {
1028
+ const payload = createX402V2Payload("test_expired_nonce");
1029
+ payload.payload.authorization.validBefore = (Math.floor(Date.now() / 1e3) - 100).toString();
1030
+ return payload;
1031
+ })(),
1032
+ malformedSignature: (() => {
1033
+ const payload = createX402V2Payload("test_malformed_sig_nonce");
1034
+ payload.payload.signature = "not-hex";
1035
+ return payload;
1036
+ })()
1072
1037
  };
1073
- var decodeSettlement = (headers) => {
1074
- const v1Response = headers.get(V1_HEADERS.PAYMENT_RESPONSE);
1075
- if (v1Response) return decodeSettlementV1(v1Response);
1076
- const v2Response = headers.get(V2_HEADERS.PAYMENT_RESPONSE);
1077
- if (v2Response) return decodeSettlementV2(v2Response);
1078
- throw new Error("No valid settlement response headers found. Expected X-PAYMENT-RESPONSE (v1) or PAYMENT-RESPONSE (v2)");
1038
+
1039
+ // src/fixtures/config.ts
1040
+ var TEST_PRIVATE_KEY2 = process.env.TEST_PRIVATE_KEY || "0x0000000000000000000000000000000000000000000000000000000000000000000001";
1041
+ var TEST_PAY_TO_ADDRESS2 = "0x1234567890123456789012345678901234567890";
1042
+ var TEST_NETWORK = "base-sepolia";
1043
+ var TEST_AMOUNT_DECIMAL = "1.0";
1044
+ var FACILITATOR_URL = process.env.FACILITATOR_URL || "https://facilitator.payai.network";
1045
+ var TEST_RPC_URL = process.env.TEST_RPC_URL || "https://sepolia.base.org";
1046
+ var DEFAULT_PAYMENT_CONFIG = {
1047
+ payTo: TEST_PAY_TO_ADDRESS2,
1048
+ amount: TEST_AMOUNT_DECIMAL,
1049
+ network: TEST_NETWORK,
1050
+ defaultVersion: 2,
1051
+ accept: {
1052
+ networks: [TEST_NETWORK],
1053
+ tokens: ["usdc"],
1054
+ facilitators: [{ url: FACILITATOR_URL }]
1055
+ }
1079
1056
  };
1080
- var isPaymentV1 = (payload) => "v" in payload && typeof payload.v === "number";
1081
- var isPaymentV2 = (payload) => "signature" in payload && typeof payload.signature === "object";
1082
- var isSettlementV1 = (response) => "success" in response;
1083
- var isSettlementV2 = (response) => "status" in response;
1084
1057
  export {
1058
+ DEFAULT_PAYMENT_CONFIG,
1085
1059
  EIP712_TYPES,
1086
1060
  ERC20_ABI,
1061
+ INVALID_PAYLOADS,
1087
1062
  NETWORKS,
1063
+ PAYMENT_REQUIRED_HEADER,
1064
+ PAYMENT_RESPONSE_HEADER,
1065
+ PAYMENT_SIGNATURE_HEADER,
1088
1066
  SCHEMES,
1067
+ TEST_CONTRACT_ADDRESS,
1068
+ TEST_PAYER_ADDRESS,
1069
+ TEST_PAY_TO_ADDRESS,
1070
+ TEST_PRIVATE_KEY,
1089
1071
  USDC_DOMAIN,
1090
- V1_HEADERS,
1091
1072
  V2_HEADERS,
1092
- X402_HEADERS,
1093
1073
  X402_VERSION,
1094
1074
  addressToAssetId,
1095
1075
  assetIdToAddress,
@@ -1098,40 +1078,23 @@ export {
1098
1078
  combineSignature as combineSignatureV2,
1099
1079
  createEIP712Domain,
1100
1080
  createError,
1081
+ createLegacyV2Payload,
1101
1082
  createNonce,
1102
1083
  createPaymentRequiredHeaders,
1103
1084
  createSettlementHeaders,
1104
1085
  createTransferWithAuthorization,
1086
+ createX402V2Payload,
1105
1087
  decodePayment,
1106
- decodePayment2 as decodePaymentLegacy,
1107
- decodePaymentPayloadLegacy as decodePaymentPayload,
1108
- decodePaymentPayloadLegacy,
1109
- decodePaymentV1,
1110
1088
  decodePaymentV2,
1111
- decodeSettlement as decodeSettlementLegacy,
1112
1089
  decodeSettlementResponse,
1113
- decodeSettlementResponseLegacy,
1114
- decodeSettlementV1,
1115
1090
  decodeSettlementV2,
1116
- decodeX402PaymentPayloadV1,
1117
- decodeX402PaymentRequiredV1,
1118
1091
  decodeX402Response,
1119
- decodeX402SettlementResponseV1,
1120
1092
  detectPaymentVersion,
1121
- detectPaymentVersion2 as detectPaymentVersionLegacy,
1122
1093
  encodePayment,
1123
- encodePaymentPayloadLegacy as encodePaymentPayload,
1124
- encodePaymentPayloadLegacy,
1125
- encodePaymentV1,
1126
1094
  encodePaymentV2,
1127
1095
  encodeSettlementResponse,
1128
- encodeSettlementResponseLegacy,
1129
- encodeSettlementV1,
1130
1096
  encodeSettlementV2,
1131
- encodeX402PaymentPayloadV1,
1132
- encodeX402PaymentRequiredV1,
1133
1097
  encodeX402Response,
1134
- encodeX402SettlementResponseV1,
1135
1098
  extractPaymentFromHeaders,
1136
1099
  fromAtomicUnits,
1137
1100
  getAllCustomTokens,
@@ -1142,13 +1105,6 @@ export {
1142
1105
  getMainnets,
1143
1106
  getNetworkByChainId,
1144
1107
  getNetworkConfig,
1145
- getPaymentHeaderName,
1146
- getPaymentRequiredHeaderName,
1147
- getPaymentRequiredVersion,
1148
- getPaymentResponseHeaderName,
1149
- getPaymentVersion,
1150
- getRequirementsVersion,
1151
- getSettlementVersion,
1152
1108
  getTestnets,
1153
1109
  getTxHash,
1154
1110
  isAddress,
@@ -1156,30 +1112,18 @@ export {
1156
1112
  isCAIPAssetId,
1157
1113
  isCustomToken,
1158
1114
  isExactEvmPayload,
1159
- isLegacyPaymentPayloadV1,
1160
- isLegacyV1,
1161
- isLegacyV1Payload,
1162
1115
  isLegacyV2,
1116
+ isLegacyV2Payload,
1163
1117
  isPaymentPayload,
1164
1118
  isPaymentPayloadV2,
1165
1119
  isPaymentRequiredV2,
1166
- isPaymentV1,
1167
1120
  isPaymentV2,
1168
1121
  isResolvedNetwork,
1169
1122
  isResolvedToken,
1170
1123
  isSettlementSuccessful,
1171
- isSettlementV1,
1172
1124
  isSettlementV2,
1173
- isV1,
1174
- isV2,
1175
1125
  isValidAddress,
1176
1126
  isValidationError,
1177
- isX402PaymentPayloadV1,
1178
- isX402PaymentRequiredV1,
1179
- isX402V1Payload,
1180
- isX402V1PaymentRequired,
1181
- isX402V1Requirements,
1182
- isX402V1Settlement,
1183
1127
  isX402V2Payload,
1184
1128
  isX402V2PaymentRequired,
1185
1129
  isX402V2Requirements,