@x402x/extensions 2.3.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- import { Network, PaymentRequirements, ResourceServerExtension, SchemeNetworkFacilitator, PaymentPayload, SchemeNetworkClient } from '@x402/core/types';
1
+ import { Network, PaymentRequirements, ResourceServerExtension, SchemeNetworkFacilitator, PaymentPayload } from '@x402/core/types';
2
2
  export { Network, PaymentPayload, PaymentRequirements } from '@x402/core/types';
3
3
  import { Chain, Address as Address$1 } from 'viem';
4
4
  import { x402ResourceServer } from '@x402/core/server';
5
- import { x402Client } from '@x402/core/client';
5
+ export { ClientEvmSigner, ExactEvmSchemeWithRouterSettlement, injectX402xExtensionHandler, registerX402xScheme } from './client/index.js';
6
+ import '@x402/core/client';
6
7
 
7
8
  /**
8
9
  * Type definitions for @x402x/extensions
@@ -1888,183 +1889,4 @@ declare function getNetworkAliasesV1ToV2(): Record<string, Network>;
1888
1889
  */
1889
1890
  declare function toCanonicalNetworkKey(network: string): Network;
1890
1891
 
1891
- /**
1892
- * x402x EVM Client Scheme with Router Settlement
1893
- *
1894
- * This scheme extends the standard EVM exact scheme to support x402x router settlement.
1895
- * The key difference is using a commitment hash (binding all settlement parameters)
1896
- * as the EIP-3009 nonce instead of a random value.
1897
- */
1898
-
1899
- /**
1900
- * Client EVM signer interface
1901
- * Compatible with viem WalletClient and LocalAccount
1902
- */
1903
- type ClientEvmSigner = {
1904
- readonly address: `0x${string}`;
1905
- signTypedData(message: {
1906
- domain: Record<string, unknown>;
1907
- types: Record<string, unknown>;
1908
- primaryType: string;
1909
- message: Record<string, unknown>;
1910
- }): Promise<`0x${string}`>;
1911
- };
1912
- /**
1913
- * EVM client implementation for the Exact payment scheme with x402x router settlement.
1914
- *
1915
- * This scheme uses a commitment hash as the EIP-3009 nonce to cryptographically bind
1916
- * all settlement parameters (salt, hook, hookData, etc.) to the user's signature,
1917
- * preventing parameter tampering attacks.
1918
- *
1919
- * @example
1920
- * ```typescript
1921
- * import { ExactEvmSchemeWithRouterSettlement } from '@x402x/extensions/client';
1922
- * import { x402Client } from '@x402/core/client';
1923
- *
1924
- * const signer = { address, signTypedData }; // viem WalletClient or LocalAccount
1925
- * const scheme = new ExactEvmSchemeWithRouterSettlement(signer);
1926
- *
1927
- * const client = new x402Client()
1928
- * .register('eip155:84532', scheme);
1929
- * ```
1930
- */
1931
- declare class ExactEvmSchemeWithRouterSettlement implements SchemeNetworkClient {
1932
- private readonly signer;
1933
- readonly scheme = "exact";
1934
- /**
1935
- * Per-request router settlement extension (typically sourced from PaymentRequired.extensions).
1936
- *
1937
- * IMPORTANT: We do NOT put this on `paymentRequirements.extra`, because for x402 v2 the
1938
- * server matches paid requests by deep-equality between `paymentPayload.accepted` and the
1939
- * server-side `accepts[]`. Mutating `accepted` will cause "No matching payment requirements".
1940
- */
1941
- private routerSettlementFromPaymentRequired?;
1942
- /**
1943
- * Creates a new ExactEvmSchemeWithRouterSettlement instance.
1944
- *
1945
- * @param signer - The EVM signer for client operations (viem WalletClient or LocalAccount)
1946
- */
1947
- constructor(signer: ClientEvmSigner);
1948
- /**
1949
- * Set router-settlement extension data for the next payment payload creation.
1950
- *
1951
- * Intended to be called from an `x402Client.onBeforePaymentCreation` hook, which has access
1952
- * to `paymentRequired.extensions`.
1953
- */
1954
- setRouterSettlementExtensionFromPaymentRequired(ext: unknown | undefined): void;
1955
- /**
1956
- * Creates a payment payload for the Exact scheme with router settlement.
1957
- *
1958
- * This method:
1959
- * 1. Extracts settlement parameters from PaymentRequired.extensions
1960
- * 2. Calculates a commitment hash binding all parameters
1961
- * 3. Uses the commitment as the EIP-3009 nonce
1962
- * 4. Signs with settlementRouter as the 'to' address
1963
- *
1964
- * @param x402Version - The x402 protocol version (must be 2)
1965
- * @param paymentRequirements - The payment requirements from the server
1966
- * @returns Promise resolving to a payment payload
1967
- *
1968
- * @throws Error if x402Version is not 2
1969
- * @throws Error if x402x-router-settlement extension is missing
1970
- * @throws Error if required settlement parameters are missing
1971
- */
1972
- createPaymentPayload(x402Version: number, paymentRequirements: PaymentRequirements): Promise<Pick<PaymentPayload, "x402Version" | "payload">>;
1973
- /**
1974
- * Sign the EIP-3009 authorization using EIP-712
1975
- *
1976
- * @param authorization - The authorization to sign
1977
- * @param requirements - The payment requirements
1978
- * @param chainId - The chain ID
1979
- * @returns Promise resolving to the signature
1980
- */
1981
- private signAuthorization;
1982
- }
1983
-
1984
- /**
1985
- * x402x Extension Handler
1986
- *
1987
- * Provides utilities to integrate x402x router settlement with official x402 SDK.
1988
- *
1989
- * The challenge: x402 v2 spec places extensions at root level in PaymentRequired,
1990
- * but x402x scheme needs settlement parameters from PaymentRequirements.extra.
1991
- *
1992
- * Solution: Provide two-layer API:
1993
- * 1. High-level: registerX402xScheme() - one line setup (recommended)
1994
- * 2. Low-level: injectX402xExtensionHandler() - flexible configuration
1995
- */
1996
-
1997
- /**
1998
- * Injects x402x extension handler into x402Client (Low-level API).
1999
- *
2000
- * IMPORTANT (x402 v2 + x402x multi-network):
2001
- * - Server returns per-option x402x info in `accepts[i].extra["x402x-router-settlement"]`
2002
- * - x402Client only passes `PaymentRequirements` to scheme (no root extensions)
2003
- * - Facilitator v2 reads from `paymentPayload.extensions["x402x-router-settlement"]`
2004
- *
2005
- * Solution: Copy the selected option's x402x info from `selectedRequirements.extra`
2006
- * into `paymentRequired.extensions` so it gets included in `paymentPayload.extensions`.
2007
- *
2008
- * This does NOT mutate `selectedRequirements` (which becomes `paymentPayload.accepted`),
2009
- * so v2 deepEqual matching still works.
2010
- *
2011
- * @param client - x402Client instance to inject handler into
2012
- * @param onRouterSettlementExtension - Callback to receive the per-request extension object
2013
- * @returns The same client instance for chaining
2014
- *
2015
- * @example Low-level API (for advanced users)
2016
- * ```typescript
2017
- * import { x402Client } from '@x402/core/client';
2018
- * import {
2019
- * injectX402xExtensionHandler,
2020
- * ExactEvmSchemeWithRouterSettlement
2021
- * } from '@x402x/extensions';
2022
- *
2023
- * const client = new x402Client();
2024
- * const scheme = new ExactEvmSchemeWithRouterSettlement(signer);
2025
- * injectX402xExtensionHandler(client, (ext) => scheme.setRouterSettlementExtensionFromPaymentRequired(ext))
2026
- * .register('eip155:84532', scheme);
2027
- * ```
2028
- */
2029
- declare function injectX402xExtensionHandler(client: x402Client, onRouterSettlementExtension?: (extension: unknown | undefined) => void): x402Client;
2030
- /**
2031
- * Register x402x router settlement scheme with automatic extension handling (High-level API).
2032
- *
2033
- * This is the recommended way to set up x402x payments. It combines:
2034
- * 1. Extension handler injection (injectX402xExtensionHandler)
2035
- * 2. Scheme registration (ExactEvmSchemeWithRouterSettlement)
2036
- *
2037
- * Use this for the simplest integration - just provide your signer and network.
2038
- *
2039
- * @param client - x402Client instance
2040
- * @param network - Network identifier in CAIP-2 format (e.g., "eip155:84532")
2041
- * @param signer - EVM signer with address and signTypedData method
2042
- * @returns The client instance for chaining
2043
- *
2044
- * @example High-level API (recommended)
2045
- * ```typescript
2046
- * import { x402Client } from '@x402/core/client';
2047
- * import { registerX402xScheme } from '@x402x/extensions';
2048
- * import { useWalletClient } from 'wagmi';
2049
- *
2050
- * const { data: walletClient } = useWalletClient();
2051
- *
2052
- * const client = new x402Client();
2053
- * registerX402xScheme(client, 'eip155:84532', {
2054
- * address: walletClient.account.address,
2055
- * signTypedData: walletClient.signTypedData,
2056
- * });
2057
- *
2058
- * // That's it! Client is ready for x402x payments
2059
- * ```
2060
- *
2061
- * @example Multiple networks
2062
- * ```typescript
2063
- * const client = new x402Client();
2064
- * registerX402xScheme(client, 'eip155:84532', signer); // Base Sepolia
2065
- * registerX402xScheme(client, 'eip155:8453', signer); // Base Mainnet
2066
- * ```
2067
- */
2068
- declare function registerX402xScheme(client: x402Client, network: Network, signer: ClientEvmSigner): x402Client;
2069
-
2070
- export { type Address, AmountError, type ClientEvmSigner, type CommitmentParams, type DemoHooks, ExactEvmSchemeWithRouterSettlement, type FacilitatorConfig, type SettleResponse$1 as FacilitatorSettleResponse, FacilitatorValidationError, type VerifyResponse$1 as FacilitatorVerifyResponse, type FeeCalculationResult, type RouteConfig as LegacyRouteConfig, type MintConfig, type Money, NETWORK_ALIASES, NETWORK_ALIASES_V1_TO_V2, NFTMintHook, type NetworkConfig, ROUTER_SETTLEMENT_KEY, type Resource, type RewardConfig, RewardHook, type RoutePattern, type RouterSettlementExtension, type RouterSettlementExtensionInfo, type RoutesConfig, SETTLEMENT_ROUTER_ABI, type SettleResponse, type SettlementExtra, type SettlementExtraCore, SettlementExtraError, type SettlementHooksConfig, type SettlementOptions, type SettlementPaymentOption, type SettlementRouteConfig, SettlementRouterError, type SettlementRouterParams, type Signer, TransferHook, type ValidationResult, type VerifyResponse, type WithRouterSettlementOptions, addSettlementExtra, assertValidSettlementExtra, calculateCommitment, calculateFacilitatorFee, clearFeeCache, computeRoutePatterns, createExtensionDeclaration, createRouterSettlementExtension, createSettlementRouteConfig, createX402xFacilitator, findMatchingPaymentRequirements, findMatchingRoute, formatDefaultAssetAmount, generateSalt, getChain, getChainById, getCustomChains, getDefaultAsset, getNetworkAlias, getNetworkAliasesV1ToV2, getNetworkConfig, getRouterSettlementExtensionKey, getSupportedNetworkAliases, getSupportedNetworkIds, getSupportedNetworks, injectX402xExtensionHandler, isCustomChain, isNetworkSupported, isRouterSettlement, isSettlementMode, isValid32ByteHex, isValidAddress, isValidHex, isValidNumericString, networks, parseDefaultAssetAmount, parseSettlementExtra, processPriceToAtomicAmount, registerRouterSettlement, registerSettlementHooks, registerX402xScheme, routerSettlementServerExtension, settle, toCanonicalNetworkKey, toJsonSafe, validateCommitmentParams, validateSettlementExtra, verify, withRouterSettlement };
1892
+ export { type Address, AmountError, type CommitmentParams, type DemoHooks, type FacilitatorConfig, type SettleResponse$1 as FacilitatorSettleResponse, FacilitatorValidationError, type VerifyResponse$1 as FacilitatorVerifyResponse, type FeeCalculationResult, type RouteConfig as LegacyRouteConfig, type MintConfig, type Money, NETWORK_ALIASES, NETWORK_ALIASES_V1_TO_V2, NFTMintHook, type NetworkConfig, ROUTER_SETTLEMENT_KEY, type Resource, type RewardConfig, RewardHook, type RoutePattern, type RouterSettlementExtension, type RouterSettlementExtensionInfo, type RoutesConfig, SETTLEMENT_ROUTER_ABI, type SettleResponse, type SettlementExtra, type SettlementExtraCore, SettlementExtraError, type SettlementHooksConfig, type SettlementOptions, type SettlementPaymentOption, type SettlementRouteConfig, SettlementRouterError, type SettlementRouterParams, type Signer, TransferHook, type ValidationResult, type VerifyResponse, type WithRouterSettlementOptions, addSettlementExtra, assertValidSettlementExtra, calculateCommitment, calculateFacilitatorFee, clearFeeCache, computeRoutePatterns, createExtensionDeclaration, createRouterSettlementExtension, createSettlementRouteConfig, createX402xFacilitator, findMatchingPaymentRequirements, findMatchingRoute, formatDefaultAssetAmount, generateSalt, getChain, getChainById, getCustomChains, getDefaultAsset, getNetworkAlias, getNetworkAliasesV1ToV2, getNetworkConfig, getRouterSettlementExtensionKey, getSupportedNetworkAliases, getSupportedNetworkIds, getSupportedNetworks, isCustomChain, isNetworkSupported, isRouterSettlement, isSettlementMode, isValid32ByteHex, isValidAddress, isValidHex, isValidNumericString, networks, parseDefaultAssetAmount, parseSettlementExtra, processPriceToAtomicAmount, registerRouterSettlement, registerSettlementHooks, routerSettlementServerExtension, settle, toCanonicalNetworkKey, toJsonSafe, validateCommitmentParams, validateSettlementExtra, verify, withRouterSettlement };
package/dist/index.js CHANGED
@@ -201,10 +201,17 @@ function isValidHex(hex) {
201
201
  var NETWORK_ALIASES_V1_TO_V2 = {
202
202
  // V1 human-readable names -> V2 CAIP-2 canonical keys
203
203
  "base-sepolia": "eip155:84532",
204
+ "xlayer-testnet": "eip155:1952",
205
+ // Legacy alias for backward compatibility
204
206
  "x-layer-testnet": "eip155:1952",
207
+ // Canonical alias (must come after legacy to override)
205
208
  "skale-base-sepolia": "eip155:324705682",
209
+ "skale-base": "eip155:1187947933",
206
210
  base: "eip155:8453",
211
+ xlayer: "eip155:196",
212
+ // Legacy alias for backward compatibility
207
213
  "x-layer": "eip155:196",
214
+ // Canonical alias (must come after legacy to override)
208
215
  "bsc-testnet": "eip155:97",
209
216
  bsc: "eip155:56"
210
217
  };
@@ -273,6 +280,14 @@ var DEFAULT_ASSETS = {
273
280
  name: "x402 Wrapped USDT",
274
281
  version: "1"
275
282
  }
283
+ },
284
+ "eip155:1187947933": {
285
+ address: "0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",
286
+ decimals: 6,
287
+ eip712: {
288
+ name: "Bridged USDC (SKALE Bridge)",
289
+ version: "2"
290
+ }
276
291
  }
277
292
  };
278
293
  function getNetworkAlias(network) {
@@ -437,7 +452,7 @@ var networks = {
437
452
  },
438
453
  metadata: {
439
454
  gasModel: "legacy",
440
- nativeToken: "Credits"
455
+ nativeToken: "CREDIT"
441
456
  }
442
457
  },
443
458
  "eip155:97": {
@@ -528,6 +543,28 @@ var networks = {
528
543
  gasModel: "legacy",
529
544
  nativeToken: "BNB"
530
545
  }
546
+ },
547
+ "eip155:1187947933": {
548
+ chainId: 1187947933,
549
+ name: "SKALE on Base",
550
+ type: "mainnet",
551
+ addressExplorerBaseUrl: "https://skale-base-explorer.skalenodes.com/address/",
552
+ txExplorerBaseUrl: "https://skale-base-explorer.skalenodes.com/tx/",
553
+ settlementRouter: "0x1Ae0E196dC18355aF3a19985faf67354213F833D",
554
+ defaultAsset: getDefaultAssetConfig("eip155:1187947933"),
555
+ hooks: {
556
+ transfer: "0x2f05fe5674aE756E25C26855258B4877E9e021Fd"
557
+ },
558
+ demoHooks: {
559
+ nftMint: "0x73fc659Cd5494E69852bE8D9D23FE05Aab14b29B",
560
+ randomNFT: "0x081258287F692D61575387ee2a4075f34dd7Aef7",
561
+ reward: "0xC20634ea518985901e32Fbc1bA27fa673D37601A",
562
+ rewardToken: "0x9Fc2c199170B039f093ABCd54008038F0C0a31d6"
563
+ },
564
+ metadata: {
565
+ gasModel: "legacy",
566
+ nativeToken: "CREDIT"
567
+ }
531
568
  }
532
569
  };
533
570
  function getNetworkConfig(network) {
@@ -572,16 +609,16 @@ var customChains = {
572
609
  324705682: viem.defineChain({
573
610
  id: 324705682,
574
611
  name: "SKALE Nebula Testnet",
575
- nativeCurrency: { name: "sFUEL", symbol: "sFUEL", decimals: 18 },
612
+ nativeCurrency: { name: "CREDIT", symbol: "CREDIT", decimals: 18 },
576
613
  rpcUrls: {
577
614
  default: {
578
- http: ["https://testnet.skalenodes.com/v1/lanky-ill-funny-testnet"]
615
+ http: ["https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha"]
579
616
  }
580
617
  },
581
618
  blockExplorers: {
582
619
  default: {
583
620
  name: "SKALE Explorer",
584
- url: "https://lanky-ill-funny-testnet.explorer.testnet.skalenodes.com"
621
+ url: "https://base-sepolia-testnet-explorer.skalenodes.com"
585
622
  }
586
623
  },
587
624
  testnet: true
@@ -598,6 +635,22 @@ var customChains = {
598
635
  default: { name: "OKLink", url: "https://www.oklink.com/xlayer" }
599
636
  },
600
637
  testnet: false
638
+ }),
639
+ // SKALE Base Mainnet
640
+ 1187947933: viem.defineChain({
641
+ id: 1187947933,
642
+ name: "SKALE Base",
643
+ nativeCurrency: { name: "CREDIT", symbol: "CREDIT", decimals: 18 },
644
+ rpcUrls: {
645
+ default: { http: ["https://skale-base.skalenodes.com/v1/base"] }
646
+ },
647
+ blockExplorers: {
648
+ default: {
649
+ name: "SKALE Explorer",
650
+ url: "https://skale-base-explorer.skalenodes.com"
651
+ }
652
+ },
653
+ testnet: false
601
654
  })
602
655
  };
603
656
  function getChain(network) {
@@ -771,6 +824,28 @@ exports.RewardHook = void 0;
771
824
  })(exports.RewardHook || (exports.RewardHook = {}));
772
825
 
773
826
  // src/validation.ts
827
+ function validateX402Version(version) {
828
+ if (typeof version === "number" && version === 2) {
829
+ return;
830
+ }
831
+ const baseMessage = "x402Version is required and must be 2. v1 is deprecated - please use x402Version=2. See https://github.com/nuwa-protocol/x402-exec for migration guide.";
832
+ if (version === void 0 || version === null) {
833
+ throw new Error(baseMessage);
834
+ }
835
+ if (typeof version !== "number") {
836
+ throw new Error(
837
+ `Invalid x402Version: expected number, got ${typeof version}. ${baseMessage}`
838
+ );
839
+ }
840
+ if (version === 1) {
841
+ throw new Error(
842
+ "x402Version 1 is deprecated. Please use x402Version=2. See https://github.com/nuwa-protocol/x402-exec for migration guide."
843
+ );
844
+ }
845
+ throw new Error(
846
+ `Version not supported: x402Version ${version} is not supported. Please use x402Version=2. See https://github.com/nuwa-protocol/x402-exec for migration guide.`
847
+ );
848
+ }
774
849
  function isValidAddress2(address) {
775
850
  return /^0x[a-fA-F0-9]{40}$/.test(address);
776
851
  }
@@ -1076,7 +1151,9 @@ async function verify(facilitatorUrl, paymentPayload, paymentRequirements) {
1076
1151
  },
1077
1152
  body: JSON.stringify({
1078
1153
  paymentPayload,
1079
- paymentRequirements
1154
+ paymentRequirements,
1155
+ x402Version: paymentPayload.x402Version ?? 2
1156
+ // Include x402Version at top level, default to 2
1080
1157
  }),
1081
1158
  // Add timeout
1082
1159
  signal: AbortSignal.timeout(1e4)
@@ -1115,7 +1192,9 @@ async function settle(facilitatorUrl, paymentPayload, paymentRequirements, timeo
1115
1192
  },
1116
1193
  body: JSON.stringify({
1117
1194
  paymentPayload,
1118
- paymentRequirements
1195
+ paymentRequirements,
1196
+ x402Version: paymentPayload.x402Version ?? 2
1197
+ // Include x402Version at top level, default to 2
1119
1198
  }),
1120
1199
  signal: controller.signal
1121
1200
  });
@@ -1290,6 +1369,7 @@ function registerSettlementHooks(server, config = {}) {
1290
1369
  if (enableSaltExtraction) {
1291
1370
  server.onBeforeVerify(async (context) => {
1292
1371
  const { paymentPayload, requirements } = context;
1372
+ validateX402Version(paymentPayload.x402Version);
1293
1373
  if (paymentPayload.extensions && "x402x-router-settlement" in paymentPayload.extensions) {
1294
1374
  const extension = paymentPayload.extensions["x402x-router-settlement"];
1295
1375
  if (extension?.info) {
@@ -1313,6 +1393,7 @@ function registerSettlementHooks(server, config = {}) {
1313
1393
  if (validateSettlementParams) {
1314
1394
  server.onBeforeSettle(async (context) => {
1315
1395
  const { paymentPayload, requirements } = context;
1396
+ validateX402Version(paymentPayload.x402Version);
1316
1397
  let settlementParams = {};
1317
1398
  if (paymentPayload.extensions && "x402x-router-settlement" in paymentPayload.extensions) {
1318
1399
  const extension = paymentPayload.extensions["x402x-router-settlement"];