@armory-sh/base 0.2.21-alpha.3.16 → 0.2.21-alpha.3.17

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.
@@ -4,7 +4,7 @@
4
4
  * Payment payloads are JSON-encoded for transport in HTTP headers.
5
5
  * Matches the Coinbase x402 v2 SDK format.
6
6
  */
7
- import type { PaymentPayload, X402Response, PaymentPayloadV2, PaymentRequirements, SettlementResponse } from "../types/x402";
7
+ import type { PaymentPayload, X402Response, PaymentRequirements, SettlementResponse } from "../types/x402";
8
8
  /**
9
9
  * Safe Base64 encode (URL-safe, no padding)
10
10
  */
@@ -16,7 +16,7 @@ export declare function safeBase64Decode(str: string): string;
16
16
  /**
17
17
  * Encode payment payload to JSON string
18
18
  */
19
- export declare function encodePayment(payload: PaymentPayload | PaymentPayloadV2): string;
19
+ export declare function encodePayment(payload: PaymentPayload): string;
20
20
  /**
21
21
  * Decode payment payload from JSON string
22
22
  */
@@ -56,10 +56,6 @@ export declare function createPaymentRequiredHeaders(requirements: PaymentRequir
56
56
  * Create settlement response headers (V2 format)
57
57
  */
58
58
  export declare function createSettlementHeaders(settlement: SettlementResponse): Record<string, string>;
59
- /**
60
- * Type guard for legacy V2 payload (without x402Version)
61
- */
62
- export declare function isLegacyV2(payload: unknown): payload is PaymentPayloadV2;
63
59
  /**
64
60
  * Decode settlement from headers (V2 only)
65
61
  */
@@ -1,13 +1,12 @@
1
1
  /**
2
2
  * Mock Payment Payloads for Testing (V2 Only)
3
3
  */
4
- import type { X402PayloadV2, PaymentPayloadV2 } from "@armory-sh/base";
4
+ import type { PaymentPayloadV2 } from "@armory-sh/base";
5
5
  export declare const TEST_PRIVATE_KEY = "0x0000000000000000000000000000000000000000000000000000000000000000001";
6
6
  export declare const TEST_PAYER_ADDRESS = "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1";
7
7
  export declare const TEST_PAY_TO_ADDRESS = "0x1234567890123456789012345678901234567890";
8
8
  export declare const TEST_CONTRACT_ADDRESS = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
9
9
  export declare const createX402V2Payload: (nonce?: string) => PaymentPayloadV2;
10
- export declare const createLegacyV2Payload: (nonce?: string) => X402PayloadV2;
11
10
  export declare const INVALID_PAYLOADS: {
12
11
  readonly missingFields: {};
13
12
  readonly invalidAddress: PaymentPayloadV2;
package/dist/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- export type { Address as X402Address, Hex, X402Version, Scheme, Network as X402Network, ExactEvmAuthorization, ExactEvmPayload, PaymentPayload as X402PaymentPayload, UnsignedPaymentPayload as X402UnsignedPaymentPayload, PaymentRequirements as X402PaymentRequirements, SettlementResponse as X402SettlementResponse, VerifyResponse, X402Response, PaymentPayloadV2 as X402PayloadV2, LegacyPaymentPayload as X402LegacyPayload, } from "./types/x402";
2
- export { X402_VERSION, SCHEMES, isPaymentPayload, isExactEvmPayload, legacyToPaymentPayload, } from "./types/x402";
3
- export { safeBase64Encode, safeBase64Decode, encodePayment, decodePayment, encodeSettlementResponse, decodeSettlementResponse, encodeX402Response, decodeX402Response, detectPaymentVersion, extractPaymentFromHeaders, createPaymentRequiredHeaders, createSettlementHeaders, isLegacyV2, } from "./encoding/x402";
1
+ export type { Address as X402Address, Hex, X402Version, Scheme, Network as X402Network, ExactEvmAuthorization, ExactEvmPayload, PaymentPayload as X402PaymentPayload, UnsignedPaymentPayload as X402UnsignedPaymentPayload, PaymentRequirements as X402PaymentRequirements, SettlementResponse as X402SettlementResponse, VerifyResponse, X402Response, } from "./types/x402";
2
+ export { X402_VERSION, SCHEMES, isPaymentPayload, isExactEvmPayload, } from "./types/x402";
3
+ export { safeBase64Encode, safeBase64Decode, encodePayment, decodePayment, encodeSettlementResponse, decodeSettlementResponse, encodeX402Response, decodeX402Response, detectPaymentVersion, extractPaymentFromHeaders, createPaymentRequiredHeaders, createSettlementHeaders, } from "./encoding/x402";
4
4
  export { createNonce, toAtomicUnits, fromAtomicUnits, caip2ToNetwork, networkToCaip2, getCurrentTimestamp, isValidAddress, normalizeAddress, } from "./utils/x402";
5
5
  export type { CAIP2Network as CAIP2ChainId, CAIPAssetId, Address, Signature, PayToV2, Extensions, PaymentPayloadV2, PaymentRequirementsV2, SettlementResponseV2, PaymentRequiredV2, ResourceInfo, EIP3009Authorization, SchemePayloadV2, } from "./types/v2";
6
6
  export { V2_HEADERS, isCAIP2ChainId, isCAIPAssetId, isAddress, isPaymentRequiredV2, isPaymentPayloadV2, assetIdToAddress, addressToAssetId, parseSignature as parseSignatureV2, combineSignature as combineSignatureV2, } from "./types/v2";
7
7
  export type { PaymentPayload, PaymentRequirements, SettlementResponse, PaymentRequired, } from "./types/protocol";
8
- export { isX402V2Payload, isX402V2Requirements, isX402V2Settlement, isX402V2PaymentRequired, isLegacyV2Payload, isSettlementSuccessful, getTxHash, PAYMENT_SIGNATURE_HEADER, PAYMENT_RESPONSE_HEADER, PAYMENT_REQUIRED_HEADER, } from "./types/protocol";
8
+ export { isX402V2Payload, isX402V2Requirements, isX402V2Settlement, isX402V2PaymentRequired, isSettlementSuccessful, getTxHash, PAYMENT_SIGNATURE_HEADER, PAYMENT_RESPONSE_HEADER, PAYMENT_REQUIRED_HEADER, } from "./types/protocol";
9
9
  export type { NetworkConfig, CustomToken } from "./types/networks";
10
10
  export { NETWORKS, getNetworkConfig, getNetworkByChainId, getMainnets, getTestnets, registerToken, getCustomToken, getAllCustomTokens, unregisterToken, isCustomToken, } from "./types/networks";
11
11
  export { TOKENS, USDC_BASE, EURC_BASE, USDC_BASE_SEPOLIA, USDC_SKALE_BASE, SKL_SKALE_BASE, USDT_SKALE_BASE, WBTC_SKALE_BASE, WETH_SKALE_BASE, SKL_SKALE_BASE_SEPOLIA, USDC_SKALE_BASE_SEPOLIA, USDT_SKALE_BASE_SEPOLIA, WBTC_SKALE_BASE_SEPOLIA, WETH_SKALE_BASE_SEPOLIA, getToken, getAllTokens, getTokensBySymbol, getTokensByChain, getUSDCTokens, getEURCTokens, getSKLTokens, getUSDTTokens, getWBTCTokens, getWETHTokens, } from "./data/tokens";
@@ -19,5 +19,7 @@ export { parseRoutePattern, matchRoute, findMatchingRoute, validateRouteConfig,
19
19
  export { encodePaymentV2, decodePaymentV2, encodeSettlementV2, decodeSettlementV2, isPaymentV2, isSettlementV2, } from "./encoding";
20
20
  export type { NetworkId, TokenId, FacilitatorConfig, FacilitatorVerifyResult, FacilitatorSettleResult, SettlementMode, PayToAddress, AcceptPaymentOptions, PricingConfig, PaymentResult, PaymentError, PaymentErrorCode, ArmoryPaymentResult, ResolvedNetwork, ResolvedToken, ResolvedFacilitator, ResolvedPaymentConfig, ValidationError, } from "./types/api";
21
21
  export type { PaymentRequiredContext, PaymentPayloadContext, HookResult, OnPaymentRequiredHook, BeforePaymentHook, ExtensionHook, HookConfig, HookRegistry, } from "./types/hooks";
22
- export { createX402V2Payload, createLegacyV2Payload, INVALID_PAYLOADS, TEST_PAYER_ADDRESS, TEST_PAY_TO_ADDRESS, TEST_CONTRACT_ADDRESS, TEST_PRIVATE_KEY, } from "./fixtures/payloads";
22
+ export type { FacilitatorClientConfig, SupportedKind, SupportedResponse, } from "./payment-client";
23
+ export { verifyPayment, settlePayment, getSupported, decodePayloadHeader, extractPayerAddress, } from "./payment-client";
24
+ export { createX402V2Payload, INVALID_PAYLOADS, TEST_PAYER_ADDRESS, TEST_PAY_TO_ADDRESS, TEST_CONTRACT_ADDRESS, TEST_PRIVATE_KEY, } from "./fixtures/payloads";
23
25
  export { DEFAULT_PAYMENT_CONFIG, type TestPaymentConfig } from "./fixtures/config";
package/dist/index.js CHANGED
@@ -1,110 +1,14 @@
1
1
  import { randomBytes } from 'crypto';
2
2
 
3
3
  // src/types/x402.ts
4
- var X402_VERSION = 1;
4
+ var X402_VERSION = 2;
5
5
  var SCHEMES = ["exact"];
6
- var CHAIN_ID_TO_NETWORK = {
7
- 1: "ethereum",
8
- 8453: "base",
9
- 84532: "base-sepolia",
10
- 137: "polygon",
11
- 42161: "arbitrum",
12
- 421614: "arbitrum-sepolia",
13
- 10: "optimism",
14
- 11155420: "optimism-sepolia",
15
- 11155111: "ethereum-sepolia"
16
- };
17
6
  function isPaymentPayload(obj) {
18
7
  return typeof obj === "object" && obj !== null && "x402Version" in obj && "scheme" in obj && "network" in obj && "payload" in obj;
19
8
  }
20
9
  function isExactEvmPayload(obj) {
21
10
  return typeof obj === "object" && obj !== null && "signature" in obj && "authorization" in obj;
22
11
  }
23
- function extractNetworkFromLegacy(legacy) {
24
- if ("network" in legacy && typeof legacy.network === "string") {
25
- return legacy.network;
26
- }
27
- if ("chainId" in legacy && typeof legacy.chainId === "string") {
28
- const match = legacy.chainId.match(/^eip155:(\d+)$/);
29
- if (match) {
30
- const chainId = parseInt(match[1], 10);
31
- return CHAIN_ID_TO_NETWORK[chainId] || `eip155:${chainId}`;
32
- }
33
- }
34
- if ("chainId" in legacy && typeof legacy.chainId === "number") {
35
- return CHAIN_ID_TO_NETWORK[legacy.chainId] || `eip155:${legacy.chainId}`;
36
- }
37
- return "base";
38
- }
39
- function extractSignatureFromLegacy(legacy) {
40
- if ("v" in legacy && "r" in legacy && "s" in legacy) {
41
- const v = legacy.v.toString(16).padStart(2, "0");
42
- const r = legacy.r.startsWith("0x") ? legacy.r.slice(2) : legacy.r;
43
- const s = legacy.s.startsWith("0x") ? legacy.s.slice(2) : legacy.s;
44
- return `0x${r}${s}${v}`;
45
- }
46
- if ("signature" in legacy && typeof legacy.signature === "object" && legacy.signature !== null) {
47
- const sig = legacy.signature;
48
- const v = sig.v.toString(16).padStart(2, "0");
49
- const r = sig.r.startsWith("0x") ? sig.r.slice(2) : sig.r;
50
- const s = sig.s.startsWith("0x") ? sig.s.slice(2) : sig.s;
51
- return `0x${r}${s}${v}`;
52
- }
53
- return "0x";
54
- }
55
- function convertAmountToAtomic(amount) {
56
- if (amount.includes(".")) {
57
- const parts = amount.split(".");
58
- const whole = parts[0];
59
- const fractional = parts[1] || "";
60
- const paddedFractional = fractional.padEnd(6, "0").slice(0, 6);
61
- return `${whole}${paddedFractional}`;
62
- }
63
- return amount;
64
- }
65
- function convertNonceToHex(nonce) {
66
- if (nonce.startsWith("0x") && nonce.length === 66) {
67
- return nonce;
68
- }
69
- const hex = BigInt(nonce).toString(16).padStart(64, "0");
70
- return `0x${hex}`;
71
- }
72
- function extractFromAddress(legacy) {
73
- return legacy.from;
74
- }
75
- function extractToAddress(legacy) {
76
- if ("to" in legacy && typeof legacy.to === "string") {
77
- return legacy.to;
78
- }
79
- return legacy.from;
80
- }
81
- function legacyToPaymentPayload(legacy) {
82
- if (isPaymentPayload(legacy)) {
83
- return legacy;
84
- }
85
- const network = extractNetworkFromLegacy(legacy);
86
- const signature = extractSignatureFromLegacy(legacy);
87
- const value = convertAmountToAtomic(legacy.amount);
88
- const nonce = convertNonceToHex(legacy.nonce);
89
- const from = extractFromAddress(legacy);
90
- const to = extractToAddress(legacy);
91
- return {
92
- x402Version: X402_VERSION,
93
- scheme: "exact",
94
- network,
95
- payload: {
96
- signature,
97
- authorization: {
98
- from,
99
- to,
100
- value,
101
- validAfter: "0",
102
- validBefore: legacy.expiry.toString(),
103
- nonce
104
- }
105
- }
106
- };
107
- }
108
12
 
109
13
  // src/types/v2.ts
110
14
  var V2_HEADERS = {
@@ -165,13 +69,10 @@ function safeBase64Decode(str) {
165
69
  return Buffer.from(str, "base64").toString("utf-8");
166
70
  }
167
71
  function encodePayment(payload) {
168
- let normalizedPayload;
169
- if (isPaymentPayload(payload)) {
170
- normalizedPayload = payload;
171
- } else {
172
- normalizedPayload = legacyToPaymentPayload(payload);
72
+ if (!isPaymentPayload(payload)) {
73
+ throw new Error("Invalid payment payload format");
173
74
  }
174
- const safePayload = JSON.parse(JSON.stringify(normalizedPayload, (_, value) => {
75
+ const safePayload = JSON.parse(JSON.stringify(payload, (_, value) => {
175
76
  if (typeof value === "bigint") {
176
77
  return value.toString();
177
78
  }
@@ -180,10 +81,15 @@ function encodePayment(payload) {
180
81
  return safeBase64Encode(JSON.stringify(safePayload));
181
82
  }
182
83
  function decodePayment(encoded) {
183
- const decoded = safeBase64Decode(encoded);
184
- const parsed = JSON.parse(decoded);
84
+ let parsed;
85
+ try {
86
+ parsed = JSON.parse(encoded);
87
+ } catch {
88
+ const decoded = safeBase64Decode(encoded);
89
+ parsed = JSON.parse(decoded);
90
+ }
185
91
  if (!isPaymentPayload(parsed)) {
186
- return legacyToPaymentPayload(parsed);
92
+ throw new Error("Invalid payment payload format");
187
93
  }
188
94
  return parsed;
189
95
  }
@@ -197,15 +103,23 @@ function encodeSettlementResponse(response) {
197
103
  return safeBase64Encode(JSON.stringify(safeResponse));
198
104
  }
199
105
  function decodeSettlementResponse(encoded) {
200
- const decoded = safeBase64Decode(encoded);
201
- return JSON.parse(decoded);
106
+ try {
107
+ return JSON.parse(encoded);
108
+ } catch {
109
+ const decoded = safeBase64Decode(encoded);
110
+ return JSON.parse(decoded);
111
+ }
202
112
  }
203
113
  function encodeX402Response(response) {
204
114
  return safeBase64Encode(JSON.stringify(response));
205
115
  }
206
116
  function decodeX402Response(encoded) {
207
- const decoded = safeBase64Decode(encoded);
208
- return JSON.parse(decoded);
117
+ try {
118
+ return JSON.parse(encoded);
119
+ } catch {
120
+ const decoded = safeBase64Decode(encoded);
121
+ return JSON.parse(decoded);
122
+ }
209
123
  }
210
124
  function detectPaymentVersion(headers) {
211
125
  if (headers.has("PAYMENT-SIGNATURE")) {
@@ -237,9 +151,6 @@ function createSettlementHeaders(settlement) {
237
151
  [V2_HEADERS.PAYMENT_RESPONSE]: encodeSettlementResponse(settlement)
238
152
  };
239
153
  }
240
- function isLegacyV2(payload) {
241
- return typeof payload === "object" && payload !== null && "signature" in payload && typeof payload.signature === "object";
242
- }
243
154
  function createNonce() {
244
155
  const bytes = randomBytes(32);
245
156
  return `0x${bytes.toString("hex")}`;
@@ -315,12 +226,6 @@ function normalizeAddress(address) {
315
226
  function isX402V2Payload(obj) {
316
227
  return typeof obj === "object" && obj !== null && "x402Version" in obj && obj.x402Version === 2 && "signature" in obj && "chainId" in obj && "assetId" in obj;
317
228
  }
318
- function isLegacyV2Payload(obj) {
319
- if (typeof obj !== "object" || obj === null) return false;
320
- const record = obj;
321
- const signature = record.signature;
322
- 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);
323
- }
324
229
  function isX402V2Requirements(obj) {
325
230
  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
326
231
  "amount" in obj && "asset" in obj && "payTo" in obj && "maxTimeoutSeconds" in obj;
@@ -1291,6 +1196,131 @@ var decodeSettlementV2 = (encoded) => base64JsonDecode(encoded);
1291
1196
  var isPaymentV2 = (payload) => "signature" in payload && typeof payload.signature === "object";
1292
1197
  var isSettlementV2 = (response) => "status" in response;
1293
1198
 
1199
+ // src/payment-client.ts
1200
+ var DEFAULT_FACILITATOR_URL = "https://facilitator.payai.network";
1201
+ function toJsonSafe(data) {
1202
+ function convert(value) {
1203
+ if (value !== null && typeof value === "object" && !Array.isArray(value)) {
1204
+ return Object.fromEntries(Object.entries(value).map(([key, val]) => [key, convert(val)]));
1205
+ }
1206
+ if (Array.isArray(value)) {
1207
+ return value.map(convert);
1208
+ }
1209
+ if (typeof value === "bigint") {
1210
+ return value.toString();
1211
+ }
1212
+ return value;
1213
+ }
1214
+ return convert(data);
1215
+ }
1216
+ function resolveUrl(config) {
1217
+ return config?.url ?? DEFAULT_FACILITATOR_URL;
1218
+ }
1219
+ async function resolveHeaders(config) {
1220
+ const base = { "Content-Type": "application/json" };
1221
+ if (!config?.createHeaders) return base;
1222
+ const extra = await config.createHeaders();
1223
+ return { ...base, ...extra };
1224
+ }
1225
+ async function verifyPayment(payload, requirements, config) {
1226
+ const url = resolveUrl(config);
1227
+ const headers = await resolveHeaders(config);
1228
+ const response = await fetch(`${url}/verify`, {
1229
+ method: "POST",
1230
+ headers,
1231
+ body: JSON.stringify({
1232
+ x402Version: payload.x402Version,
1233
+ paymentPayload: toJsonSafe(payload),
1234
+ paymentRequirements: toJsonSafe(requirements)
1235
+ })
1236
+ });
1237
+ if (response.status !== 200) {
1238
+ const text = await response.text().catch(() => response.statusText);
1239
+ throw new Error(`Facilitator verify failed: ${response.status} ${text}`);
1240
+ }
1241
+ return await response.json();
1242
+ }
1243
+ async function settlePayment(payload, requirements, config) {
1244
+ const url = resolveUrl(config);
1245
+ const headers = await resolveHeaders(config);
1246
+ const response = await fetch(`${url}/settle`, {
1247
+ method: "POST",
1248
+ headers,
1249
+ body: JSON.stringify({
1250
+ x402Version: payload.x402Version,
1251
+ paymentPayload: toJsonSafe(payload),
1252
+ paymentRequirements: toJsonSafe(requirements)
1253
+ })
1254
+ });
1255
+ if (response.status !== 200) {
1256
+ const text = await response.text().catch(() => response.statusText);
1257
+ throw new Error(`Facilitator settle failed: ${response.status} ${text}`);
1258
+ }
1259
+ return await response.json();
1260
+ }
1261
+ async function getSupported(config) {
1262
+ const url = resolveUrl(config);
1263
+ const headers = await resolveHeaders(config);
1264
+ const response = await fetch(`${url}/supported`, {
1265
+ method: "GET",
1266
+ headers
1267
+ });
1268
+ if (response.status !== 200) {
1269
+ throw new Error(`Facilitator supported failed: ${response.statusText}`);
1270
+ }
1271
+ return await response.json();
1272
+ }
1273
+ function tryParseHeaderJson(headerValue) {
1274
+ if (headerValue.startsWith("{")) {
1275
+ return JSON.parse(headerValue);
1276
+ }
1277
+ const normalized = headerValue.replace(/-/g, "+").replace(/_/g, "/").padEnd(Math.ceil(headerValue.length / 4) * 4, "=");
1278
+ return JSON.parse(Buffer.from(normalized, "base64").toString("utf-8"));
1279
+ }
1280
+ function isCompactV2Payload(payload) {
1281
+ if (typeof payload !== "object" || payload === null) return false;
1282
+ const record = payload;
1283
+ return typeof record.x402Version === "number" && "payload" in record;
1284
+ }
1285
+ function decodePayloadHeader(headerValue, defaults) {
1286
+ if (headerValue.startsWith("{")) {
1287
+ const parsed = JSON.parse(headerValue);
1288
+ if (isPaymentPayload(parsed)) return parsed;
1289
+ if (isCompactV2Payload(parsed)) {
1290
+ const compact = parsed;
1291
+ return {
1292
+ x402Version: 2,
1293
+ scheme: defaults?.scheme ?? "exact",
1294
+ network: defaults?.network ?? "base",
1295
+ payload: compact.payload
1296
+ };
1297
+ }
1298
+ throw new Error("Invalid payment payload: unrecognized format");
1299
+ }
1300
+ try {
1301
+ return decodePayment(headerValue);
1302
+ } catch {
1303
+ const parsed = tryParseHeaderJson(headerValue);
1304
+ if (isPaymentPayload(parsed)) return parsed;
1305
+ if (isCompactV2Payload(parsed)) {
1306
+ const compact = parsed;
1307
+ return {
1308
+ x402Version: 2,
1309
+ scheme: defaults?.scheme ?? "exact",
1310
+ network: defaults?.network ?? "base",
1311
+ payload: compact.payload
1312
+ };
1313
+ }
1314
+ throw new Error("Invalid payment payload: unrecognized format");
1315
+ }
1316
+ }
1317
+ function extractPayerAddress(payload) {
1318
+ if (isExactEvmPayload(payload.payload)) {
1319
+ return payload.payload.authorization.from;
1320
+ }
1321
+ throw new Error("Unable to extract payer address from payload");
1322
+ }
1323
+
1294
1324
  // src/fixtures/payloads.ts
1295
1325
  var TEST_PRIVATE_KEY = "0x0000000000000000000000000000000000000000000000000000000000000000001";
1296
1326
  var TEST_PAYER_ADDRESS = "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1";
@@ -1318,20 +1348,6 @@ var createX402V2Payload = (nonce) => ({
1318
1348
  description: "Test resource"
1319
1349
  }
1320
1350
  });
1321
- var createLegacyV2Payload = (nonce) => ({
1322
- from: TEST_PAYER_ADDRESS,
1323
- to: TEST_PAY_TO_ADDRESS,
1324
- amount: "1000000",
1325
- nonce: nonce ?? "test_legacy_v2_nonce",
1326
- expiry: Math.floor(Date.now() / 1e3) + 3600,
1327
- signature: {
1328
- v: 27,
1329
- r: `0x${"f".repeat(64)}`,
1330
- s: `0x${"0".repeat(64)}`
1331
- },
1332
- chainId: "eip155:84532",
1333
- assetId: `eip155:84532/erc20:${TEST_CONTRACT_ADDRESS.slice(2)}`
1334
- });
1335
1351
  var INVALID_PAYLOADS = {
1336
1352
  missingFields: {},
1337
1353
  invalidAddress: {
@@ -1381,4 +1397,4 @@ var DEFAULT_PAYMENT_CONFIG = {
1381
1397
  }
1382
1398
  };
1383
1399
 
1384
- export { DEFAULT_PAYMENT_CONFIG, EIP712_TYPES, ERC20_ABI, EURC_BASE, INVALID_PAYLOADS, NETWORKS, PAYMENT_REQUIRED_HEADER, PAYMENT_RESPONSE_HEADER, PAYMENT_SIGNATURE_HEADER, SCHEMES, SKL_SKALE_BASE, SKL_SKALE_BASE_SEPOLIA, TEST_CONTRACT_ADDRESS, TEST_PAYER_ADDRESS, TEST_PAY_TO_ADDRESS, TEST_PRIVATE_KEY, TOKENS, USDC_BASE, USDC_BASE_SEPOLIA, USDC_DOMAIN, USDC_SKALE_BASE, USDC_SKALE_BASE_SEPOLIA, USDT_SKALE_BASE, USDT_SKALE_BASE_SEPOLIA, V2_HEADERS, WBTC_SKALE_BASE, WBTC_SKALE_BASE_SEPOLIA, WETH_SKALE_BASE, WETH_SKALE_BASE_SEPOLIA, X402_VERSION, addressToAssetId, assetIdToAddress, caip2ToNetwork, checkFacilitatorSupport, combineSignature as combineSignatureV2, createEIP712Domain, createError, createLegacyV2Payload, createNonce, createPaymentRequiredHeaders, createSettlementHeaders, createTransferWithAuthorization, createX402V2Payload, decodePayment, decodePaymentV2, decodeSettlementResponse, decodeSettlementV2, decodeX402Response, detectPaymentVersion, encodePayment, encodePaymentV2, encodeSettlementResponse, encodeSettlementV2, encodeX402Response, extractPaymentFromHeaders, findMatchingRoute, fromAtomicUnits, getAllCustomTokens, getAllTokens, getAvailableNetworks, getAvailableTokens, getCurrentTimestamp, getCustomToken, getEURCTokens, getMainnets, getNetworkByChainId, getNetworkConfig, getSKLTokens, getTestnets, getToken, getTokensByChain, getTokensBySymbol, getTxHash, getUSDCTokens, getUSDTTokens, getWBTCTokens, getWETHTokens, isAddress, isCAIP2ChainId, isCAIPAssetId, isCustomToken, isExactEvmPayload, isLegacyV2, isLegacyV2Payload, isPaymentPayload, isPaymentPayloadV2, isPaymentRequiredV2, isPaymentV2, isResolvedNetwork, isResolvedToken, isSettlementSuccessful, isSettlementV2, isValidAddress, isValidationError, isX402V2Payload, isX402V2PaymentRequired, isX402V2Requirements, isX402V2Settlement, legacyToPaymentPayload, matchRoute, networkToCaip2, normalizeAddress, normalizeNetworkName, parseRoutePattern, parseSignature as parseSignatureV2, registerToken, resolveFacilitator, resolveNetwork, resolveToken, safeBase64Decode, safeBase64Encode, toAtomicUnits, unregisterToken, validateAcceptConfig, validatePaymentConfig, validateRouteConfig, validateTransferWithAuthorization };
1400
+ export { DEFAULT_PAYMENT_CONFIG, EIP712_TYPES, ERC20_ABI, EURC_BASE, INVALID_PAYLOADS, NETWORKS, PAYMENT_REQUIRED_HEADER, PAYMENT_RESPONSE_HEADER, PAYMENT_SIGNATURE_HEADER, SCHEMES, SKL_SKALE_BASE, SKL_SKALE_BASE_SEPOLIA, TEST_CONTRACT_ADDRESS, TEST_PAYER_ADDRESS, TEST_PAY_TO_ADDRESS, TEST_PRIVATE_KEY, TOKENS, USDC_BASE, USDC_BASE_SEPOLIA, USDC_DOMAIN, USDC_SKALE_BASE, USDC_SKALE_BASE_SEPOLIA, USDT_SKALE_BASE, USDT_SKALE_BASE_SEPOLIA, V2_HEADERS, WBTC_SKALE_BASE, WBTC_SKALE_BASE_SEPOLIA, WETH_SKALE_BASE, WETH_SKALE_BASE_SEPOLIA, X402_VERSION, addressToAssetId, assetIdToAddress, caip2ToNetwork, checkFacilitatorSupport, combineSignature as combineSignatureV2, createEIP712Domain, createError, createNonce, createPaymentRequiredHeaders, createSettlementHeaders, createTransferWithAuthorization, createX402V2Payload, decodePayloadHeader, decodePayment, decodePaymentV2, decodeSettlementResponse, decodeSettlementV2, decodeX402Response, detectPaymentVersion, encodePayment, encodePaymentV2, encodeSettlementResponse, encodeSettlementV2, encodeX402Response, extractPayerAddress, extractPaymentFromHeaders, findMatchingRoute, fromAtomicUnits, getAllCustomTokens, getAllTokens, getAvailableNetworks, getAvailableTokens, getCurrentTimestamp, getCustomToken, getEURCTokens, getMainnets, getNetworkByChainId, getNetworkConfig, getSKLTokens, getSupported, getTestnets, getToken, getTokensByChain, getTokensBySymbol, getTxHash, getUSDCTokens, getUSDTTokens, getWBTCTokens, getWETHTokens, isAddress, isCAIP2ChainId, isCAIPAssetId, isCustomToken, isExactEvmPayload, isPaymentPayload, isPaymentPayloadV2, isPaymentRequiredV2, isPaymentV2, isResolvedNetwork, isResolvedToken, isSettlementSuccessful, isSettlementV2, isValidAddress, isValidationError, isX402V2Payload, isX402V2PaymentRequired, isX402V2Requirements, isX402V2Settlement, matchRoute, networkToCaip2, normalizeAddress, normalizeNetworkName, parseRoutePattern, parseSignature as parseSignatureV2, registerToken, resolveFacilitator, resolveNetwork, resolveToken, safeBase64Decode, safeBase64Encode, settlePayment, toAtomicUnits, unregisterToken, validateAcceptConfig, validatePaymentConfig, validateRouteConfig, validateTransferWithAuthorization, verifyPayment };
@@ -0,0 +1,24 @@
1
+ import type { PaymentPayload, PaymentRequirements, VerifyResponse, SettlementResponse } from "./types/x402";
2
+ export interface FacilitatorClientConfig {
3
+ url: string;
4
+ createHeaders?: () => Record<string, string> | Promise<Record<string, string>>;
5
+ }
6
+ export declare function verifyPayment(payload: PaymentPayload, requirements: PaymentRequirements, config?: FacilitatorClientConfig): Promise<VerifyResponse>;
7
+ export declare function settlePayment(payload: PaymentPayload, requirements: PaymentRequirements, config?: FacilitatorClientConfig): Promise<SettlementResponse>;
8
+ export interface SupportedKind {
9
+ x402Version: number;
10
+ scheme: string;
11
+ network: string;
12
+ extra?: Record<string, unknown>;
13
+ }
14
+ export interface SupportedResponse {
15
+ kinds: SupportedKind[];
16
+ }
17
+ interface DecodePayloadDefaults {
18
+ scheme?: string;
19
+ network?: string;
20
+ }
21
+ export declare function getSupported(config?: FacilitatorClientConfig): Promise<SupportedResponse>;
22
+ export declare function decodePayloadHeader(headerValue: string, defaults?: DecodePayloadDefaults): PaymentPayload;
23
+ export declare function extractPayerAddress(payload: PaymentPayload): string;
24
+ export {};
@@ -53,10 +53,6 @@ export type CAIPAssetId = `eip155:${string}/erc20:${string}`;
53
53
  * Check if payload is x402 V2 format (Coinbase format)
54
54
  */
55
55
  export declare function isX402V2Payload(obj: unknown): obj is PaymentPayloadV2;
56
- /**
57
- * Check if payload is legacy Armory V2 format
58
- */
59
- export declare function isLegacyV2Payload(obj: unknown): boolean;
60
56
  /**
61
57
  * Check if requirements is x402 V2 format
62
58
  */
@@ -6,7 +6,7 @@
6
6
  */
7
7
  export type Address = `0x${string}`;
8
8
  export type Hex = `0x${string}`;
9
- export declare const X402_VERSION: 1;
9
+ export declare const X402_VERSION: 2;
10
10
  export type X402Version = typeof X402_VERSION;
11
11
  export declare const SCHEMES: readonly ["exact"];
12
12
  export type Scheme = (typeof SCHEMES)[number];
@@ -92,44 +92,8 @@ export interface X402Response {
92
92
  accepts?: PaymentRequirements[];
93
93
  payer?: Address;
94
94
  }
95
- export interface PaymentPayloadV1 {
96
- from: string;
97
- to: string;
98
- amount: string;
99
- nonce: string;
100
- expiry: number;
101
- v: number;
102
- r: string;
103
- s: string;
104
- chainId: number;
105
- contractAddress: string;
106
- network: string;
107
- }
108
- export interface PaymentPayloadV2 {
109
- from: Address;
110
- to: Address | {
111
- role?: string;
112
- callback?: string;
113
- };
114
- amount: string;
115
- nonce: string;
116
- expiry: number;
117
- signature: {
118
- v: number;
119
- r: string;
120
- s: string;
121
- };
122
- chainId: `eip155:${string}`;
123
- assetId: `eip155:${string}/erc20:${string}`;
124
- extensions?: Record<string, unknown>;
125
- }
126
- export type LegacyPaymentPayload = PaymentPayloadV1 | PaymentPayloadV2;
127
95
  /**
128
96
  * Type guards
129
97
  */
130
98
  export declare function isPaymentPayload(obj: unknown): obj is PaymentPayload;
131
99
  export declare function isExactEvmPayload(obj: unknown): obj is ExactEvmPayload;
132
- /**
133
- * Convert legacy payload to new format
134
- */
135
- export declare function legacyToPaymentPayload(legacy: LegacyPaymentPayload | PaymentPayload): PaymentPayload;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@armory-sh/base",
3
- "version": "0.2.21-alpha.3.16",
3
+ "version": "0.2.21-alpha.3.17",
4
4
  "license": "MIT",
5
5
  "author": "Sawyer Cutler <sawyer@dirtroad.dev>",
6
6
  "type": "module",
@@ -1,156 +0,0 @@
1
- /**
2
- * Armory V1 Types - x402 Protocol V1 Compatible
3
- *
4
- * Supports both the x402 V1 specification format and legacy Armory V1 format.
5
- *
6
- * x402 V1 Specification: https://github.com/coinbase/x402
7
- */
8
- import type { Address } from "./v2";
9
- /**
10
- * Network name for x402 V1 (e.g., "base-sepolia", "ethereum-mainnet")
11
- */
12
- export type X402V1Network = string;
13
- /**
14
- * EIP-3009 authorization data (same format for V1 and V2)
15
- */
16
- export interface EIP3009AuthorizationV1 {
17
- from: Address;
18
- to: Address;
19
- value: string;
20
- validAfter: string;
21
- validBefore: string;
22
- nonce: `0x${string}`;
23
- }
24
- /**
25
- * Payment requirements for a specific payment method (x402 V1)
26
- */
27
- export interface X402PaymentRequirementsV1 {
28
- scheme: "exact";
29
- network: X402V1Network;
30
- maxAmountRequired: string;
31
- asset: Address;
32
- payTo: Address;
33
- resource: string;
34
- description: string;
35
- mimeType?: string;
36
- outputSchema?: object | null;
37
- maxTimeoutSeconds: number;
38
- extra?: Record<string, unknown>;
39
- }
40
- /**
41
- * Payment requirements response (x402 V1)
42
- * Matches x402 V1 PaymentRequirementsResponse spec
43
- */
44
- export interface X402PaymentRequiredV1 {
45
- x402Version: 1;
46
- error: string;
47
- accepts: X402PaymentRequirementsV1[];
48
- }
49
- /**
50
- * Scheme payload data (x402 V1)
51
- */
52
- export interface X402SchemePayloadV1 {
53
- signature: `0x${string}`;
54
- authorization: EIP3009AuthorizationV1;
55
- }
56
- /**
57
- * Payment payload (x402 V1)
58
- * Matches x402 V1 PaymentPayload spec
59
- */
60
- export interface X402PaymentPayloadV1 {
61
- x402Version: 1;
62
- scheme: "exact";
63
- network: X402V1Network;
64
- payload: X402SchemePayloadV1;
65
- }
66
- /**
67
- * Settlement response (x402 V1)
68
- * Matches x402 V1 SettlementResponse spec
69
- */
70
- export interface X402SettlementResponseV1 {
71
- success: boolean;
72
- errorReason?: string;
73
- transaction: string;
74
- network: X402V1Network;
75
- payer: Address;
76
- }
77
- /**
78
- * Legacy Armory V1 payment payload format
79
- * @deprecated Use X402PaymentPayloadV1 for new code
80
- */
81
- export interface LegacyPaymentPayloadV1 {
82
- from: string;
83
- to: string;
84
- amount: string;
85
- nonce: string;
86
- expiry: number;
87
- v: number;
88
- r: string;
89
- s: string;
90
- chainId: number;
91
- contractAddress: string;
92
- network: string;
93
- }
94
- /**
95
- * Legacy Armory V1 payment requirements format
96
- * @deprecated Use X402PaymentRequirementsV1 for new code
97
- */
98
- export interface LegacyPaymentRequirementsV1 {
99
- amount: string;
100
- network: string;
101
- contractAddress: string;
102
- payTo: string;
103
- expiry: number;
104
- }
105
- /**
106
- * Legacy Armory V1 settlement response format
107
- * @deprecated Use X402SettlementResponseV1 for new code
108
- */
109
- export interface LegacySettlementResponseV1 {
110
- success: boolean;
111
- txHash?: string;
112
- error?: string;
113
- timestamp: number;
114
- }
115
- export type PaymentPayloadV1 = X402PaymentPayloadV1 | LegacyPaymentPayloadV1;
116
- export type PaymentRequirementsV1 = X402PaymentRequirementsV1 | LegacyPaymentRequirementsV1;
117
- export type SettlementResponseV1 = X402SettlementResponseV1 | LegacySettlementResponseV1;
118
- export declare const V1_HEADERS: {
119
- readonly PAYMENT: "X-PAYMENT";
120
- readonly PAYMENT_RESPONSE: "X-PAYMENT-RESPONSE";
121
- readonly PAYMENT_REQUIRED: "X-PAYMENT-REQUIRED";
122
- };
123
- export declare function encodeX402PaymentRequiredV1(data: X402PaymentRequiredV1): string;
124
- export declare function decodeX402PaymentRequiredV1(encoded: string): X402PaymentRequiredV1;
125
- export declare function encodeX402PaymentPayloadV1(data: X402PaymentPayloadV1): string;
126
- export declare function decodeX402PaymentPayloadV1(encoded: string): X402PaymentPayloadV1;
127
- export declare function encodeX402SettlementResponseV1(data: X402SettlementResponseV1): string;
128
- export declare function decodeX402SettlementResponseV1(encoded: string): X402SettlementResponseV1;
129
- /**
130
- * @deprecated Use encodeX402PaymentPayloadV1 instead
131
- */
132
- export declare function encodePaymentPayloadLegacy(payload: LegacyPaymentPayloadV1): string;
133
- /**
134
- * @deprecated Use decodeX402PaymentPayloadV1 instead
135
- */
136
- export declare function decodePaymentPayloadLegacy(encoded: string): LegacyPaymentPayloadV1;
137
- /**
138
- * @deprecated Use encodeX402SettlementResponseV1 instead
139
- */
140
- export declare function encodeSettlementResponseLegacy(response: LegacySettlementResponseV1): string;
141
- /**
142
- * @deprecated Use decodeX402SettlementResponseV1 instead
143
- */
144
- export declare function decodeSettlementResponseLegacy(encoded: string): LegacySettlementResponseV1;
145
- /**
146
- * Check if value is x402 V1 PaymentRequired
147
- */
148
- export declare function isX402PaymentRequiredV1(obj: unknown): obj is X402PaymentRequiredV1;
149
- /**
150
- * Check if value is x402 V1 PaymentPayload
151
- */
152
- export declare function isX402PaymentPayloadV1(obj: unknown): obj is X402PaymentPayloadV1;
153
- /**
154
- * Check if value is legacy Armory V1 format
155
- */
156
- export declare function isLegacyPaymentPayloadV1(obj: unknown): obj is LegacyPaymentPayloadV1;