@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/eip712.d.ts +2 -1
- package/dist/encoding/x402.d.ts +15 -26
- package/dist/encoding.d.ts +19 -12
- package/dist/fixtures/config.d.ts +48 -0
- package/dist/fixtures/payloads.d.ts +16 -0
- package/dist/fixtures/requirements.d.ts +35 -0
- package/dist/index.d.ts +7 -8
- package/dist/index.js +197 -253
- package/dist/types/{simple.d.ts → api.d.ts} +38 -4
- package/dist/types/arktype.d.ts +0 -0
- package/dist/types/networks.d.ts +2 -2
- package/dist/types/protocol.d.ts +45 -61
- package/dist/types/v2.d.ts +13 -6
- package/dist/types/x402.d.ts +4 -5
- package/dist/utils/utils/index.d.ts +7 -0
- package/dist/utils/utils/mock-facilitator.d.ts +38 -0
- package/dist/validation.d.ts +4 -31
- package/package.json +7 -8
- package/dist/validation.test.d.ts +0 -5
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(
|
|
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:
|
|
226
|
+
x402Version: 2,
|
|
201
227
|
accepts
|
|
202
228
|
};
|
|
203
229
|
return {
|
|
204
|
-
[
|
|
230
|
+
[V2_HEADERS.PAYMENT_REQUIRED]: safeBase64Encode(JSON.stringify(response))
|
|
205
231
|
};
|
|
206
232
|
}
|
|
207
233
|
function createSettlementHeaders(settlement) {
|
|
208
234
|
return {
|
|
209
|
-
[
|
|
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 && "
|
|
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
|
-
|
|
436
|
-
|
|
437
|
-
|
|
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
|
-
|
|
523
|
-
|
|
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 (
|
|
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
|
|
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
|
|
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:
|
|
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 =
|
|
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
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
var
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
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
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
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
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
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,
|