@armory-sh/base 0.2.12 → 0.2.13
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/fixtures/config.d.ts +48 -0
- package/dist/fixtures/payloads.d.ts +18 -0
- package/dist/fixtures/requirements.d.ts +35 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +202 -168
- package/dist/types/arktype.d.ts +0 -0
- package/dist/types/networks.d.ts +2 -2
- package/dist/types/protocol.d.ts +43 -2
- package/dist/types/simple.d.ts +34 -0
- package/dist/types/v2.d.ts +8 -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 +11 -30
- package/package.json +6 -4
- package/dist/validation.test.d.ts +0 -5
package/dist/eip712.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ export interface TransferWithAuthorization {
|
|
|
19
19
|
validBefore: bigint;
|
|
20
20
|
nonce: bigint;
|
|
21
21
|
}
|
|
22
|
+
export type TransferWithAuthorizationRecord = TransferWithAuthorization & Record<string, unknown>;
|
|
22
23
|
export type TypedDataField = {
|
|
23
24
|
name: string;
|
|
24
25
|
type: string;
|
|
@@ -57,5 +58,5 @@ export declare const createTransferWithAuthorization: (params: Omit<TransferWith
|
|
|
57
58
|
validAfter: bigint | number;
|
|
58
59
|
validBefore: bigint | number;
|
|
59
60
|
nonce: bigint | number;
|
|
60
|
-
}) =>
|
|
61
|
+
}) => TransferWithAuthorizationRecord;
|
|
61
62
|
export declare const validateTransferWithAuthorization: (message: TransferWithAuthorization) => boolean;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test Configuration
|
|
3
|
+
*
|
|
4
|
+
* Shared configuration for E2E tests including network configs,
|
|
5
|
+
* test keys, and facilitator URLs.
|
|
6
|
+
*/
|
|
7
|
+
export declare const TEST_PRIVATE_KEY: `0x${string}`;
|
|
8
|
+
export declare const TEST_PAYER_ADDRESS: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1";
|
|
9
|
+
export declare const TEST_PAY_TO_ADDRESS: "0x1234567890123456789012345678901234567890";
|
|
10
|
+
export declare const TEST_CONTRACT_ADDRESS: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
|
|
11
|
+
export declare const TEST_NETWORK: "base-sepolia";
|
|
12
|
+
export declare const TEST_CHAIN_ID: 84532;
|
|
13
|
+
export declare const TEST_CAIP2_NETWORK: "eip155:84532";
|
|
14
|
+
export declare const TEST_ASSET_ID: "eip155:84532/erc20:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
|
|
15
|
+
export declare const TEST_AMOUNT: "1000000";
|
|
16
|
+
export declare const TEST_AMOUNT_DECIMAL: "1.0";
|
|
17
|
+
export declare const FACILITATOR_URL: string;
|
|
18
|
+
export declare const MOCK_FACILITATOR_PORT = 8899;
|
|
19
|
+
export declare const TEST_TIMEOUT_MS = 30000;
|
|
20
|
+
export declare const SERVER_STARTUP_DELAY_MS = 100;
|
|
21
|
+
export declare const SETTLEMENT_TIMEOUT_MS = 10000;
|
|
22
|
+
export declare const TEST_RPC_URL: string;
|
|
23
|
+
export interface TestPaymentConfig {
|
|
24
|
+
payTo: `0x${string}`;
|
|
25
|
+
amount: string;
|
|
26
|
+
network: string;
|
|
27
|
+
defaultVersion: 1 | 2;
|
|
28
|
+
accept: {
|
|
29
|
+
networks: string[];
|
|
30
|
+
tokens: string[];
|
|
31
|
+
facilitators: Array<{
|
|
32
|
+
url: string;
|
|
33
|
+
}>;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export declare const DEFAULT_PAYMENT_CONFIG: TestPaymentConfig;
|
|
37
|
+
/**
|
|
38
|
+
* Get a random port for test servers
|
|
39
|
+
*/
|
|
40
|
+
export declare const getRandomPort: () => number;
|
|
41
|
+
/**
|
|
42
|
+
* Create a test nonce with timestamp
|
|
43
|
+
*/
|
|
44
|
+
export declare const createTestNonce: (prefix: string) => string;
|
|
45
|
+
/**
|
|
46
|
+
* Sleep for specified milliseconds
|
|
47
|
+
*/
|
|
48
|
+
export declare const sleep: (ms: number) => Promise<void>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock Payment Payloads for Testing
|
|
3
|
+
*/
|
|
4
|
+
import type { X402PaymentPayloadV1, X402PayloadV2, PaymentPayloadV2 } from "@armory-sh/base";
|
|
5
|
+
export declare const TEST_PRIVATE_KEY = "0x0000000000000000000000000000000000000000000000000000000000000000000001";
|
|
6
|
+
export declare const TEST_PAYER_ADDRESS = "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1";
|
|
7
|
+
export declare const TEST_PAY_TO_ADDRESS = "0x1234567890123456789012345678901234567890";
|
|
8
|
+
export declare const TEST_CONTRACT_ADDRESS = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
|
|
9
|
+
export declare const createX402V1Payload: (nonce?: string) => X402PaymentPayloadV1;
|
|
10
|
+
export declare const createFaremeterPayload: (nonce?: string) => X402PaymentPayloadV1;
|
|
11
|
+
export declare const createX402V2Payload: (nonce?: string) => PaymentPayloadV2;
|
|
12
|
+
export declare const createLegacyV2Payload: (nonce?: string) => X402PayloadV2;
|
|
13
|
+
export declare const INVALID_PAYLOADS: {
|
|
14
|
+
readonly missingFields: {};
|
|
15
|
+
readonly invalidAddress: PaymentPayloadV2;
|
|
16
|
+
readonly expired: PaymentPayloadV2;
|
|
17
|
+
readonly malformedSignature: PaymentPayloadV2;
|
|
18
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock Payment Requirements for Testing
|
|
3
|
+
*/
|
|
4
|
+
import type { X402PaymentRequirementsV1, PaymentRequirementsV2 } from "@armory-sh/base";
|
|
5
|
+
export declare const MOCK_X402_V1_REQUIREMENTS: X402PaymentRequirementsV1;
|
|
6
|
+
export declare const createX402V1Requirements: (overrides?: Partial<X402PaymentRequirementsV1>) => X402PaymentRequirementsV1;
|
|
7
|
+
export declare const MOCK_X402_V2_REQUIREMENTS: PaymentRequirementsV2;
|
|
8
|
+
export declare const createX402V2Requirements: (overrides?: Partial<PaymentRequirementsV2>) => PaymentRequirementsV2;
|
|
9
|
+
export declare const INVALID_REQUIREMENTS: {
|
|
10
|
+
readonly missingAmount: {
|
|
11
|
+
scheme: "exact";
|
|
12
|
+
network: import("@armory-sh/base").CAIP2ChainId;
|
|
13
|
+
amount: string;
|
|
14
|
+
asset: import("@armory-sh/base").Address;
|
|
15
|
+
payTo: import("@armory-sh/base").Address;
|
|
16
|
+
maxTimeoutSeconds: number;
|
|
17
|
+
extra?: import("@armory-sh/base").Extensions;
|
|
18
|
+
};
|
|
19
|
+
readonly invalidNetwork: {
|
|
20
|
+
readonly scheme: "exact";
|
|
21
|
+
readonly network: `eip155:${string}`;
|
|
22
|
+
readonly amount: "1000000";
|
|
23
|
+
readonly asset: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
|
|
24
|
+
readonly payTo: "0x1234567890123456789012345678901234567890";
|
|
25
|
+
readonly maxTimeoutSeconds: 300;
|
|
26
|
+
};
|
|
27
|
+
readonly invalidAsset: {
|
|
28
|
+
readonly scheme: "exact";
|
|
29
|
+
readonly network: "eip155:84532";
|
|
30
|
+
readonly amount: "1000000";
|
|
31
|
+
readonly asset: `0x${string}`;
|
|
32
|
+
readonly payTo: "0x1234567890123456789012345678901234567890";
|
|
33
|
+
readonly maxTimeoutSeconds: 300;
|
|
34
|
+
};
|
|
35
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -17,4 +17,4 @@ export type { TypedDataDomain, EIP712Domain, TransferWithAuthorization, TypedDat
|
|
|
17
17
|
export { EIP712_TYPES, USDC_DOMAIN, createEIP712Domain, createTransferWithAuthorization, validateTransferWithAuthorization, } from "./eip712";
|
|
18
18
|
export { resolveNetwork, resolveToken, resolveFacilitator, checkFacilitatorSupport, validatePaymentConfig, validateAcceptConfig, getAvailableNetworks, getAvailableTokens, isValidationError, isResolvedNetwork, isResolvedToken, createError, normalizeNetworkName, } from "./validation";
|
|
19
19
|
export { encodePaymentV1, decodePaymentV1, encodeSettlementV1, decodeSettlementV1, encodePaymentV2, decodePaymentV2, encodeSettlementV2, decodeSettlementV2, detectPaymentVersion as detectPaymentVersionLegacy, decodePayment as decodePaymentLegacy, decodeSettlement as decodeSettlementLegacy, isPaymentV1, isPaymentV2, isSettlementV1, isSettlementV2, } from "./encoding";
|
|
20
|
-
export type { NetworkId, TokenId, FacilitatorConfig, AcceptPaymentOptions, PricingConfig, PaymentResult, PaymentError, PaymentErrorCode, ArmoryPaymentResult, ResolvedNetwork, ResolvedToken, ResolvedFacilitator, ResolvedPaymentConfig, ValidationError, } from "./types/simple";
|
|
20
|
+
export type { NetworkId, TokenId, FacilitatorConfig, FacilitatorVerifyResult, FacilitatorSettleResult, SettlementMode, PayToAddress, AcceptPaymentOptions, PricingConfig, PaymentResult, PaymentError, PaymentErrorCode, ArmoryPaymentResult, ResolvedNetwork, ResolvedToken, ResolvedFacilitator, ResolvedPaymentConfig, ValidationError, } from "./types/simple";
|
package/dist/index.js
CHANGED
|
@@ -354,7 +354,7 @@ function isPaymentRequiredV2(obj) {
|
|
|
354
354
|
return typeof obj === "object" && obj !== null && "x402Version" in obj && obj.x402Version === 2 && "resource" in obj && "accepts" in obj && Array.isArray(obj.accepts);
|
|
355
355
|
}
|
|
356
356
|
function isPaymentPayloadV2(obj) {
|
|
357
|
-
return typeof obj === "object" && obj !== null && "x402Version" in obj && obj.x402Version === 2 && "
|
|
357
|
+
return typeof obj === "object" && obj !== null && "x402Version" in obj && obj.x402Version === 2 && "scheme" in obj && "network" in obj && "payload" in obj;
|
|
358
358
|
}
|
|
359
359
|
function assetIdToAddress(assetId) {
|
|
360
360
|
const match = assetId.match(/\/erc20:(0x[a-fA-F0-9]{40})$/);
|
|
@@ -386,7 +386,7 @@ function isX402V1Payload(obj) {
|
|
|
386
386
|
return typeof obj === "object" && obj !== null && "x402Version" in obj && obj.x402Version === 1 && "scheme" in obj && "network" in obj && "payload" in obj;
|
|
387
387
|
}
|
|
388
388
|
function isX402V2Payload(obj) {
|
|
389
|
-
return typeof obj === "object" && obj !== null && "x402Version" in obj && obj.x402Version === 2 && "
|
|
389
|
+
return typeof obj === "object" && obj !== null && "x402Version" in obj && obj.x402Version === 2 && "scheme" in obj && "network" in obj && "payload" in obj;
|
|
390
390
|
}
|
|
391
391
|
function isLegacyV1Payload(obj) {
|
|
392
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);
|
|
@@ -462,172 +462,20 @@ function isV2(obj) {
|
|
|
462
462
|
}
|
|
463
463
|
|
|
464
464
|
// src/types/networks.ts
|
|
465
|
-
|
|
466
|
-
var tokenKey = (chainId, contractAddress) => `${chainId}:${contractAddress.toLowerCase()}`;
|
|
467
|
-
var NETWORKS = {
|
|
468
|
-
ethereum: {
|
|
469
|
-
name: "Ethereum Mainnet",
|
|
470
|
-
chainId: 1,
|
|
471
|
-
usdcAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
472
|
-
rpcUrl: "https://eth.llamarpc.com",
|
|
473
|
-
caip2Id: "eip155:1",
|
|
474
|
-
caipAssetId: "eip155:1/erc20:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
|
|
475
|
-
},
|
|
476
|
-
base: {
|
|
477
|
-
name: "Base Mainnet",
|
|
478
|
-
chainId: 8453,
|
|
479
|
-
usdcAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
480
|
-
rpcUrl: "https://mainnet.base.org",
|
|
481
|
-
caip2Id: "eip155:8453",
|
|
482
|
-
caipAssetId: "eip155:8453/erc20:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
|
|
483
|
-
},
|
|
484
|
-
"base-sepolia": {
|
|
485
|
-
name: "Base Sepolia",
|
|
486
|
-
chainId: 84532,
|
|
487
|
-
usdcAddress: "0x036CbD53842c5426634e7929541eA237834d2D14",
|
|
488
|
-
rpcUrl: "https://sepolia.base.org",
|
|
489
|
-
caip2Id: "eip155:84532",
|
|
490
|
-
caipAssetId: "eip155:84532/erc20:0x036CbD53842c5426634e7929541eA237834d2D14"
|
|
491
|
-
},
|
|
492
|
-
"skale-base": {
|
|
493
|
-
name: "SKALE Base",
|
|
494
|
-
chainId: 1187947933,
|
|
495
|
-
usdcAddress: "0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",
|
|
496
|
-
rpcUrl: "https://skale-base.skalenodes.com/v1/base",
|
|
497
|
-
caip2Id: "eip155:1187947933",
|
|
498
|
-
caipAssetId: "eip155:1187947933/erc20:0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20"
|
|
499
|
-
},
|
|
500
|
-
"skale-base-sepolia": {
|
|
501
|
-
name: "SKALE Base Sepolia",
|
|
502
|
-
chainId: 324705682,
|
|
503
|
-
usdcAddress: "0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",
|
|
504
|
-
rpcUrl: "https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",
|
|
505
|
-
caip2Id: "eip155:324705682",
|
|
506
|
-
caipAssetId: "eip155:324705682/erc20:0x2e08028E3C4c2356572E096d8EF835cD5C6030bD"
|
|
507
|
-
},
|
|
508
|
-
"ethereum-sepolia": {
|
|
509
|
-
name: "Ethereum Sepolia",
|
|
510
|
-
chainId: 11155111,
|
|
511
|
-
usdcAddress: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
|
|
512
|
-
rpcUrl: "https://rpc.sepolia.org",
|
|
513
|
-
caip2Id: "eip155:11155111",
|
|
514
|
-
caipAssetId: "eip155:11155111/erc20:0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238"
|
|
515
|
-
}
|
|
516
|
-
};
|
|
517
|
-
var getNetworkConfig = (name) => NETWORKS[name];
|
|
518
|
-
var getNetworkByChainId = (chainId) => Object.values(NETWORKS).find((c) => c.chainId === chainId);
|
|
519
|
-
var getMainnets = () => Object.values(NETWORKS).filter((c) => !c.name.toLowerCase().includes("sepolia"));
|
|
520
|
-
var getTestnets = () => Object.values(NETWORKS).filter((c) => c.name.toLowerCase().includes("sepolia"));
|
|
521
|
-
var registerToken = (token) => {
|
|
522
|
-
tokenRegistry.set(tokenKey(token.chainId, token.contractAddress), token);
|
|
523
|
-
return token;
|
|
524
|
-
};
|
|
525
|
-
var getCustomToken = (chainId, contractAddress) => tokenRegistry.get(tokenKey(chainId, contractAddress));
|
|
526
|
-
var getAllCustomTokens = () => Array.from(tokenRegistry.values());
|
|
527
|
-
var unregisterToken = (chainId, contractAddress) => tokenRegistry.delete(tokenKey(chainId, contractAddress));
|
|
528
|
-
var isCustomToken = (chainId, contractAddress) => tokenRegistry.has(tokenKey(chainId, contractAddress));
|
|
529
|
-
|
|
530
|
-
// src/abi/erc20.ts
|
|
531
|
-
var ERC20_ABI = [
|
|
532
|
-
{
|
|
533
|
-
type: "function",
|
|
534
|
-
name: "transferWithAuthorization",
|
|
535
|
-
stateMutability: "nonpayable",
|
|
536
|
-
inputs: [
|
|
537
|
-
{ name: "from", type: "address" },
|
|
538
|
-
{ name: "to", type: "address" },
|
|
539
|
-
{ name: "amount", type: "uint256" },
|
|
540
|
-
{ name: "validAfter", type: "uint256" },
|
|
541
|
-
{ name: "expiry", type: "uint256" },
|
|
542
|
-
{ name: "v", type: "uint8" },
|
|
543
|
-
{ name: "r", type: "bytes32" },
|
|
544
|
-
{ name: "s", type: "bytes32" }
|
|
545
|
-
],
|
|
546
|
-
outputs: []
|
|
547
|
-
},
|
|
548
|
-
{
|
|
549
|
-
type: "function",
|
|
550
|
-
name: "receiveWithAuthorization",
|
|
551
|
-
stateMutability: "nonpayable",
|
|
552
|
-
inputs: [
|
|
553
|
-
{ name: "from", type: "address" },
|
|
554
|
-
{ name: "to", type: "address" },
|
|
555
|
-
{ name: "amount", type: "uint256" },
|
|
556
|
-
{ name: "validAfter", type: "uint256" },
|
|
557
|
-
{ name: "expiry", type: "uint256" },
|
|
558
|
-
{ name: "v", type: "uint8" },
|
|
559
|
-
{ name: "r", type: "bytes32" },
|
|
560
|
-
{ name: "s", type: "bytes32" }
|
|
561
|
-
],
|
|
562
|
-
outputs: []
|
|
563
|
-
},
|
|
564
|
-
{
|
|
565
|
-
type: "function",
|
|
566
|
-
name: "balanceOf",
|
|
567
|
-
stateMutability: "view",
|
|
568
|
-
inputs: [{ name: "account", type: "address" }],
|
|
569
|
-
outputs: [{ name: "balance", type: "uint256" }]
|
|
570
|
-
},
|
|
571
|
-
{
|
|
572
|
-
type: "function",
|
|
573
|
-
name: "name",
|
|
574
|
-
stateMutability: "view",
|
|
575
|
-
inputs: [],
|
|
576
|
-
outputs: [{ name: "", type: "string" }]
|
|
577
|
-
},
|
|
578
|
-
{
|
|
579
|
-
type: "function",
|
|
580
|
-
name: "symbol",
|
|
581
|
-
stateMutability: "view",
|
|
582
|
-
inputs: [],
|
|
583
|
-
outputs: [{ name: "", type: "string" }]
|
|
584
|
-
}
|
|
585
|
-
];
|
|
586
|
-
|
|
587
|
-
// src/eip712.ts
|
|
588
|
-
var EIP712_TYPES = {
|
|
589
|
-
TransferWithAuthorization: [
|
|
590
|
-
{ name: "from", type: "address" },
|
|
591
|
-
{ name: "to", type: "address" },
|
|
592
|
-
{ name: "value", type: "uint256" },
|
|
593
|
-
{ name: "validAfter", type: "uint256" },
|
|
594
|
-
{ name: "validBefore", type: "uint256" },
|
|
595
|
-
{ name: "nonce", type: "uint256" }
|
|
596
|
-
]
|
|
597
|
-
};
|
|
598
|
-
var USDC_DOMAIN = {
|
|
599
|
-
NAME: "USD Coin",
|
|
600
|
-
VERSION: "2"
|
|
601
|
-
};
|
|
602
|
-
var createEIP712Domain = (chainId, contractAddress) => ({
|
|
603
|
-
name: USDC_DOMAIN.NAME,
|
|
604
|
-
version: USDC_DOMAIN.VERSION,
|
|
605
|
-
chainId,
|
|
606
|
-
verifyingContract: contractAddress
|
|
607
|
-
});
|
|
608
|
-
var createTransferWithAuthorization = (params) => ({
|
|
609
|
-
from: params.from,
|
|
610
|
-
to: params.to,
|
|
611
|
-
value: BigInt(params.value),
|
|
612
|
-
validAfter: BigInt(params.validAfter),
|
|
613
|
-
validBefore: BigInt(params.validBefore),
|
|
614
|
-
nonce: BigInt(params.nonce)
|
|
615
|
-
});
|
|
616
|
-
var isAddress2 = (value) => /^0x[a-fA-F0-9]{40}$/.test(value);
|
|
617
|
-
var validateTransferWithAuthorization = (message) => {
|
|
618
|
-
if (!isAddress2(message.from)) throw new Error(`Invalid "from" address: ${message.from}`);
|
|
619
|
-
if (!isAddress2(message.to)) throw new Error(`Invalid "to" address: ${message.to}`);
|
|
620
|
-
if (message.value < 0n) throw new Error(`"value" must be non-negative: ${message.value}`);
|
|
621
|
-
if (message.validAfter < 0n) throw new Error(`"validAfter" must be non-negative: ${message.validAfter}`);
|
|
622
|
-
if (message.validBefore < 0n) throw new Error(`"validBefore" must be non-negative: ${message.validBefore}`);
|
|
623
|
-
if (message.validAfter >= message.validBefore) {
|
|
624
|
-
throw new Error(`"validAfter" (${message.validAfter}) must be before "validBefore" (${message.validBefore})`);
|
|
625
|
-
}
|
|
626
|
-
if (message.nonce < 0n) throw new Error(`"nonce" must be non-negative: ${message.nonce}`);
|
|
627
|
-
return true;
|
|
628
|
-
};
|
|
465
|
+
import { type as arkType2 } from "arktype";
|
|
629
466
|
|
|
630
467
|
// src/validation.ts
|
|
468
|
+
import { type as arkType } from "arktype";
|
|
469
|
+
var CustomTokenSchema = arkType({
|
|
470
|
+
symbol: "string",
|
|
471
|
+
name: "string",
|
|
472
|
+
version: "string",
|
|
473
|
+
contractAddress: "/^0x[a-fA-F0-9]{40}$/",
|
|
474
|
+
chainId: "number.integer > 0",
|
|
475
|
+
decimals: "number.integer >= 0?"
|
|
476
|
+
});
|
|
477
|
+
var NetworkIdSchema = arkType("string | number | object");
|
|
478
|
+
var TokenIdSchema = arkType("string | number | object");
|
|
631
479
|
var createError = (code, message, details) => ({
|
|
632
480
|
code,
|
|
633
481
|
message,
|
|
@@ -635,6 +483,14 @@ var createError = (code, message, details) => ({
|
|
|
635
483
|
});
|
|
636
484
|
var normalizeNetworkName = (name) => name.toLowerCase().replace(/\s+/g, "-").replace("-mainnet", "").replace(/-mainnet/, "").replace("mainnet-", "").replace(/-sepolia$/, "-sepolia").replace(/^-|-$/g, "");
|
|
637
485
|
var resolveNetwork = (input) => {
|
|
486
|
+
const inputCheck = NetworkIdSchema(input);
|
|
487
|
+
if (inputCheck instanceof arkType.errors) {
|
|
488
|
+
return createError(
|
|
489
|
+
"VALIDATION_FAILED",
|
|
490
|
+
"Invalid network input type",
|
|
491
|
+
{ value: input, validOptions: ["string (name/CAIP-2)", "number (chainId)", "NetworkConfig"] }
|
|
492
|
+
);
|
|
493
|
+
}
|
|
638
494
|
if (typeof input === "object" && input !== null && "chainId" in input) {
|
|
639
495
|
const config = input;
|
|
640
496
|
if (!config.chainId || !config.usdcAddress || !config.caip2Id) {
|
|
@@ -701,6 +557,14 @@ var getAvailableNetworks = () => Object.keys(NETWORKS);
|
|
|
701
557
|
var normalizeTokenSymbol = (symbol) => symbol.toUpperCase();
|
|
702
558
|
var isEvmAddress = (value) => /^0x[a-fA-F0-9]{40}$/.test(value);
|
|
703
559
|
var resolveToken = (input, network) => {
|
|
560
|
+
const inputCheck = TokenIdSchema(input);
|
|
561
|
+
if (inputCheck instanceof arkType.errors) {
|
|
562
|
+
return createError(
|
|
563
|
+
"VALIDATION_FAILED",
|
|
564
|
+
"Invalid token input type",
|
|
565
|
+
{ value: input, validOptions: ["string (symbol/address/CAIP Asset)", "number (deprecated)", "CustomToken"] }
|
|
566
|
+
);
|
|
567
|
+
}
|
|
704
568
|
if (typeof input === "object" && input !== null && "contractAddress" in input) {
|
|
705
569
|
const config = input;
|
|
706
570
|
if (!config.chainId || !config.contractAddress || !config.symbol) {
|
|
@@ -800,7 +664,7 @@ var resolveToken = (input, network) => {
|
|
|
800
664
|
if (network) {
|
|
801
665
|
const customTokens2 = getAllCustomTokens();
|
|
802
666
|
const matchingToken2 = customTokens2.find(
|
|
803
|
-
(t) => t.symbol
|
|
667
|
+
(t) => t.symbol?.toUpperCase() === normalizedSymbol && t.chainId === network.config.chainId
|
|
804
668
|
);
|
|
805
669
|
if (matchingToken2) {
|
|
806
670
|
return {
|
|
@@ -825,7 +689,7 @@ var resolveToken = (input, network) => {
|
|
|
825
689
|
};
|
|
826
690
|
}
|
|
827
691
|
const customTokens = getAllCustomTokens();
|
|
828
|
-
const matchingToken = customTokens.find((t) => t.symbol
|
|
692
|
+
const matchingToken = customTokens.find((t) => t.symbol?.toUpperCase() === normalizedSymbol);
|
|
829
693
|
if (matchingToken) {
|
|
830
694
|
const tokenNetwork = resolveNetwork(matchingToken.chainId);
|
|
831
695
|
if ("code" in tokenNetwork) {
|
|
@@ -1042,6 +906,176 @@ var isResolvedToken = (value) => {
|
|
|
1042
906
|
return typeof value === "object" && value !== null && "config" in value && "caipAsset" in value;
|
|
1043
907
|
};
|
|
1044
908
|
|
|
909
|
+
// src/types/networks.ts
|
|
910
|
+
var tokenRegistry = /* @__PURE__ */ new Map();
|
|
911
|
+
var tokenKey = (chainId, contractAddress) => `${chainId}:${contractAddress.toLowerCase()}`;
|
|
912
|
+
var NETWORKS = {
|
|
913
|
+
ethereum: {
|
|
914
|
+
name: "Ethereum Mainnet",
|
|
915
|
+
chainId: 1,
|
|
916
|
+
usdcAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
917
|
+
rpcUrl: "https://eth.llamarpc.com",
|
|
918
|
+
caip2Id: "eip155:1",
|
|
919
|
+
caipAssetId: "eip155:1/erc20:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
|
|
920
|
+
},
|
|
921
|
+
base: {
|
|
922
|
+
name: "Base Mainnet",
|
|
923
|
+
chainId: 8453,
|
|
924
|
+
usdcAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
925
|
+
rpcUrl: "https://mainnet.base.org",
|
|
926
|
+
caip2Id: "eip155:8453",
|
|
927
|
+
caipAssetId: "eip155:8453/erc20:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
|
|
928
|
+
},
|
|
929
|
+
"base-sepolia": {
|
|
930
|
+
name: "Base Sepolia",
|
|
931
|
+
chainId: 84532,
|
|
932
|
+
usdcAddress: "0x036CbD53842c5426634e7929541eA237834d2D14",
|
|
933
|
+
rpcUrl: "https://sepolia.base.org",
|
|
934
|
+
caip2Id: "eip155:84532",
|
|
935
|
+
caipAssetId: "eip155:84532/erc20:0x036CbD53842c5426634e7929541eA237834d2D14"
|
|
936
|
+
},
|
|
937
|
+
"skale-base": {
|
|
938
|
+
name: "SKALE Base",
|
|
939
|
+
chainId: 1187947933,
|
|
940
|
+
usdcAddress: "0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",
|
|
941
|
+
rpcUrl: "https://skale-base.skalenodes.com/v1/base",
|
|
942
|
+
caip2Id: "eip155:1187947933",
|
|
943
|
+
caipAssetId: "eip155:1187947933/erc20:0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20"
|
|
944
|
+
},
|
|
945
|
+
"skale-base-sepolia": {
|
|
946
|
+
name: "SKALE Base Sepolia",
|
|
947
|
+
chainId: 324705682,
|
|
948
|
+
usdcAddress: "0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",
|
|
949
|
+
rpcUrl: "https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",
|
|
950
|
+
caip2Id: "eip155:324705682",
|
|
951
|
+
caipAssetId: "eip155:324705682/erc20:0x2e08028E3C4c2356572E096d8EF835cD5C6030bD"
|
|
952
|
+
},
|
|
953
|
+
"ethereum-sepolia": {
|
|
954
|
+
name: "Ethereum Sepolia",
|
|
955
|
+
chainId: 11155111,
|
|
956
|
+
usdcAddress: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
|
|
957
|
+
rpcUrl: "https://rpc.sepolia.org",
|
|
958
|
+
caip2Id: "eip155:11155111",
|
|
959
|
+
caipAssetId: "eip155:11155111/erc20:0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238"
|
|
960
|
+
}
|
|
961
|
+
};
|
|
962
|
+
var getNetworkConfig = (name) => NETWORKS[name];
|
|
963
|
+
var getNetworkByChainId = (chainId) => Object.values(NETWORKS).find((c) => c.chainId === chainId);
|
|
964
|
+
var getMainnets = () => Object.values(NETWORKS).filter((c) => !c.name.toLowerCase().includes("sepolia"));
|
|
965
|
+
var getTestnets = () => Object.values(NETWORKS).filter((c) => c.name.toLowerCase().includes("sepolia"));
|
|
966
|
+
var registerToken = (token) => {
|
|
967
|
+
const validated = CustomTokenSchema(token);
|
|
968
|
+
if (validated instanceof arkType2.errors) {
|
|
969
|
+
throw new Error(`Invalid token: ${validated.summary}`);
|
|
970
|
+
}
|
|
971
|
+
tokenRegistry.set(tokenKey(validated.chainId, validated.contractAddress), validated);
|
|
972
|
+
return validated;
|
|
973
|
+
};
|
|
974
|
+
var getCustomToken = (chainId, contractAddress) => tokenRegistry.get(tokenKey(chainId, contractAddress));
|
|
975
|
+
var getAllCustomTokens = () => Array.from(tokenRegistry.values());
|
|
976
|
+
var unregisterToken = (chainId, contractAddress) => tokenRegistry.delete(tokenKey(chainId, contractAddress));
|
|
977
|
+
var isCustomToken = (chainId, contractAddress) => tokenRegistry.has(tokenKey(chainId, contractAddress));
|
|
978
|
+
|
|
979
|
+
// src/abi/erc20.ts
|
|
980
|
+
var ERC20_ABI = [
|
|
981
|
+
{
|
|
982
|
+
type: "function",
|
|
983
|
+
name: "transferWithAuthorization",
|
|
984
|
+
stateMutability: "nonpayable",
|
|
985
|
+
inputs: [
|
|
986
|
+
{ name: "from", type: "address" },
|
|
987
|
+
{ name: "to", type: "address" },
|
|
988
|
+
{ name: "amount", type: "uint256" },
|
|
989
|
+
{ name: "validAfter", type: "uint256" },
|
|
990
|
+
{ name: "expiry", type: "uint256" },
|
|
991
|
+
{ name: "v", type: "uint8" },
|
|
992
|
+
{ name: "r", type: "bytes32" },
|
|
993
|
+
{ name: "s", type: "bytes32" }
|
|
994
|
+
],
|
|
995
|
+
outputs: []
|
|
996
|
+
},
|
|
997
|
+
{
|
|
998
|
+
type: "function",
|
|
999
|
+
name: "receiveWithAuthorization",
|
|
1000
|
+
stateMutability: "nonpayable",
|
|
1001
|
+
inputs: [
|
|
1002
|
+
{ name: "from", type: "address" },
|
|
1003
|
+
{ name: "to", type: "address" },
|
|
1004
|
+
{ name: "amount", type: "uint256" },
|
|
1005
|
+
{ name: "validAfter", type: "uint256" },
|
|
1006
|
+
{ name: "expiry", type: "uint256" },
|
|
1007
|
+
{ name: "v", type: "uint8" },
|
|
1008
|
+
{ name: "r", type: "bytes32" },
|
|
1009
|
+
{ name: "s", type: "bytes32" }
|
|
1010
|
+
],
|
|
1011
|
+
outputs: []
|
|
1012
|
+
},
|
|
1013
|
+
{
|
|
1014
|
+
type: "function",
|
|
1015
|
+
name: "balanceOf",
|
|
1016
|
+
stateMutability: "view",
|
|
1017
|
+
inputs: [{ name: "account", type: "address" }],
|
|
1018
|
+
outputs: [{ name: "balance", type: "uint256" }]
|
|
1019
|
+
},
|
|
1020
|
+
{
|
|
1021
|
+
type: "function",
|
|
1022
|
+
name: "name",
|
|
1023
|
+
stateMutability: "view",
|
|
1024
|
+
inputs: [],
|
|
1025
|
+
outputs: [{ name: "", type: "string" }]
|
|
1026
|
+
},
|
|
1027
|
+
{
|
|
1028
|
+
type: "function",
|
|
1029
|
+
name: "symbol",
|
|
1030
|
+
stateMutability: "view",
|
|
1031
|
+
inputs: [],
|
|
1032
|
+
outputs: [{ name: "", type: "string" }]
|
|
1033
|
+
}
|
|
1034
|
+
];
|
|
1035
|
+
|
|
1036
|
+
// src/eip712.ts
|
|
1037
|
+
var EIP712_TYPES = {
|
|
1038
|
+
TransferWithAuthorization: [
|
|
1039
|
+
{ name: "from", type: "address" },
|
|
1040
|
+
{ name: "to", type: "address" },
|
|
1041
|
+
{ name: "value", type: "uint256" },
|
|
1042
|
+
{ name: "validAfter", type: "uint256" },
|
|
1043
|
+
{ name: "validBefore", type: "uint256" },
|
|
1044
|
+
{ name: "nonce", type: "uint256" }
|
|
1045
|
+
]
|
|
1046
|
+
};
|
|
1047
|
+
var USDC_DOMAIN = {
|
|
1048
|
+
NAME: "USD Coin",
|
|
1049
|
+
VERSION: "2"
|
|
1050
|
+
};
|
|
1051
|
+
var createEIP712Domain = (chainId, contractAddress) => ({
|
|
1052
|
+
name: USDC_DOMAIN.NAME,
|
|
1053
|
+
version: USDC_DOMAIN.VERSION,
|
|
1054
|
+
chainId,
|
|
1055
|
+
verifyingContract: contractAddress
|
|
1056
|
+
});
|
|
1057
|
+
var createTransferWithAuthorization = (params) => ({
|
|
1058
|
+
from: params.from,
|
|
1059
|
+
to: params.to,
|
|
1060
|
+
value: BigInt(params.value),
|
|
1061
|
+
validAfter: BigInt(params.validAfter),
|
|
1062
|
+
validBefore: BigInt(params.validBefore),
|
|
1063
|
+
nonce: BigInt(params.nonce)
|
|
1064
|
+
});
|
|
1065
|
+
var isAddress2 = (value) => /^0x[a-fA-F0-9]{40}$/.test(value);
|
|
1066
|
+
var validateTransferWithAuthorization = (message) => {
|
|
1067
|
+
if (!isAddress2(message.from)) throw new Error(`Invalid "from" address: ${message.from}`);
|
|
1068
|
+
if (!isAddress2(message.to)) throw new Error(`Invalid "to" address: ${message.to}`);
|
|
1069
|
+
if (message.value < 0n) throw new Error(`"value" must be non-negative: ${message.value}`);
|
|
1070
|
+
if (message.validAfter < 0n) throw new Error(`"validAfter" must be non-negative: ${message.validAfter}`);
|
|
1071
|
+
if (message.validBefore < 0n) throw new Error(`"validBefore" must be non-negative: ${message.validBefore}`);
|
|
1072
|
+
if (message.validAfter >= message.validBefore) {
|
|
1073
|
+
throw new Error(`"validAfter" (${message.validAfter}) must be before "validBefore" (${message.validBefore})`);
|
|
1074
|
+
}
|
|
1075
|
+
if (message.nonce < 0n) throw new Error(`"nonce" must be non-negative: ${message.nonce}`);
|
|
1076
|
+
return true;
|
|
1077
|
+
};
|
|
1078
|
+
|
|
1045
1079
|
// src/encoding.ts
|
|
1046
1080
|
var base64Encode = (data) => Buffer.from(JSON.stringify(data)).toString("base64");
|
|
1047
1081
|
var base64Decode = (encoded) => JSON.parse(Buffer.from(encoded, "base64").toString("utf-8"));
|
|
File without changes
|
package/dist/types/networks.d.ts
CHANGED
|
@@ -12,14 +12,14 @@ export interface CustomToken {
|
|
|
12
12
|
version: string;
|
|
13
13
|
contractAddress: `0x${string}`;
|
|
14
14
|
chainId: number;
|
|
15
|
-
decimals
|
|
15
|
+
decimals?: number;
|
|
16
16
|
}
|
|
17
17
|
export declare const NETWORKS: Record<string, NetworkConfig>;
|
|
18
18
|
export declare const getNetworkConfig: (name: string) => NetworkConfig | undefined;
|
|
19
19
|
export declare const getNetworkByChainId: (chainId: number) => NetworkConfig | undefined;
|
|
20
20
|
export declare const getMainnets: () => NetworkConfig[];
|
|
21
21
|
export declare const getTestnets: () => NetworkConfig[];
|
|
22
|
-
export declare const registerToken: (token:
|
|
22
|
+
export declare const registerToken: (token: unknown) => CustomToken;
|
|
23
23
|
export declare const getCustomToken: (chainId: number, contractAddress: string) => CustomToken | undefined;
|
|
24
24
|
export declare const getAllCustomTokens: () => CustomToken[];
|
|
25
25
|
export declare const unregisterToken: (chainId: number, contractAddress: string) => boolean;
|
package/dist/types/protocol.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Handles both x402 V1 and V2 formats along with legacy Armory formats
|
|
5
5
|
*/
|
|
6
6
|
import type { X402PaymentPayloadV1, X402PaymentRequiredV1, X402PaymentRequirementsV1, X402SettlementResponseV1, LegacyPaymentPayloadV1, LegacyPaymentRequirementsV1, LegacySettlementResponseV1 } from "./v1";
|
|
7
|
-
import type { PaymentPayloadV2, PaymentRequirementsV2, SettlementResponseV2, PaymentRequiredV2 } from "./v2";
|
|
7
|
+
import type { PaymentPayloadV2, PaymentRequirementsV2, SettlementResponseV2, PaymentRequiredV2, Address } from "./v2";
|
|
8
8
|
/**
|
|
9
9
|
* All x402 compatible payment payload types
|
|
10
10
|
*/
|
|
@@ -17,16 +17,57 @@ export type PaymentRequirements = X402PaymentRequirementsV1 | PaymentRequirement
|
|
|
17
17
|
* All x402 compatible settlement response types
|
|
18
18
|
*/
|
|
19
19
|
export type SettlementResponse = X402SettlementResponseV1 | SettlementResponseV2 | LegacySettlementResponseV1;
|
|
20
|
+
/**
|
|
21
|
+
* Configuration for connecting to a facilitator service
|
|
22
|
+
*/
|
|
23
|
+
export interface FacilitatorConfig {
|
|
24
|
+
url: string;
|
|
25
|
+
createHeaders?: () => Record<string, string>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Result from facilitator verification
|
|
29
|
+
*/
|
|
30
|
+
export interface FacilitatorVerifyResult {
|
|
31
|
+
success: boolean;
|
|
32
|
+
payerAddress?: string;
|
|
33
|
+
balance?: string;
|
|
34
|
+
requiredAmount?: string;
|
|
35
|
+
error?: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Result from facilitator settlement
|
|
39
|
+
*/
|
|
40
|
+
export interface FacilitatorSettleResult {
|
|
41
|
+
success: boolean;
|
|
42
|
+
txHash?: string;
|
|
43
|
+
error?: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Settlement mode - verify only, settle only, or both
|
|
47
|
+
*/
|
|
48
|
+
export type SettlementMode = "verify" | "settle" | "async";
|
|
49
|
+
/**
|
|
50
|
+
* Payment destination - address, CAIP-2 chain ID, or CAIP asset ID
|
|
51
|
+
*/
|
|
52
|
+
export type PayToAddress = Address | CAIP2ChainId | CAIPAssetId;
|
|
20
53
|
/**
|
|
21
54
|
* All x402 compatible payment required response types
|
|
22
55
|
*/
|
|
23
56
|
export type PaymentRequired = X402PaymentRequiredV1 | PaymentRequiredV2;
|
|
57
|
+
/**
|
|
58
|
+
* CAIP-2 chain ID type (e.g., eip155:8453)
|
|
59
|
+
*/
|
|
60
|
+
export type CAIP2ChainId = `eip155:${string}`;
|
|
61
|
+
/**
|
|
62
|
+
* CAIP-2 asset ID type (e.g., eip155:8453/erc20:0xa0b8691...)
|
|
63
|
+
*/
|
|
64
|
+
export type CAIPAssetId = `eip155:${string}/erc20:${string}`;
|
|
24
65
|
/**
|
|
25
66
|
* Check if payload is x402 V1 format
|
|
26
67
|
*/
|
|
27
68
|
export declare function isX402V1Payload(obj: unknown): obj is X402PaymentPayloadV1;
|
|
28
69
|
/**
|
|
29
|
-
* Check if payload is x402 V2 format
|
|
70
|
+
* Check if payload is x402 V2 format (Coinbase format)
|
|
30
71
|
*/
|
|
31
72
|
export declare function isX402V2Payload(obj: unknown): obj is PaymentPayloadV2;
|
|
32
73
|
/**
|
package/dist/types/simple.d.ts
CHANGED
|
@@ -31,6 +31,40 @@ export interface FacilitatorConfig {
|
|
|
31
31
|
/** Tokens this facilitator supports (optional) */
|
|
32
32
|
tokens?: TokenId[];
|
|
33
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Result from facilitator verification
|
|
36
|
+
*/
|
|
37
|
+
export interface FacilitatorVerifyResult {
|
|
38
|
+
success: boolean;
|
|
39
|
+
payerAddress?: string;
|
|
40
|
+
balance?: string;
|
|
41
|
+
requiredAmount?: string;
|
|
42
|
+
error?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Result from facilitator settlement
|
|
46
|
+
*/
|
|
47
|
+
export interface FacilitatorSettleResult {
|
|
48
|
+
success: boolean;
|
|
49
|
+
txHash?: string;
|
|
50
|
+
error?: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Settlement mode - verify only, settle only, or both
|
|
54
|
+
*/
|
|
55
|
+
export type SettlementMode = "verify" | "settle" | "async";
|
|
56
|
+
/**
|
|
57
|
+
* CAIP-2 chain ID type (e.g., eip155:8453)
|
|
58
|
+
*/
|
|
59
|
+
export type CAIP2ChainId = `eip155:${string}`;
|
|
60
|
+
/**
|
|
61
|
+
* CAIP-2 asset ID type (e.g., eip155:8453/erc20:0xa0b8691...)
|
|
62
|
+
*/
|
|
63
|
+
export type CAIP2AssetId = `eip155:${string}/erc20:${string}`;
|
|
64
|
+
/**
|
|
65
|
+
* Payment destination - address, CAIP-2 chain ID, or CAIP asset ID
|
|
66
|
+
*/
|
|
67
|
+
export type PayToAddress = `0x${string}` | CAIP2ChainId | CAIP2AssetId;
|
|
34
68
|
/**
|
|
35
69
|
* Pricing configuration for a specific network/token/facilitator combination
|
|
36
70
|
*/
|
package/dist/types/v2.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export type PayToV2 = Address | {
|
|
|
18
18
|
role?: string;
|
|
19
19
|
callback?: string;
|
|
20
20
|
};
|
|
21
|
+
export type PayToAddress = Address | PayToV2;
|
|
21
22
|
export interface Extensions {
|
|
22
23
|
[key: string]: unknown;
|
|
23
24
|
}
|
|
@@ -97,17 +98,19 @@ export interface SchemePayloadV2 {
|
|
|
97
98
|
}
|
|
98
99
|
/**
|
|
99
100
|
* Payment payload sent by client
|
|
100
|
-
* Matches x402 V2 PaymentPayload spec
|
|
101
|
+
* Matches x402 V2 PaymentPayload spec (Coinbase format)
|
|
101
102
|
*/
|
|
102
103
|
export interface PaymentPayloadV2 {
|
|
103
104
|
/** Protocol version identifier */
|
|
104
105
|
x402Version: 2;
|
|
105
|
-
/**
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
|
|
106
|
+
/** Payment scheme (e.g., "exact") */
|
|
107
|
+
scheme: string;
|
|
108
|
+
/** Network identifier in CAIP-2 format */
|
|
109
|
+
network: string;
|
|
109
110
|
/** Scheme-specific payment data */
|
|
110
111
|
payload: SchemePayloadV2;
|
|
112
|
+
/** Resource being accessed (optional, echoed from server) */
|
|
113
|
+
resource?: ResourceInfo;
|
|
111
114
|
/** Protocol extensions data */
|
|
112
115
|
extensions?: Extensions;
|
|
113
116
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock Facilitator for Testing
|
|
3
|
+
*/
|
|
4
|
+
import type { PaymentPayload } from "@armory-sh/base";
|
|
5
|
+
export interface FacilitatorVerifyRequest {
|
|
6
|
+
payload: PaymentPayload;
|
|
7
|
+
requirements: Record<string, unknown>;
|
|
8
|
+
options?: Record<string, unknown>;
|
|
9
|
+
}
|
|
10
|
+
export interface FacilitatorVerifyResponse {
|
|
11
|
+
success: boolean;
|
|
12
|
+
payerAddress?: string;
|
|
13
|
+
balance?: string;
|
|
14
|
+
requiredAmount?: string;
|
|
15
|
+
error?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface FacilitatorSettleRequest {
|
|
18
|
+
payload: PaymentPayload;
|
|
19
|
+
requirements: Record<string, unknown>;
|
|
20
|
+
}
|
|
21
|
+
export interface FacilitatorSettleResponse {
|
|
22
|
+
success: boolean;
|
|
23
|
+
txHash?: string;
|
|
24
|
+
error?: string;
|
|
25
|
+
}
|
|
26
|
+
export type AnyFacilitatorRequest = FacilitatorVerifyRequest | FacilitatorSettleRequest;
|
|
27
|
+
export type AnyFacilitatorResponse = FacilitatorVerifyResponse | FacilitatorSettleResponse;
|
|
28
|
+
export interface MockFacilitatorOptions {
|
|
29
|
+
port?: number;
|
|
30
|
+
alwaysVerify?: boolean;
|
|
31
|
+
alwaysSettle?: boolean;
|
|
32
|
+
verifyDelay?: number;
|
|
33
|
+
settleDelay?: number;
|
|
34
|
+
}
|
|
35
|
+
export declare const createMockFacilitator: (options?: MockFacilitatorOptions) => Promise<{
|
|
36
|
+
url: string;
|
|
37
|
+
close: () => Promise<void>;
|
|
38
|
+
}>;
|
package/dist/validation.d.ts
CHANGED
|
@@ -2,45 +2,26 @@
|
|
|
2
2
|
* Comprehensive validation for Armory configurations
|
|
3
3
|
* Ensures networks, tokens, and facilitators are compatible
|
|
4
4
|
*/
|
|
5
|
-
import type { NetworkId, TokenId, FacilitatorConfig, ResolvedNetwork, ResolvedToken, ResolvedFacilitator, ResolvedPaymentConfig, ValidationError, PaymentErrorCode } from "./types/simple
|
|
5
|
+
import type { NetworkId, TokenId, FacilitatorConfig, ResolvedNetwork, ResolvedToken, ResolvedFacilitator, ResolvedPaymentConfig, ValidationError, PaymentErrorCode } from "./types/simple";
|
|
6
|
+
export declare const CustomTokenSchema: import("arktype/internal/variants/object.ts").ObjectType<{
|
|
7
|
+
symbol: string;
|
|
8
|
+
name: string;
|
|
9
|
+
version: string;
|
|
10
|
+
contractAddress: `0x${string}`;
|
|
11
|
+
chainId: number;
|
|
12
|
+
decimals?: number | undefined;
|
|
13
|
+
}, {}>;
|
|
6
14
|
export declare const createError: (code: PaymentErrorCode, message: string, details?: Partial<ValidationError>) => ValidationError;
|
|
7
|
-
/**
|
|
8
|
-
* Normalize network name to match registry keys
|
|
9
|
-
*/
|
|
10
15
|
export declare const normalizeNetworkName: (name: string) => string;
|
|
11
|
-
|
|
12
|
-
* Resolve a network identifier to a network config
|
|
13
|
-
*/
|
|
14
|
-
export declare const resolveNetwork: (input: NetworkId) => ResolvedNetwork | ValidationError;
|
|
15
|
-
/**
|
|
16
|
-
* Get all available network names
|
|
17
|
-
*/
|
|
16
|
+
export declare const resolveNetwork: (input: unknown) => ResolvedNetwork | ValidationError;
|
|
18
17
|
export declare const getAvailableNetworks: () => string[];
|
|
19
|
-
|
|
20
|
-
* Resolve a token identifier to a token config
|
|
21
|
-
*/
|
|
22
|
-
export declare const resolveToken: (input: TokenId, network?: ResolvedNetwork) => ResolvedToken | ValidationError;
|
|
23
|
-
/**
|
|
24
|
-
* Get all available token symbols
|
|
25
|
-
*/
|
|
18
|
+
export declare const resolveToken: (input: unknown, network?: ResolvedNetwork) => ResolvedToken | ValidationError;
|
|
26
19
|
export declare const getAvailableTokens: () => string[];
|
|
27
|
-
/**
|
|
28
|
-
* Resolve a facilitator configuration
|
|
29
|
-
*/
|
|
30
20
|
export declare const resolveFacilitator: (input: FacilitatorConfig, supportedNetworks?: ResolvedNetwork[], supportedTokens?: ResolvedToken[]) => ResolvedFacilitator | ValidationError;
|
|
31
|
-
/**
|
|
32
|
-
* Check if a facilitator supports a specific network/token combination
|
|
33
|
-
*/
|
|
34
21
|
export declare const checkFacilitatorSupport: (facilitator: ResolvedFacilitator, network: ResolvedNetwork, token: ResolvedToken) => ValidationError | {
|
|
35
22
|
supported: true;
|
|
36
23
|
};
|
|
37
|
-
/**
|
|
38
|
-
* Validate a complete payment configuration
|
|
39
|
-
*/
|
|
40
24
|
export declare const validatePaymentConfig: (network: NetworkId, token: TokenId, facilitators?: FacilitatorConfig | FacilitatorConfig[], payTo?: string, amount?: string) => ResolvedPaymentConfig | ValidationError;
|
|
41
|
-
/**
|
|
42
|
-
* Validate multi-accept configuration (for merchants)
|
|
43
|
-
*/
|
|
44
25
|
export declare const validateAcceptConfig: (options: {
|
|
45
26
|
networks?: NetworkId[];
|
|
46
27
|
tokens?: TokenId[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@armory-sh/base",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.13",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Sawyer Cutler <sawyer@dirtroad.dev>",
|
|
6
6
|
"type": "module",
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"directory": "packages/core"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
+
"arktype": "^2.1.29",
|
|
30
31
|
"viem": "2.45.0"
|
|
31
32
|
},
|
|
32
33
|
"devDependencies": {
|
|
@@ -35,7 +36,8 @@
|
|
|
35
36
|
"typescript": "5.9.3"
|
|
36
37
|
},
|
|
37
38
|
"scripts": {
|
|
38
|
-
"build": "tsup && tsc --emitDeclarationOnly",
|
|
39
|
-
"test": "bun test"
|
|
39
|
+
"build": "rm -rf dist && tsup && tsc --emitDeclarationOnly",
|
|
40
|
+
"test": "bun test",
|
|
41
|
+
"typecheck": "tsc --noEmit"
|
|
40
42
|
}
|
|
41
|
-
}
|
|
43
|
+
}
|