@x402/evm 2.9.0 → 2.10.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/README.md CHANGED
@@ -145,7 +145,7 @@ Supports two asset transfer methods:
145
145
  - **EIP-3009**: Tokens with native `transferWithAuthorization()` (e.g., USDC, EURC) — simplest, truly gasless
146
146
  - **Permit2**: Any ERC-20 token — universal fallback, requires one-time approval
147
147
 
148
- See [DEFAULT_ASSET.md](src/exact/server/DEFAULT_ASSET.md) for the current list of configured chains and how to add new ones.
148
+ See [DEFAULT_ASSETS.md](../../../../DEFAULT_ASSETS.md) for the current list of configured chains and how to add new ones.
149
149
 
150
150
  ## Development
151
151
 
@@ -90,8 +90,17 @@ var DEFAULT_STABLECOINS = {
90
90
  name: "USD Coin",
91
91
  version: "2",
92
92
  decimals: 6
93
- }
93
+ },
94
94
  // Arbitrum Sepolia USDC
95
+ "eip155:31611": {
96
+ address: "0x118917a40FAF1CD7a13dB0Ef56C86De7973Ac503",
97
+ name: "Mezo USD",
98
+ version: "1",
99
+ decimals: 18,
100
+ assetTransferMethod: "permit2",
101
+ supportsEip2612: true
102
+ }
103
+ // Mezo Testnet mUSD (no EIP-3009, supports EIP-2612)
95
104
  };
96
105
  function getDefaultAsset(network) {
97
106
  const info = DEFAULT_STABLECOINS[network];
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/exact/server/index.ts","../../../../src/shared/defaultAssets.ts","../../../../src/exact/server/scheme.ts","../../../../src/exact/server/register.ts"],"sourcesContent":["export { ExactEvmScheme } from \"./scheme\";\nexport { registerExactEvmScheme } from \"./register\";\nexport type { EvmResourceServerConfig } from \"./register\";\n","import type { Network } from \"@x402/core/types\";\n\n/**\n * Base stablecoin asset configuration shared across all EVM payment schemes.\n * Contains the core fields needed to identify and convert tokens.\n */\nexport type DefaultAssetInfo = {\n /** Token contract address */\n address: string;\n /** EIP-712 domain name (must match the token's domain separator) */\n name: string;\n /** EIP-712 domain version (must match the token's domain separator) */\n version: string;\n /** Token decimal places (typically 6 for USDC) */\n decimals: number;\n};\n\n/**\n * Extended asset configuration for the exact scheme.\n * Includes transfer method hints that control client-side behaviour.\n */\nexport type ExactDefaultAssetInfo = DefaultAssetInfo & {\n /**\n * Transfer method override: `\"permit2\"` for tokens that don't support EIP-3009.\n * Omit for EIP-3009 tokens (default behaviour).\n */\n assetTransferMethod?: string;\n /**\n * Set to `true` for permit2 tokens that implement EIP-2612 `permit()`.\n * Controls whether name/version are included in `extra` so the client can\n * sign a gasless EIP-2612 permit for Permit2 approval.\n */\n supportsEip2612?: boolean;\n};\n\n/**\n * Default stablecoins indexed by CAIP-2 network identifier.\n *\n * Each network has the right to determine its own default stablecoin that can\n * be expressed as a USD string by calling servers. See DEFAULT_ASSET.md in\n * exact/server/ for how to add new chains.\n */\nexport const DEFAULT_STABLECOINS: Record<string, ExactDefaultAssetInfo> = {\n \"eip155:8453\": {\n address: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Base mainnet USDC\n \"eip155:84532\": {\n address: \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\",\n name: \"USDC\",\n version: \"2\",\n decimals: 6,\n }, // Base Sepolia USDC\n \"eip155:4326\": {\n address: \"0xFAfDdbb3FC7688494971a79cc65DCa3EF82079E7\",\n name: \"MegaUSD\",\n version: \"1\",\n decimals: 18,\n assetTransferMethod: \"permit2\",\n supportsEip2612: true,\n }, // MegaETH mainnet MegaUSD (no EIP-3009, supports EIP-2612)\n \"eip155:143\": {\n address: \"0x754704Bc059F8C67012fEd69BC8A327a5aafb603\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Monad mainnet USDC\n \"eip155:988\": {\n address: \"0x779Ded0c9e1022225f8E0630b35a9b54bE713736\",\n name: \"USDT0\",\n version: \"1\",\n decimals: 6,\n }, // Stable mainnet USDT0\n \"eip155:2201\": {\n address: \"0x78Cf24370174180738C5B8E352B6D14c83a6c9A9\",\n name: \"USDT0\",\n version: \"1\",\n decimals: 6,\n }, // Stable testnet USDT0\n \"eip155:137\": {\n address: \"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Polygon mainnet USDC\n \"eip155:42161\": {\n address: \"0xaf88d065e77c8cC2239327C5EDb3A432268e5831\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Arbitrum One USDC\n \"eip155:421614\": {\n address: \"0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Arbitrum Sepolia USDC\n};\n\n/**\n * Look up the default stablecoin for a network.\n *\n * @param network - CAIP-2 network identifier (e.g. \"eip155:8453\")\n * @returns The default asset info\n * @throws If no default asset is configured for the network\n */\nexport function getDefaultAsset(network: Network): ExactDefaultAssetInfo {\n const info = DEFAULT_STABLECOINS[network];\n if (!info) {\n throw new Error(`No default asset configured for network ${network}`);\n }\n return info;\n}\n","import {\n AssetAmount,\n Network,\n PaymentRequirements,\n Price,\n SchemeNetworkServer,\n MoneyParser,\n} from \"@x402/core/types\";\nimport { getDefaultAsset, type ExactDefaultAssetInfo } from \"../../shared/defaultAssets\";\n\n/**\n * EVM server implementation for the Exact payment scheme.\n */\nexport class ExactEvmScheme implements SchemeNetworkServer {\n readonly scheme = \"exact\";\n private moneyParsers: MoneyParser[] = [];\n\n /**\n * Register a custom money parser in the parser chain.\n * Multiple parsers can be registered - they will be tried in registration order.\n * Each parser receives a decimal amount (e.g., 1.50 for $1.50).\n * If a parser returns null, the next parser in the chain will be tried.\n * The default parser is always the final fallback.\n *\n * @param parser - Custom function to convert amount to AssetAmount (or null to skip)\n * @returns The server instance for chaining\n *\n * @example\n * evmServer.registerMoneyParser(async (amount, network) => {\n * // Custom conversion logic\n * if (amount > 100) {\n * // Use different token for large amounts\n * return { amount: (amount * 1e18).toString(), asset: \"0xCustomToken\" };\n * }\n * return null; // Use next parser\n * });\n */\n registerMoneyParser(parser: MoneyParser): ExactEvmScheme {\n this.moneyParsers.push(parser);\n return this;\n }\n\n /**\n * Returns the decimal precision of the default stablecoin for the given network.\n * Implements the optional AssetDecimalsProvider interface used by resolveSettlementOverrideAmount.\n *\n * @param _asset - The asset symbol (unused; defaults to the network's default stablecoin)\n * @param network - The network to look up the default asset for\n * @returns The number of decimal places for the asset\n */\n getAssetDecimals(_asset: string, network: Network): number {\n try {\n return getDefaultAsset(network).decimals;\n } catch {\n return 6;\n }\n }\n\n /**\n * Parses a price into an asset amount.\n * If price is already an AssetAmount, returns it directly.\n * If price is Money (string | number), parses to decimal and tries custom parsers.\n * Falls back to default conversion if all custom parsers return null.\n *\n * @param price - The price to parse\n * @param network - The network to use\n * @returns Promise that resolves to the parsed asset amount\n */\n async parsePrice(price: Price, network: Network): Promise<AssetAmount> {\n // If already an AssetAmount, return it directly\n if (typeof price === \"object\" && price !== null && \"amount\" in price) {\n if (!price.asset) {\n throw new Error(`Asset address must be specified for AssetAmount on network ${network}`);\n }\n return {\n amount: price.amount,\n asset: price.asset,\n extra: price.extra || {},\n };\n }\n\n // Parse Money to decimal number\n const amount = this.parseMoneyToDecimal(price);\n\n // Try each custom money parser in order\n for (const parser of this.moneyParsers) {\n const result = await parser(amount, network);\n if (result !== null) {\n return result;\n }\n }\n\n // All custom parsers returned null, use default conversion\n return this.defaultMoneyConversion(amount, network);\n }\n\n /**\n * Build payment requirements for this scheme/network combination\n *\n * @param paymentRequirements - The base payment requirements\n * @param supportedKind - The supported kind from facilitator (unused)\n * @param supportedKind.x402Version - The x402 version\n * @param supportedKind.scheme - The logical payment scheme\n * @param supportedKind.network - The network identifier in CAIP-2 format\n * @param supportedKind.extra - Optional extra metadata regarding scheme/network implementation details\n * @param extensionKeys - Extension keys supported by the facilitator (unused)\n * @returns Payment requirements ready to be sent to clients\n */\n enhancePaymentRequirements(\n paymentRequirements: PaymentRequirements,\n supportedKind: {\n x402Version: number;\n scheme: string;\n network: Network;\n extra?: Record<string, unknown>;\n },\n extensionKeys: string[],\n ): Promise<PaymentRequirements> {\n // Mark unused parameters to satisfy linter\n void supportedKind;\n void extensionKeys;\n return Promise.resolve(paymentRequirements);\n }\n\n /**\n * Parse Money (string | number) to a decimal number.\n * Handles formats like \"$1.50\", \"1.50\", 1.50, etc.\n *\n * @param money - The money value to parse\n * @returns Decimal number\n */\n private parseMoneyToDecimal(money: string | number): number {\n if (typeof money === \"number\") {\n return money;\n }\n\n // Remove $ sign and whitespace, then parse\n const cleanMoney = money.replace(/^\\$/, \"\").trim();\n const amount = parseFloat(cleanMoney);\n\n if (isNaN(amount)) {\n throw new Error(`Invalid money format: ${money}`);\n }\n\n return amount;\n }\n\n /**\n * Converts a numeric dollar amount to an AssetAmount using the default token for the network.\n *\n * @param amount - The dollar amount as a number\n * @param network - The target network\n * @returns The converted asset amount with token metadata\n */\n private defaultMoneyConversion(amount: number, network: Network): AssetAmount {\n const assetInfo: ExactDefaultAssetInfo = getDefaultAsset(network);\n const tokenAmount = this.convertToTokenAmount(amount.toString(), assetInfo.decimals);\n\n // EIP-3009 tokens always need name/version for their transferWithAuthorization domain.\n // Permit2 tokens only need them if the token supports EIP-2612 (for gasless permit signing).\n // Omitting name/version for permit2 tokens signals the client to skip EIP-2612 and use\n // ERC-20 approval gas sponsoring instead.\n const includeEip712Domain = !assetInfo.assetTransferMethod || assetInfo.supportsEip2612;\n\n return {\n amount: tokenAmount,\n asset: assetInfo.address,\n extra: {\n ...(includeEip712Domain && {\n name: assetInfo.name,\n version: assetInfo.version,\n }),\n ...(assetInfo.assetTransferMethod && {\n assetTransferMethod: assetInfo.assetTransferMethod,\n }),\n },\n };\n }\n\n /**\n * Converts a decimal string amount to an integer token amount using the given decimals.\n *\n * @param decimalAmount - The amount as a decimal string (e.g. \"1.5\")\n * @param decimals - The number of decimal places for the token\n * @returns The token amount as an integer string in smallest units\n */\n private convertToTokenAmount(decimalAmount: string, decimals: number): string {\n const amount = parseFloat(decimalAmount);\n if (isNaN(amount)) {\n throw new Error(`Invalid amount: ${decimalAmount}`);\n }\n const [intPart, decPart = \"\"] = String(amount).split(\".\");\n const paddedDec = decPart.padEnd(decimals, \"0\").slice(0, decimals);\n const tokenAmount = (intPart + paddedDec).replace(/^0+/, \"\") || \"0\";\n return tokenAmount;\n }\n}\n","import { x402ResourceServer } from \"@x402/core/server\";\nimport { Network } from \"@x402/core/types\";\nimport { ExactEvmScheme } from \"./scheme\";\n\n/**\n * Configuration options for registering EVM schemes to an x402ResourceServer\n */\nexport interface EvmResourceServerConfig {\n /**\n * Optional specific networks to register\n * If not provided, registers wildcard support (eip155:*)\n */\n networks?: Network[];\n}\n\n/**\n * Registers EVM exact payment schemes to an x402ResourceServer instance.\n *\n * This function registers:\n * - V2: eip155:* wildcard scheme with ExactEvmScheme (or specific networks if provided)\n *\n * @param server - The x402ResourceServer instance to register schemes to\n * @param config - Configuration for EVM resource server registration\n * @returns The server instance for chaining\n *\n * @example\n * ```typescript\n * import { registerExactEvmScheme } from \"@x402/evm/exact/server/register\";\n * import { x402ResourceServer } from \"@x402/core/server\";\n *\n * const server = new x402ResourceServer(facilitatorClient);\n * registerExactEvmScheme(server, {});\n * ```\n */\nexport function registerExactEvmScheme(\n server: x402ResourceServer,\n config: EvmResourceServerConfig = {},\n): x402ResourceServer {\n // Register V2 scheme\n if (config.networks && config.networks.length > 0) {\n // Register specific networks\n config.networks.forEach(network => {\n server.register(network, new ExactEvmScheme());\n });\n } else {\n // Register wildcard for all EVM chains\n server.register(\"eip155:*\", new ExactEvmScheme());\n }\n\n return server;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/exact/server/index.ts","../../../../src/shared/defaultAssets.ts","../../../../src/exact/server/scheme.ts","../../../../src/exact/server/register.ts"],"sourcesContent":["export { ExactEvmScheme } from \"./scheme\";\nexport { registerExactEvmScheme } from \"./register\";\nexport type { EvmResourceServerConfig } from \"./register\";\n","import type { Network } from \"@x402/core/types\";\n\n/**\n * Base stablecoin asset configuration shared across all EVM payment schemes.\n * Contains the core fields needed to identify and convert tokens.\n */\nexport type DefaultAssetInfo = {\n /** Token contract address */\n address: string;\n /** EIP-712 domain name (must match the token's domain separator) */\n name: string;\n /** EIP-712 domain version (must match the token's domain separator) */\n version: string;\n /** Token decimal places (typically 6 for USDC) */\n decimals: number;\n};\n\n/**\n * Extended asset configuration for the exact scheme.\n * Includes transfer method hints that control client-side behaviour.\n */\nexport type ExactDefaultAssetInfo = DefaultAssetInfo & {\n /**\n * Transfer method override: `\"permit2\"` for tokens that don't support EIP-3009.\n * Omit for EIP-3009 tokens (default behaviour).\n */\n assetTransferMethod?: string;\n /**\n * Set to `true` for permit2 tokens that implement EIP-2612 `permit()`.\n * Controls whether name/version are included in `extra` so the client can\n * sign a gasless EIP-2612 permit for Permit2 approval.\n */\n supportsEip2612?: boolean;\n};\n\n/**\n * Default stablecoins indexed by CAIP-2 network identifier.\n *\n * Each network has the right to determine its own default stablecoin that can\n * be expressed as a USD string by calling servers. See DEFAULT_ASSET.md in\n * exact/server/ for how to add new chains.\n */\nexport const DEFAULT_STABLECOINS: Record<string, ExactDefaultAssetInfo> = {\n \"eip155:8453\": {\n address: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Base mainnet USDC\n \"eip155:84532\": {\n address: \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\",\n name: \"USDC\",\n version: \"2\",\n decimals: 6,\n }, // Base Sepolia USDC\n \"eip155:4326\": {\n address: \"0xFAfDdbb3FC7688494971a79cc65DCa3EF82079E7\",\n name: \"MegaUSD\",\n version: \"1\",\n decimals: 18,\n assetTransferMethod: \"permit2\",\n supportsEip2612: true,\n }, // MegaETH mainnet MegaUSD (no EIP-3009, supports EIP-2612)\n \"eip155:143\": {\n address: \"0x754704Bc059F8C67012fEd69BC8A327a5aafb603\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Monad mainnet USDC\n \"eip155:988\": {\n address: \"0x779Ded0c9e1022225f8E0630b35a9b54bE713736\",\n name: \"USDT0\",\n version: \"1\",\n decimals: 6,\n }, // Stable mainnet USDT0\n \"eip155:2201\": {\n address: \"0x78Cf24370174180738C5B8E352B6D14c83a6c9A9\",\n name: \"USDT0\",\n version: \"1\",\n decimals: 6,\n }, // Stable testnet USDT0\n \"eip155:137\": {\n address: \"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Polygon mainnet USDC\n \"eip155:42161\": {\n address: \"0xaf88d065e77c8cC2239327C5EDb3A432268e5831\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Arbitrum One USDC\n \"eip155:421614\": {\n address: \"0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Arbitrum Sepolia USDC\n \"eip155:31611\": {\n address: \"0x118917a40FAF1CD7a13dB0Ef56C86De7973Ac503\",\n name: \"Mezo USD\",\n version: \"1\",\n decimals: 18,\n assetTransferMethod: \"permit2\",\n supportsEip2612: true,\n }, // Mezo Testnet mUSD (no EIP-3009, supports EIP-2612)\n};\n\n/**\n * Look up the default stablecoin for a network.\n *\n * @param network - CAIP-2 network identifier (e.g. \"eip155:8453\")\n * @returns The default asset info\n * @throws If no default asset is configured for the network\n */\nexport function getDefaultAsset(network: Network): ExactDefaultAssetInfo {\n const info = DEFAULT_STABLECOINS[network];\n if (!info) {\n throw new Error(`No default asset configured for network ${network}`);\n }\n return info;\n}\n","import {\n AssetAmount,\n Network,\n PaymentRequirements,\n Price,\n SchemeNetworkServer,\n MoneyParser,\n} from \"@x402/core/types\";\nimport { getDefaultAsset, type ExactDefaultAssetInfo } from \"../../shared/defaultAssets\";\n\n/**\n * EVM server implementation for the Exact payment scheme.\n */\nexport class ExactEvmScheme implements SchemeNetworkServer {\n readonly scheme = \"exact\";\n private moneyParsers: MoneyParser[] = [];\n\n /**\n * Register a custom money parser in the parser chain.\n * Multiple parsers can be registered - they will be tried in registration order.\n * Each parser receives a decimal amount (e.g., 1.50 for $1.50).\n * If a parser returns null, the next parser in the chain will be tried.\n * The default parser is always the final fallback.\n *\n * @param parser - Custom function to convert amount to AssetAmount (or null to skip)\n * @returns The server instance for chaining\n *\n * @example\n * evmServer.registerMoneyParser(async (amount, network) => {\n * // Custom conversion logic\n * if (amount > 100) {\n * // Use different token for large amounts\n * return { amount: (amount * 1e18).toString(), asset: \"0xCustomToken\" };\n * }\n * return null; // Use next parser\n * });\n */\n registerMoneyParser(parser: MoneyParser): ExactEvmScheme {\n this.moneyParsers.push(parser);\n return this;\n }\n\n /**\n * Returns the decimal precision of the default stablecoin for the given network.\n * Implements the optional AssetDecimalsProvider interface used by resolveSettlementOverrideAmount.\n *\n * @param _asset - The asset symbol (unused; defaults to the network's default stablecoin)\n * @param network - The network to look up the default asset for\n * @returns The number of decimal places for the asset\n */\n getAssetDecimals(_asset: string, network: Network): number {\n try {\n return getDefaultAsset(network).decimals;\n } catch {\n return 6;\n }\n }\n\n /**\n * Parses a price into an asset amount.\n * If price is already an AssetAmount, returns it directly.\n * If price is Money (string | number), parses to decimal and tries custom parsers.\n * Falls back to default conversion if all custom parsers return null.\n *\n * @param price - The price to parse\n * @param network - The network to use\n * @returns Promise that resolves to the parsed asset amount\n */\n async parsePrice(price: Price, network: Network): Promise<AssetAmount> {\n // If already an AssetAmount, return it directly\n if (typeof price === \"object\" && price !== null && \"amount\" in price) {\n if (!price.asset) {\n throw new Error(`Asset address must be specified for AssetAmount on network ${network}`);\n }\n return {\n amount: price.amount,\n asset: price.asset,\n extra: price.extra || {},\n };\n }\n\n // Parse Money to decimal number\n const amount = this.parseMoneyToDecimal(price);\n\n // Try each custom money parser in order\n for (const parser of this.moneyParsers) {\n const result = await parser(amount, network);\n if (result !== null) {\n return result;\n }\n }\n\n // All custom parsers returned null, use default conversion\n return this.defaultMoneyConversion(amount, network);\n }\n\n /**\n * Build payment requirements for this scheme/network combination\n *\n * @param paymentRequirements - The base payment requirements\n * @param supportedKind - The supported kind from facilitator (unused)\n * @param supportedKind.x402Version - The x402 version\n * @param supportedKind.scheme - The logical payment scheme\n * @param supportedKind.network - The network identifier in CAIP-2 format\n * @param supportedKind.extra - Optional extra metadata regarding scheme/network implementation details\n * @param extensionKeys - Extension keys supported by the facilitator (unused)\n * @returns Payment requirements ready to be sent to clients\n */\n enhancePaymentRequirements(\n paymentRequirements: PaymentRequirements,\n supportedKind: {\n x402Version: number;\n scheme: string;\n network: Network;\n extra?: Record<string, unknown>;\n },\n extensionKeys: string[],\n ): Promise<PaymentRequirements> {\n // Mark unused parameters to satisfy linter\n void supportedKind;\n void extensionKeys;\n return Promise.resolve(paymentRequirements);\n }\n\n /**\n * Parse Money (string | number) to a decimal number.\n * Handles formats like \"$1.50\", \"1.50\", 1.50, etc.\n *\n * @param money - The money value to parse\n * @returns Decimal number\n */\n private parseMoneyToDecimal(money: string | number): number {\n if (typeof money === \"number\") {\n return money;\n }\n\n // Remove $ sign and whitespace, then parse\n const cleanMoney = money.replace(/^\\$/, \"\").trim();\n const amount = parseFloat(cleanMoney);\n\n if (isNaN(amount)) {\n throw new Error(`Invalid money format: ${money}`);\n }\n\n return amount;\n }\n\n /**\n * Converts a numeric dollar amount to an AssetAmount using the default token for the network.\n *\n * @param amount - The dollar amount as a number\n * @param network - The target network\n * @returns The converted asset amount with token metadata\n */\n private defaultMoneyConversion(amount: number, network: Network): AssetAmount {\n const assetInfo: ExactDefaultAssetInfo = getDefaultAsset(network);\n const tokenAmount = this.convertToTokenAmount(amount.toString(), assetInfo.decimals);\n\n // EIP-3009 tokens always need name/version for their transferWithAuthorization domain.\n // Permit2 tokens only need them if the token supports EIP-2612 (for gasless permit signing).\n // Omitting name/version for permit2 tokens signals the client to skip EIP-2612 and use\n // ERC-20 approval gas sponsoring instead.\n const includeEip712Domain = !assetInfo.assetTransferMethod || assetInfo.supportsEip2612;\n\n return {\n amount: tokenAmount,\n asset: assetInfo.address,\n extra: {\n ...(includeEip712Domain && {\n name: assetInfo.name,\n version: assetInfo.version,\n }),\n ...(assetInfo.assetTransferMethod && {\n assetTransferMethod: assetInfo.assetTransferMethod,\n }),\n },\n };\n }\n\n /**\n * Converts a decimal string amount to an integer token amount using the given decimals.\n *\n * @param decimalAmount - The amount as a decimal string (e.g. \"1.5\")\n * @param decimals - The number of decimal places for the token\n * @returns The token amount as an integer string in smallest units\n */\n private convertToTokenAmount(decimalAmount: string, decimals: number): string {\n const amount = parseFloat(decimalAmount);\n if (isNaN(amount)) {\n throw new Error(`Invalid amount: ${decimalAmount}`);\n }\n const [intPart, decPart = \"\"] = String(amount).split(\".\");\n const paddedDec = decPart.padEnd(decimals, \"0\").slice(0, decimals);\n const tokenAmount = (intPart + paddedDec).replace(/^0+/, \"\") || \"0\";\n return tokenAmount;\n }\n}\n","import { x402ResourceServer } from \"@x402/core/server\";\nimport { Network } from \"@x402/core/types\";\nimport { ExactEvmScheme } from \"./scheme\";\n\n/**\n * Configuration options for registering EVM schemes to an x402ResourceServer\n */\nexport interface EvmResourceServerConfig {\n /**\n * Optional specific networks to register\n * If not provided, registers wildcard support (eip155:*)\n */\n networks?: Network[];\n}\n\n/**\n * Registers EVM exact payment schemes to an x402ResourceServer instance.\n *\n * This function registers:\n * - V2: eip155:* wildcard scheme with ExactEvmScheme (or specific networks if provided)\n *\n * @param server - The x402ResourceServer instance to register schemes to\n * @param config - Configuration for EVM resource server registration\n * @returns The server instance for chaining\n *\n * @example\n * ```typescript\n * import { registerExactEvmScheme } from \"@x402/evm/exact/server/register\";\n * import { x402ResourceServer } from \"@x402/core/server\";\n *\n * const server = new x402ResourceServer(facilitatorClient);\n * registerExactEvmScheme(server, {});\n * ```\n */\nexport function registerExactEvmScheme(\n server: x402ResourceServer,\n config: EvmResourceServerConfig = {},\n): x402ResourceServer {\n // Register V2 scheme\n if (config.networks && config.networks.length > 0) {\n // Register specific networks\n config.networks.forEach(network => {\n server.register(network, new ExactEvmScheme());\n });\n } else {\n // Register wildcard for all EVM chains\n server.register(\"eip155:*\", new ExactEvmScheme());\n }\n\n return server;\n}\n"],"mappings":"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","names":[]}
@@ -92,8 +92,17 @@ var DEFAULT_STABLECOINS = {
92
92
  name: "USD Coin",
93
93
  version: "2",
94
94
  decimals: 6
95
- }
95
+ },
96
96
  // Arbitrum Sepolia USDC
97
+ "eip155:31611": {
98
+ address: "0x118917a40FAF1CD7a13dB0Ef56C86De7973Ac503",
99
+ name: "Mezo USD",
100
+ version: "1",
101
+ decimals: 18,
102
+ assetTransferMethod: "permit2",
103
+ supportsEip2612: true
104
+ }
105
+ // Mezo Testnet mUSD (no EIP-3009, supports EIP-2612)
97
106
  };
98
107
  function getDefaultAsset(network) {
99
108
  const info = DEFAULT_STABLECOINS[network];
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/upto/server/index.ts","../../../../src/upto/server/scheme.ts","../../../../src/shared/defaultAssets.ts"],"sourcesContent":["// Note: No register.ts helper — V1 backward compatibility is not needed for upto.\n// Use direct class instantiation: server.register(\"eip155:*\", new UptoEvmScheme())\nexport { UptoEvmScheme } from \"./scheme\";\n","import {\n AssetAmount,\n Network,\n PaymentRequirements,\n Price,\n SchemeNetworkServer,\n MoneyParser,\n} from \"@x402/core/types\";\nimport { getAddress } from \"viem\";\nimport { getDefaultAsset } from \"../../shared/defaultAssets\";\n\n/**\n * EVM server implementation for the Upto payment scheme.\n * Handles price parsing, payment requirements enhancement, and default asset resolution.\n */\nexport class UptoEvmScheme implements SchemeNetworkServer {\n readonly scheme = \"upto\";\n private moneyParsers: MoneyParser[] = [];\n\n /**\n * Registers a custom money parser for converting prices to asset amounts.\n *\n * @param parser - The money parser function to register\n * @returns This instance for chaining\n */\n registerMoneyParser(parser: MoneyParser): UptoEvmScheme {\n this.moneyParsers.push(parser);\n return this;\n }\n\n /**\n * Returns the decimal precision of the default stablecoin for the given network.\n * Implements the optional AssetDecimalsProvider interface used by resolveSettlementOverrideAmount.\n *\n * @param _asset - The asset symbol (unused; defaults to the network's default stablecoin)\n * @param network - The network to look up the default asset for\n * @returns The number of decimal places for the asset\n */\n getAssetDecimals(_asset: string, network: Network): number {\n try {\n return getDefaultAsset(network).decimals;\n } catch {\n return 6;\n }\n }\n\n /**\n * Parses a price into an asset amount for the given network.\n *\n * @param price - The price to parse (string, number, or AssetAmount)\n * @param network - The target network\n * @returns Promise resolving to an asset amount\n */\n async parsePrice(price: Price, network: Network): Promise<AssetAmount> {\n if (typeof price === \"object\" && price !== null && \"amount\" in price) {\n if (!price.asset) {\n throw new Error(`Asset address must be specified for AssetAmount on network ${network}`);\n }\n return {\n amount: price.amount,\n asset: price.asset,\n extra: price.extra || {},\n };\n }\n\n const amount = this.parseMoneyToDecimal(price);\n\n for (const parser of this.moneyParsers) {\n const result = await parser(amount, network);\n if (result !== null) {\n return result;\n }\n }\n\n return this.defaultMoneyConversion(amount, network);\n }\n\n /**\n * Enhances payment requirements with upto-specific metadata.\n *\n * @param paymentRequirements - The base payment requirements\n * @param supportedKind - The supported scheme/network kind\n * @param supportedKind.x402Version - The x402 protocol version\n * @param supportedKind.scheme - The payment scheme name\n * @param supportedKind.network - The target network\n * @param supportedKind.extra - Optional extra metadata\n * @param extensionKeys - Extension keys to include\n * @returns Promise resolving to enhanced payment requirements\n */\n enhancePaymentRequirements(\n paymentRequirements: PaymentRequirements,\n supportedKind: {\n x402Version: number;\n scheme: string;\n network: Network;\n extra?: Record<string, unknown>;\n },\n extensionKeys: string[],\n ): Promise<PaymentRequirements> {\n void extensionKeys;\n return Promise.resolve({\n ...paymentRequirements,\n extra: {\n ...paymentRequirements.extra,\n assetTransferMethod: \"permit2\",\n ...(supportedKind.extra?.facilitatorAddress\n ? { facilitatorAddress: getAddress(supportedKind.extra.facilitatorAddress as string) }\n : {}),\n },\n });\n }\n\n /**\n * Parses a money string or number into a decimal value.\n *\n * @param money - The money value to parse\n * @returns The parsed decimal amount\n */\n private parseMoneyToDecimal(money: string | number): number {\n if (typeof money === \"number\") {\n return money;\n }\n\n const cleanMoney = money.replace(/^\\$/, \"\").trim();\n const amount = parseFloat(cleanMoney);\n\n if (isNaN(amount)) {\n throw new Error(`Invalid money format: ${money}`);\n }\n\n return amount;\n }\n\n /**\n * Converts a numeric dollar amount to an AssetAmount using the default token for the network.\n *\n * @param amount - The dollar amount as a number\n * @param network - The target network\n * @returns The converted asset amount with token metadata\n */\n private defaultMoneyConversion(amount: number, network: Network): AssetAmount {\n const assetInfo = getDefaultAsset(network);\n const tokenAmount = this.convertToTokenAmount(amount.toString(), assetInfo.decimals);\n\n return {\n amount: tokenAmount,\n asset: assetInfo.address,\n extra: {\n name: assetInfo.name,\n version: assetInfo.version,\n assetTransferMethod: \"permit2\",\n },\n };\n }\n\n /**\n * Converts a decimal string amount to an integer token amount using the given decimals.\n *\n * @param decimalAmount - The amount as a decimal string (e.g. \"1.5\")\n * @param decimals - The number of decimal places for the token\n * @returns The token amount as an integer string in smallest units\n */\n private convertToTokenAmount(decimalAmount: string, decimals: number): string {\n const amount = parseFloat(decimalAmount);\n if (isNaN(amount)) {\n throw new Error(`Invalid amount: ${decimalAmount}`);\n }\n const [intPart, decPart = \"\"] = String(amount).split(\".\");\n const paddedDec = decPart.padEnd(decimals, \"0\").slice(0, decimals);\n const tokenAmount = (intPart + paddedDec).replace(/^0+/, \"\") || \"0\";\n return tokenAmount;\n }\n}\n","import type { Network } from \"@x402/core/types\";\n\n/**\n * Base stablecoin asset configuration shared across all EVM payment schemes.\n * Contains the core fields needed to identify and convert tokens.\n */\nexport type DefaultAssetInfo = {\n /** Token contract address */\n address: string;\n /** EIP-712 domain name (must match the token's domain separator) */\n name: string;\n /** EIP-712 domain version (must match the token's domain separator) */\n version: string;\n /** Token decimal places (typically 6 for USDC) */\n decimals: number;\n};\n\n/**\n * Extended asset configuration for the exact scheme.\n * Includes transfer method hints that control client-side behaviour.\n */\nexport type ExactDefaultAssetInfo = DefaultAssetInfo & {\n /**\n * Transfer method override: `\"permit2\"` for tokens that don't support EIP-3009.\n * Omit for EIP-3009 tokens (default behaviour).\n */\n assetTransferMethod?: string;\n /**\n * Set to `true` for permit2 tokens that implement EIP-2612 `permit()`.\n * Controls whether name/version are included in `extra` so the client can\n * sign a gasless EIP-2612 permit for Permit2 approval.\n */\n supportsEip2612?: boolean;\n};\n\n/**\n * Default stablecoins indexed by CAIP-2 network identifier.\n *\n * Each network has the right to determine its own default stablecoin that can\n * be expressed as a USD string by calling servers. See DEFAULT_ASSET.md in\n * exact/server/ for how to add new chains.\n */\nexport const DEFAULT_STABLECOINS: Record<string, ExactDefaultAssetInfo> = {\n \"eip155:8453\": {\n address: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Base mainnet USDC\n \"eip155:84532\": {\n address: \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\",\n name: \"USDC\",\n version: \"2\",\n decimals: 6,\n }, // Base Sepolia USDC\n \"eip155:4326\": {\n address: \"0xFAfDdbb3FC7688494971a79cc65DCa3EF82079E7\",\n name: \"MegaUSD\",\n version: \"1\",\n decimals: 18,\n assetTransferMethod: \"permit2\",\n supportsEip2612: true,\n }, // MegaETH mainnet MegaUSD (no EIP-3009, supports EIP-2612)\n \"eip155:143\": {\n address: \"0x754704Bc059F8C67012fEd69BC8A327a5aafb603\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Monad mainnet USDC\n \"eip155:988\": {\n address: \"0x779Ded0c9e1022225f8E0630b35a9b54bE713736\",\n name: \"USDT0\",\n version: \"1\",\n decimals: 6,\n }, // Stable mainnet USDT0\n \"eip155:2201\": {\n address: \"0x78Cf24370174180738C5B8E352B6D14c83a6c9A9\",\n name: \"USDT0\",\n version: \"1\",\n decimals: 6,\n }, // Stable testnet USDT0\n \"eip155:137\": {\n address: \"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Polygon mainnet USDC\n \"eip155:42161\": {\n address: \"0xaf88d065e77c8cC2239327C5EDb3A432268e5831\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Arbitrum One USDC\n \"eip155:421614\": {\n address: \"0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Arbitrum Sepolia USDC\n};\n\n/**\n * Look up the default stablecoin for a network.\n *\n * @param network - CAIP-2 network identifier (e.g. \"eip155:8453\")\n * @returns The default asset info\n * @throws If no default asset is configured for the network\n */\nexport function getDefaultAsset(network: Network): ExactDefaultAssetInfo {\n const info = DEFAULT_STABLECOINS[network];\n if (!info) {\n throw new Error(`No default asset configured for network ${network}`);\n }\n return info;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/upto/server/index.ts","../../../../src/upto/server/scheme.ts","../../../../src/shared/defaultAssets.ts"],"sourcesContent":["// Note: No register.ts helper — V1 backward compatibility is not needed for upto.\n// Use direct class instantiation: server.register(\"eip155:*\", new UptoEvmScheme())\nexport { UptoEvmScheme } from \"./scheme\";\n","import {\n AssetAmount,\n Network,\n PaymentRequirements,\n Price,\n SchemeNetworkServer,\n MoneyParser,\n} from \"@x402/core/types\";\nimport { getAddress } from \"viem\";\nimport { getDefaultAsset } from \"../../shared/defaultAssets\";\n\n/**\n * EVM server implementation for the Upto payment scheme.\n * Handles price parsing, payment requirements enhancement, and default asset resolution.\n */\nexport class UptoEvmScheme implements SchemeNetworkServer {\n readonly scheme = \"upto\";\n private moneyParsers: MoneyParser[] = [];\n\n /**\n * Registers a custom money parser for converting prices to asset amounts.\n *\n * @param parser - The money parser function to register\n * @returns This instance for chaining\n */\n registerMoneyParser(parser: MoneyParser): UptoEvmScheme {\n this.moneyParsers.push(parser);\n return this;\n }\n\n /**\n * Returns the decimal precision of the default stablecoin for the given network.\n * Implements the optional AssetDecimalsProvider interface used by resolveSettlementOverrideAmount.\n *\n * @param _asset - The asset symbol (unused; defaults to the network's default stablecoin)\n * @param network - The network to look up the default asset for\n * @returns The number of decimal places for the asset\n */\n getAssetDecimals(_asset: string, network: Network): number {\n try {\n return getDefaultAsset(network).decimals;\n } catch {\n return 6;\n }\n }\n\n /**\n * Parses a price into an asset amount for the given network.\n *\n * @param price - The price to parse (string, number, or AssetAmount)\n * @param network - The target network\n * @returns Promise resolving to an asset amount\n */\n async parsePrice(price: Price, network: Network): Promise<AssetAmount> {\n if (typeof price === \"object\" && price !== null && \"amount\" in price) {\n if (!price.asset) {\n throw new Error(`Asset address must be specified for AssetAmount on network ${network}`);\n }\n return {\n amount: price.amount,\n asset: price.asset,\n extra: price.extra || {},\n };\n }\n\n const amount = this.parseMoneyToDecimal(price);\n\n for (const parser of this.moneyParsers) {\n const result = await parser(amount, network);\n if (result !== null) {\n return result;\n }\n }\n\n return this.defaultMoneyConversion(amount, network);\n }\n\n /**\n * Enhances payment requirements with upto-specific metadata.\n *\n * @param paymentRequirements - The base payment requirements\n * @param supportedKind - The supported scheme/network kind\n * @param supportedKind.x402Version - The x402 protocol version\n * @param supportedKind.scheme - The payment scheme name\n * @param supportedKind.network - The target network\n * @param supportedKind.extra - Optional extra metadata\n * @param extensionKeys - Extension keys to include\n * @returns Promise resolving to enhanced payment requirements\n */\n enhancePaymentRequirements(\n paymentRequirements: PaymentRequirements,\n supportedKind: {\n x402Version: number;\n scheme: string;\n network: Network;\n extra?: Record<string, unknown>;\n },\n extensionKeys: string[],\n ): Promise<PaymentRequirements> {\n void extensionKeys;\n return Promise.resolve({\n ...paymentRequirements,\n extra: {\n ...paymentRequirements.extra,\n assetTransferMethod: \"permit2\",\n ...(supportedKind.extra?.facilitatorAddress\n ? { facilitatorAddress: getAddress(supportedKind.extra.facilitatorAddress as string) }\n : {}),\n },\n });\n }\n\n /**\n * Parses a money string or number into a decimal value.\n *\n * @param money - The money value to parse\n * @returns The parsed decimal amount\n */\n private parseMoneyToDecimal(money: string | number): number {\n if (typeof money === \"number\") {\n return money;\n }\n\n const cleanMoney = money.replace(/^\\$/, \"\").trim();\n const amount = parseFloat(cleanMoney);\n\n if (isNaN(amount)) {\n throw new Error(`Invalid money format: ${money}`);\n }\n\n return amount;\n }\n\n /**\n * Converts a numeric dollar amount to an AssetAmount using the default token for the network.\n *\n * @param amount - The dollar amount as a number\n * @param network - The target network\n * @returns The converted asset amount with token metadata\n */\n private defaultMoneyConversion(amount: number, network: Network): AssetAmount {\n const assetInfo = getDefaultAsset(network);\n const tokenAmount = this.convertToTokenAmount(amount.toString(), assetInfo.decimals);\n\n return {\n amount: tokenAmount,\n asset: assetInfo.address,\n extra: {\n name: assetInfo.name,\n version: assetInfo.version,\n assetTransferMethod: \"permit2\",\n },\n };\n }\n\n /**\n * Converts a decimal string amount to an integer token amount using the given decimals.\n *\n * @param decimalAmount - The amount as a decimal string (e.g. \"1.5\")\n * @param decimals - The number of decimal places for the token\n * @returns The token amount as an integer string in smallest units\n */\n private convertToTokenAmount(decimalAmount: string, decimals: number): string {\n const amount = parseFloat(decimalAmount);\n if (isNaN(amount)) {\n throw new Error(`Invalid amount: ${decimalAmount}`);\n }\n const [intPart, decPart = \"\"] = String(amount).split(\".\");\n const paddedDec = decPart.padEnd(decimals, \"0\").slice(0, decimals);\n const tokenAmount = (intPart + paddedDec).replace(/^0+/, \"\") || \"0\";\n return tokenAmount;\n }\n}\n","import type { Network } from \"@x402/core/types\";\n\n/**\n * Base stablecoin asset configuration shared across all EVM payment schemes.\n * Contains the core fields needed to identify and convert tokens.\n */\nexport type DefaultAssetInfo = {\n /** Token contract address */\n address: string;\n /** EIP-712 domain name (must match the token's domain separator) */\n name: string;\n /** EIP-712 domain version (must match the token's domain separator) */\n version: string;\n /** Token decimal places (typically 6 for USDC) */\n decimals: number;\n};\n\n/**\n * Extended asset configuration for the exact scheme.\n * Includes transfer method hints that control client-side behaviour.\n */\nexport type ExactDefaultAssetInfo = DefaultAssetInfo & {\n /**\n * Transfer method override: `\"permit2\"` for tokens that don't support EIP-3009.\n * Omit for EIP-3009 tokens (default behaviour).\n */\n assetTransferMethod?: string;\n /**\n * Set to `true` for permit2 tokens that implement EIP-2612 `permit()`.\n * Controls whether name/version are included in `extra` so the client can\n * sign a gasless EIP-2612 permit for Permit2 approval.\n */\n supportsEip2612?: boolean;\n};\n\n/**\n * Default stablecoins indexed by CAIP-2 network identifier.\n *\n * Each network has the right to determine its own default stablecoin that can\n * be expressed as a USD string by calling servers. See DEFAULT_ASSET.md in\n * exact/server/ for how to add new chains.\n */\nexport const DEFAULT_STABLECOINS: Record<string, ExactDefaultAssetInfo> = {\n \"eip155:8453\": {\n address: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Base mainnet USDC\n \"eip155:84532\": {\n address: \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\",\n name: \"USDC\",\n version: \"2\",\n decimals: 6,\n }, // Base Sepolia USDC\n \"eip155:4326\": {\n address: \"0xFAfDdbb3FC7688494971a79cc65DCa3EF82079E7\",\n name: \"MegaUSD\",\n version: \"1\",\n decimals: 18,\n assetTransferMethod: \"permit2\",\n supportsEip2612: true,\n }, // MegaETH mainnet MegaUSD (no EIP-3009, supports EIP-2612)\n \"eip155:143\": {\n address: \"0x754704Bc059F8C67012fEd69BC8A327a5aafb603\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Monad mainnet USDC\n \"eip155:988\": {\n address: \"0x779Ded0c9e1022225f8E0630b35a9b54bE713736\",\n name: \"USDT0\",\n version: \"1\",\n decimals: 6,\n }, // Stable mainnet USDT0\n \"eip155:2201\": {\n address: \"0x78Cf24370174180738C5B8E352B6D14c83a6c9A9\",\n name: \"USDT0\",\n version: \"1\",\n decimals: 6,\n }, // Stable testnet USDT0\n \"eip155:137\": {\n address: \"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Polygon mainnet USDC\n \"eip155:42161\": {\n address: \"0xaf88d065e77c8cC2239327C5EDb3A432268e5831\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Arbitrum One USDC\n \"eip155:421614\": {\n address: \"0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Arbitrum Sepolia USDC\n \"eip155:31611\": {\n address: \"0x118917a40FAF1CD7a13dB0Ef56C86De7973Ac503\",\n name: \"Mezo USD\",\n version: \"1\",\n decimals: 18,\n assetTransferMethod: \"permit2\",\n supportsEip2612: true,\n }, // Mezo Testnet mUSD (no EIP-3009, supports EIP-2612)\n};\n\n/**\n * Look up the default stablecoin for a network.\n *\n * @param network - CAIP-2 network identifier (e.g. \"eip155:8453\")\n * @returns The default asset info\n * @throws If no default asset is configured for the network\n */\nexport function getDefaultAsset(network: Network): ExactDefaultAssetInfo {\n const info = DEFAULT_STABLECOINS[network];\n if (!info) {\n throw new Error(`No default asset configured for network ${network}`);\n }\n return info;\n}\n"],"mappings":"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","names":[]}
@@ -63,8 +63,17 @@ var DEFAULT_STABLECOINS = {
63
63
  name: "USD Coin",
64
64
  version: "2",
65
65
  decimals: 6
66
- }
66
+ },
67
67
  // Arbitrum Sepolia USDC
68
+ "eip155:31611": {
69
+ address: "0x118917a40FAF1CD7a13dB0Ef56C86De7973Ac503",
70
+ name: "Mezo USD",
71
+ version: "1",
72
+ decimals: 18,
73
+ assetTransferMethod: "permit2",
74
+ supportsEip2612: true
75
+ }
76
+ // Mezo Testnet mUSD (no EIP-3009, supports EIP-2612)
68
77
  };
69
78
  function getDefaultAsset(network) {
70
79
  const info = DEFAULT_STABLECOINS[network];
@@ -77,4 +86,4 @@ function getDefaultAsset(network) {
77
86
  export {
78
87
  getDefaultAsset
79
88
  };
80
- //# sourceMappingURL=chunk-NSFLAANF.mjs.map
89
+ //# sourceMappingURL=chunk-F3OOHBAW.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/shared/defaultAssets.ts"],"sourcesContent":["import type { Network } from \"@x402/core/types\";\n\n/**\n * Base stablecoin asset configuration shared across all EVM payment schemes.\n * Contains the core fields needed to identify and convert tokens.\n */\nexport type DefaultAssetInfo = {\n /** Token contract address */\n address: string;\n /** EIP-712 domain name (must match the token's domain separator) */\n name: string;\n /** EIP-712 domain version (must match the token's domain separator) */\n version: string;\n /** Token decimal places (typically 6 for USDC) */\n decimals: number;\n};\n\n/**\n * Extended asset configuration for the exact scheme.\n * Includes transfer method hints that control client-side behaviour.\n */\nexport type ExactDefaultAssetInfo = DefaultAssetInfo & {\n /**\n * Transfer method override: `\"permit2\"` for tokens that don't support EIP-3009.\n * Omit for EIP-3009 tokens (default behaviour).\n */\n assetTransferMethod?: string;\n /**\n * Set to `true` for permit2 tokens that implement EIP-2612 `permit()`.\n * Controls whether name/version are included in `extra` so the client can\n * sign a gasless EIP-2612 permit for Permit2 approval.\n */\n supportsEip2612?: boolean;\n};\n\n/**\n * Default stablecoins indexed by CAIP-2 network identifier.\n *\n * Each network has the right to determine its own default stablecoin that can\n * be expressed as a USD string by calling servers. See DEFAULT_ASSET.md in\n * exact/server/ for how to add new chains.\n */\nexport const DEFAULT_STABLECOINS: Record<string, ExactDefaultAssetInfo> = {\n \"eip155:8453\": {\n address: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Base mainnet USDC\n \"eip155:84532\": {\n address: \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\",\n name: \"USDC\",\n version: \"2\",\n decimals: 6,\n }, // Base Sepolia USDC\n \"eip155:4326\": {\n address: \"0xFAfDdbb3FC7688494971a79cc65DCa3EF82079E7\",\n name: \"MegaUSD\",\n version: \"1\",\n decimals: 18,\n assetTransferMethod: \"permit2\",\n supportsEip2612: true,\n }, // MegaETH mainnet MegaUSD (no EIP-3009, supports EIP-2612)\n \"eip155:143\": {\n address: \"0x754704Bc059F8C67012fEd69BC8A327a5aafb603\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Monad mainnet USDC\n \"eip155:988\": {\n address: \"0x779Ded0c9e1022225f8E0630b35a9b54bE713736\",\n name: \"USDT0\",\n version: \"1\",\n decimals: 6,\n }, // Stable mainnet USDT0\n \"eip155:2201\": {\n address: \"0x78Cf24370174180738C5B8E352B6D14c83a6c9A9\",\n name: \"USDT0\",\n version: \"1\",\n decimals: 6,\n }, // Stable testnet USDT0\n \"eip155:137\": {\n address: \"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Polygon mainnet USDC\n \"eip155:42161\": {\n address: \"0xaf88d065e77c8cC2239327C5EDb3A432268e5831\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Arbitrum One USDC\n \"eip155:421614\": {\n address: \"0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Arbitrum Sepolia USDC\n};\n\n/**\n * Look up the default stablecoin for a network.\n *\n * @param network - CAIP-2 network identifier (e.g. \"eip155:8453\")\n * @returns The default asset info\n * @throws If no default asset is configured for the network\n */\nexport function getDefaultAsset(network: Network): ExactDefaultAssetInfo {\n const info = DEFAULT_STABLECOINS[network];\n if (!info) {\n throw new Error(`No default asset configured for network ${network}`);\n }\n return info;\n}\n"],"mappings":";AA0CO,IAAM,sBAA6D;AAAA,EACxE,eAAe;AAAA,IACb,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA;AAAA,EACA,gBAAgB;AAAA,IACd,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA;AAAA,EACA,eAAe;AAAA,IACb,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,IACV,qBAAqB;AAAA,IACrB,iBAAiB;AAAA,EACnB;AAAA;AAAA,EACA,cAAc;AAAA,IACZ,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA;AAAA,EACA,cAAc;AAAA,IACZ,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA;AAAA,EACA,eAAe;AAAA,IACb,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA;AAAA,EACA,cAAc;AAAA,IACZ,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA;AAAA,EACA,gBAAgB;AAAA,IACd,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA;AAAA,EACA,iBAAiB;AAAA,IACf,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA;AACF;AASO,SAAS,gBAAgB,SAAyC;AACvE,QAAM,OAAO,oBAAoB,OAAO;AACxC,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,MAAM,2CAA2C,OAAO,EAAE;AAAA,EACtE;AACA,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../src/shared/defaultAssets.ts"],"sourcesContent":["import type { Network } from \"@x402/core/types\";\n\n/**\n * Base stablecoin asset configuration shared across all EVM payment schemes.\n * Contains the core fields needed to identify and convert tokens.\n */\nexport type DefaultAssetInfo = {\n /** Token contract address */\n address: string;\n /** EIP-712 domain name (must match the token's domain separator) */\n name: string;\n /** EIP-712 domain version (must match the token's domain separator) */\n version: string;\n /** Token decimal places (typically 6 for USDC) */\n decimals: number;\n};\n\n/**\n * Extended asset configuration for the exact scheme.\n * Includes transfer method hints that control client-side behaviour.\n */\nexport type ExactDefaultAssetInfo = DefaultAssetInfo & {\n /**\n * Transfer method override: `\"permit2\"` for tokens that don't support EIP-3009.\n * Omit for EIP-3009 tokens (default behaviour).\n */\n assetTransferMethod?: string;\n /**\n * Set to `true` for permit2 tokens that implement EIP-2612 `permit()`.\n * Controls whether name/version are included in `extra` so the client can\n * sign a gasless EIP-2612 permit for Permit2 approval.\n */\n supportsEip2612?: boolean;\n};\n\n/**\n * Default stablecoins indexed by CAIP-2 network identifier.\n *\n * Each network has the right to determine its own default stablecoin that can\n * be expressed as a USD string by calling servers. See DEFAULT_ASSET.md in\n * exact/server/ for how to add new chains.\n */\nexport const DEFAULT_STABLECOINS: Record<string, ExactDefaultAssetInfo> = {\n \"eip155:8453\": {\n address: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Base mainnet USDC\n \"eip155:84532\": {\n address: \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\",\n name: \"USDC\",\n version: \"2\",\n decimals: 6,\n }, // Base Sepolia USDC\n \"eip155:4326\": {\n address: \"0xFAfDdbb3FC7688494971a79cc65DCa3EF82079E7\",\n name: \"MegaUSD\",\n version: \"1\",\n decimals: 18,\n assetTransferMethod: \"permit2\",\n supportsEip2612: true,\n }, // MegaETH mainnet MegaUSD (no EIP-3009, supports EIP-2612)\n \"eip155:143\": {\n address: \"0x754704Bc059F8C67012fEd69BC8A327a5aafb603\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Monad mainnet USDC\n \"eip155:988\": {\n address: \"0x779Ded0c9e1022225f8E0630b35a9b54bE713736\",\n name: \"USDT0\",\n version: \"1\",\n decimals: 6,\n }, // Stable mainnet USDT0\n \"eip155:2201\": {\n address: \"0x78Cf24370174180738C5B8E352B6D14c83a6c9A9\",\n name: \"USDT0\",\n version: \"1\",\n decimals: 6,\n }, // Stable testnet USDT0\n \"eip155:137\": {\n address: \"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Polygon mainnet USDC\n \"eip155:42161\": {\n address: \"0xaf88d065e77c8cC2239327C5EDb3A432268e5831\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Arbitrum One USDC\n \"eip155:421614\": {\n address: \"0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Arbitrum Sepolia USDC\n \"eip155:31611\": {\n address: \"0x118917a40FAF1CD7a13dB0Ef56C86De7973Ac503\",\n name: \"Mezo USD\",\n version: \"1\",\n decimals: 18,\n assetTransferMethod: \"permit2\",\n supportsEip2612: true,\n }, // Mezo Testnet mUSD (no EIP-3009, supports EIP-2612)\n};\n\n/**\n * Look up the default stablecoin for a network.\n *\n * @param network - CAIP-2 network identifier (e.g. \"eip155:8453\")\n * @returns The default asset info\n * @throws If no default asset is configured for the network\n */\nexport function getDefaultAsset(network: Network): ExactDefaultAssetInfo {\n const info = DEFAULT_STABLECOINS[network];\n if (!info) {\n throw new Error(`No default asset configured for network ${network}`);\n }\n return info;\n}\n"],"mappings":";AA0CO,IAAM,sBAA6D;AAAA,EACxE,eAAe;AAAA,IACb,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA;AAAA,EACA,gBAAgB;AAAA,IACd,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA;AAAA,EACA,eAAe;AAAA,IACb,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,IACV,qBAAqB;AAAA,IACrB,iBAAiB;AAAA,EACnB;AAAA;AAAA,EACA,cAAc;AAAA,IACZ,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA;AAAA,EACA,cAAc;AAAA,IACZ,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA;AAAA,EACA,eAAe;AAAA,IACb,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA;AAAA,EACA,cAAc;AAAA,IACZ,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA;AAAA,EACA,gBAAgB;AAAA,IACd,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA;AAAA,EACA,iBAAiB;AAAA,IACf,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA;AAAA,EACA,gBAAgB;AAAA,IACd,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,IACV,qBAAqB;AAAA,IACrB,iBAAiB;AAAA,EACnB;AAAA;AACF;AASO,SAAS,gBAAgB,SAAyC;AACvE,QAAM,OAAO,oBAAoB,OAAO;AACxC,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,MAAM,2CAA2C,OAAO,EAAE;AAAA,EACtE;AACA,SAAO;AACT;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getDefaultAsset
3
- } from "../../chunk-NSFLAANF.mjs";
3
+ } from "../../chunk-F3OOHBAW.mjs";
4
4
 
5
5
  // src/exact/server/scheme.ts
6
6
  var ExactEvmScheme = class {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getDefaultAsset
3
- } from "../../chunk-NSFLAANF.mjs";
3
+ } from "../../chunk-F3OOHBAW.mjs";
4
4
 
5
5
  // src/upto/server/scheme.ts
6
6
  import { getAddress } from "viem";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@x402/evm",
3
- "version": "2.9.0",
3
+ "version": "2.10.0",
4
4
  "main": "./dist/cjs/index.js",
5
5
  "module": "./dist/esm/index.js",
6
6
  "types": "./dist/cjs/index.d.ts",
@@ -35,7 +35,7 @@
35
35
  "dependencies": {
36
36
  "viem": "^2.39.3",
37
37
  "zod": "^3.24.2",
38
- "@x402/core": "~2.9.0"
38
+ "@x402/core": "~2.10.0"
39
39
  },
40
40
  "exports": {
41
41
  ".": {