@t402/evm 2.2.0 → 2.3.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/cjs/exact/client/index.d.ts +2 -2
- package/dist/cjs/exact/client/index.js +4 -2
- package/dist/cjs/exact/client/index.js.map +1 -1
- package/dist/cjs/exact/facilitator/index.d.ts +1 -1
- package/dist/cjs/exact/facilitator/index.js +40 -4
- package/dist/cjs/exact/facilitator/index.js.map +1 -1
- package/dist/cjs/exact/server/index.d.ts +1 -1
- package/dist/cjs/exact/server/index.js +301 -33
- package/dist/cjs/exact/server/index.js.map +1 -1
- package/dist/cjs/exact/v1/client/index.d.ts +1 -1
- package/dist/cjs/exact/v1/client/index.js +3 -1
- package/dist/cjs/exact/v1/client/index.js.map +1 -1
- package/dist/cjs/exact/v1/facilitator/index.d.ts +1 -1
- package/dist/cjs/exact/v1/facilitator/index.js +21 -2
- package/dist/cjs/exact/v1/facilitator/index.js.map +1 -1
- package/dist/cjs/index.d.ts +606 -352
- package/dist/cjs/index.js +1436 -268
- package/dist/cjs/index.js.map +1 -1
- package/dist/{esm/scheme-yqGaK9rK.d.mts → cjs/scheme-B4rXSKCN.d.ts} +18 -16
- package/dist/cjs/scheme-CIar5W2B.d.ts +200 -0
- package/dist/cjs/{scheme-OojTBKAz.d.ts → scheme-CjijeY7y.d.ts} +1 -1
- package/dist/{esm/signer-BkcAzwYi.d.mts → cjs/signer-DcavxxZt.d.ts} +1 -18
- package/dist/cjs/upto/client/index.d.ts +61 -0
- package/dist/cjs/upto/client/index.js +154 -0
- package/dist/cjs/upto/client/index.js.map +1 -0
- package/dist/cjs/upto/index.d.ts +111 -0
- package/dist/cjs/upto/index.js +1030 -0
- package/dist/cjs/upto/index.js.map +1 -0
- package/dist/cjs/v1/index.d.ts +1 -1
- package/dist/cjs/v1/index.js +3 -1
- package/dist/cjs/v1/index.js.map +1 -1
- package/dist/esm/{chunk-ACDQ5QNT.mjs → chunk-4FBTQTNM.mjs} +27 -5
- package/dist/esm/chunk-4FBTQTNM.mjs.map +1 -0
- package/dist/esm/chunk-IWSDEZKI.mjs +477 -0
- package/dist/esm/chunk-IWSDEZKI.mjs.map +1 -0
- package/dist/esm/{chunk-LGSG73NJ.mjs → chunk-LM5RZBVP.mjs} +9 -4
- package/dist/esm/{chunk-LGSG73NJ.mjs.map → chunk-LM5RZBVP.mjs.map} +1 -1
- package/dist/esm/chunk-NSSMTXJJ.mjs +8 -0
- package/dist/esm/chunk-NSSMTXJJ.mjs.map +1 -0
- package/dist/esm/chunk-SJ52GTJJ.mjs +411 -0
- package/dist/esm/chunk-SJ52GTJJ.mjs.map +1 -0
- package/dist/esm/chunk-SURTCHSX.mjs +129 -0
- package/dist/esm/chunk-SURTCHSX.mjs.map +1 -0
- package/dist/esm/chunk-SYVPLXYV.mjs +26 -0
- package/dist/esm/chunk-SYVPLXYV.mjs.map +1 -0
- package/dist/esm/{chunk-XYKAO6KJ.mjs → chunk-Y4U7Q543.mjs} +2 -25
- package/dist/esm/chunk-Y4U7Q543.mjs.map +1 -0
- package/dist/esm/{chunk-JBWWBRYY.mjs → chunk-ZWEYARER.mjs} +9 -4
- package/dist/esm/{chunk-JBWWBRYY.mjs.map → chunk-ZWEYARER.mjs.map} +1 -1
- package/dist/esm/exact/client/index.d.mts +2 -2
- package/dist/esm/exact/client/index.mjs +6 -4
- package/dist/esm/exact/client/index.mjs.map +1 -1
- package/dist/esm/exact/facilitator/index.d.mts +1 -1
- package/dist/esm/exact/facilitator/index.mjs +26 -5
- package/dist/esm/exact/facilitator/index.mjs.map +1 -1
- package/dist/esm/exact/server/index.d.mts +1 -1
- package/dist/esm/exact/server/index.mjs +29 -30
- package/dist/esm/exact/server/index.mjs.map +1 -1
- package/dist/esm/exact/v1/client/index.d.mts +1 -1
- package/dist/esm/exact/v1/client/index.mjs +4 -2
- package/dist/esm/exact/v1/facilitator/index.d.mts +1 -1
- package/dist/esm/exact/v1/facilitator/index.mjs +4 -2
- package/dist/esm/index.d.mts +606 -352
- package/dist/esm/index.mjs +626 -138
- package/dist/esm/index.mjs.map +1 -1
- package/dist/{cjs/scheme-yqGaK9rK.d.ts → esm/scheme-B4rXSKCN.d.mts} +18 -16
- package/dist/esm/scheme-DATfd6oM.d.mts +200 -0
- package/dist/esm/{scheme-D4mOqq9l.d.mts → scheme-Ddb0dG_F.d.mts} +1 -1
- package/dist/{cjs/signer-BkcAzwYi.d.ts → esm/signer-DcavxxZt.d.mts} +1 -18
- package/dist/esm/upto/client/index.d.mts +61 -0
- package/dist/esm/upto/client/index.mjs +11 -0
- package/dist/esm/upto/client/index.mjs.map +1 -0
- package/dist/esm/upto/index.d.mts +111 -0
- package/dist/esm/upto/index.mjs +26 -0
- package/dist/esm/upto/index.mjs.map +1 -0
- package/dist/esm/v1/index.d.mts +1 -1
- package/dist/esm/v1/index.mjs +5 -3
- package/package.json +30 -6
- package/dist/cjs/scheme-C6uD7PdY.d.ts +0 -130
- package/dist/esm/chunk-ACDQ5QNT.mjs.map +0 -1
- package/dist/esm/chunk-OEXW2OK2.mjs +0 -251
- package/dist/esm/chunk-OEXW2OK2.mjs.map +0 -1
- package/dist/esm/chunk-XYKAO6KJ.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/upto/index.ts","../../../src/upto/client/scheme.ts","../../../src/types.ts","../../../src/utils.ts","../../../src/upto/server/scheme.ts","../../../src/tokens.ts","../../../src/upto/facilitator/scheme.ts"],"sourcesContent":["/**\n * Up-To Scheme for EVM\n *\n * The upto scheme enables usage-based billing by authorizing\n * transfer of up to a maximum amount using EIP-2612 Permit.\n *\n * @example\n * ```typescript\n * // Client-side\n * import { UptoEvmScheme } from \"@t402/evm/upto/client\";\n *\n * const scheme = new UptoEvmScheme(signer);\n * client.registerScheme(\"eip155:8453\", scheme);\n *\n * // Make request with upto authorization\n * const response = await fetchWithPayment(\"https://api.example.com/llm\", {\n * method: \"POST\",\n * body: JSON.stringify({ prompt: \"Hello\" }),\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Server-side\n * import { UptoEvmServerScheme } from \"@t402/evm/upto/server\";\n *\n * const scheme = new UptoEvmServerScheme({\n * routerAddress: \"0x...\",\n * defaultUnit: \"token\",\n * });\n * server.registerScheme(\"eip155:8453\", scheme);\n * ```\n *\n * @example\n * ```typescript\n * // Facilitator-side\n * import { UptoEvmFacilitatorScheme } from \"@t402/evm/upto/facilitator\";\n *\n * const scheme = new UptoEvmFacilitatorScheme(signer, {\n * routerAddresses: { \"eip155:8453\": \"0x...\" },\n * });\n * facilitator.registerScheme(scheme);\n * ```\n *\n * @module\n */\n\n// Client exports\nexport { UptoEvmScheme, createUptoEvmScheme } from \"./client/index.js\";\n\n// Server exports\nexport { UptoEvmServerScheme, createUptoEvmServerScheme } from \"./server/index.js\";\nexport type { UptoEvmServerSchemeConfig } from \"./server/index.js\";\n\n// Facilitator exports\nexport { UptoEvmFacilitatorScheme, createUptoEvmFacilitatorScheme } from \"./facilitator/index.js\";\nexport type { UptoEvmFacilitatorSchemeConfig } from \"./facilitator/index.js\";\n\n// Re-export types\nexport type {\n UptoEIP2612Payload,\n UptoEIP2612PayloadCompact,\n UptoEvmPayloadV2,\n UptoEvmExtra,\n UptoEvmSettlement,\n PermitSignature,\n PermitAuthorization,\n} from \"../types.js\";\n\nexport { permitTypes, isUptoEIP2612Payload } from \"../types.js\";\n","import { PaymentPayload, PaymentRequirements, SchemeNetworkClient } from \"@t402/core/types\";\nimport { getAddress } from \"viem\";\nimport { permitTypes, UptoEIP2612Payload, UptoEvmExtra } from \"../../types\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport { createNonce } from \"../../utils\";\n\n/**\n * EVM client implementation for the Up-To payment scheme.\n *\n * Uses EIP-2612 Permit to authorize up to a maximum amount,\n * enabling usage-based billing where the actual settlement\n * amount is determined by the server based on usage.\n *\n * @example\n * ```typescript\n * import { UptoEvmScheme } from \"@t402/evm/upto/client\";\n * import { privateKeyToAccount } from \"viem/accounts\";\n *\n * const signer = privateKeyToAccount(privateKey);\n * const scheme = new UptoEvmScheme(signer);\n *\n * // Client will register this with the t402 client\n * client.registerScheme(\"eip155:8453\", scheme);\n * ```\n */\nexport class UptoEvmScheme implements SchemeNetworkClient {\n readonly scheme = \"upto\";\n\n /**\n * Creates a new UptoEvmScheme instance.\n *\n * @param signer - The EVM signer for client operations\n */\n constructor(private readonly signer: ClientEvmSigner) {}\n\n /**\n * Creates a payment payload for the Up-To scheme.\n *\n * The payload contains an EIP-2612 permit signature authorizing\n * the router contract (or facilitator) to transfer up to the\n * specified maximum amount.\n *\n * @param t402Version - The t402 protocol version\n * @param paymentRequirements - The payment requirements (must include maxAmount)\n * @returns Promise resolving to a payment payload\n */\n async createPaymentPayload(\n t402Version: number,\n paymentRequirements: PaymentRequirements,\n ): Promise<Pick<PaymentPayload, \"t402Version\" | \"payload\">> {\n // Validate that this is an upto requirement\n if (paymentRequirements.scheme !== \"upto\") {\n throw new Error(`Expected upto scheme, got ${paymentRequirements.scheme}`);\n }\n\n const extra = paymentRequirements.extra as UptoEvmExtra;\n if (!extra?.name || !extra?.version) {\n throw new Error(\"EIP-712 domain parameters (name, version) are required for upto scheme\");\n }\n\n // Get maxAmount from the requirements\n const maxAmount = (paymentRequirements as unknown as { maxAmount: string }).maxAmount;\n if (!maxAmount) {\n throw new Error(\"maxAmount is required for upto scheme\");\n }\n\n // Determine the spender (router contract or payTo address)\n const spender = extra.routerAddress\n ? getAddress(extra.routerAddress)\n : getAddress(paymentRequirements.payTo);\n\n // Calculate deadline\n const now = Math.floor(Date.now() / 1000);\n const deadline = now + paymentRequirements.maxTimeoutSeconds;\n\n // Get the permit nonce from the token contract\n // Note: In a real implementation, this would query the token contract\n // For now, we'll use 0 and expect the caller to provide it via extra\n const permitNonce = (extra as { permitNonce?: number }).permitNonce ?? 0;\n\n // Create the permit authorization\n const authorization: UptoEIP2612Payload[\"authorization\"] = {\n owner: this.signer.address,\n spender,\n value: maxAmount,\n deadline: deadline.toString(),\n nonce: permitNonce,\n };\n\n // Sign the permit\n const signature = await this.signPermit(authorization, paymentRequirements);\n\n // Create unique payment nonce\n const paymentNonce = createNonce();\n\n const payload: UptoEIP2612Payload = {\n signature,\n authorization,\n paymentNonce,\n };\n\n return {\n t402Version,\n payload,\n };\n }\n\n /**\n * Sign the EIP-2612 permit using EIP-712\n *\n * @param authorization - The permit authorization to sign\n * @param requirements - The payment requirements\n * @returns Promise resolving to the signature components\n */\n private async signPermit(\n authorization: UptoEIP2612Payload[\"authorization\"],\n requirements: PaymentRequirements,\n ): Promise<UptoEIP2612Payload[\"signature\"]> {\n const chainId = parseInt(requirements.network.split(\":\")[1]);\n const extra = requirements.extra as UptoEvmExtra;\n\n const domain = {\n name: extra.name,\n version: extra.version,\n chainId,\n verifyingContract: getAddress(requirements.asset),\n };\n\n const message = {\n owner: getAddress(authorization.owner),\n spender: getAddress(authorization.spender),\n value: BigInt(authorization.value),\n nonce: BigInt(authorization.nonce),\n deadline: BigInt(authorization.deadline),\n };\n\n // Sign with EIP-712\n const signature = await this.signer.signTypedData({\n domain,\n types: permitTypes,\n primaryType: \"Permit\",\n message,\n });\n\n // Parse signature into v, r, s components\n const r = `0x${signature.slice(2, 66)}` as `0x${string}`;\n const s = `0x${signature.slice(66, 130)}` as `0x${string}`;\n const v = parseInt(signature.slice(130, 132), 16);\n\n return { v, r, s };\n }\n}\n\n/**\n * Factory function to create an UptoEvmScheme.\n *\n * @param signer - The EVM signer\n * @returns A new UptoEvmScheme instance\n */\nexport function createUptoEvmScheme(signer: ClientEvmSigner): UptoEvmScheme {\n return new UptoEvmScheme(signer);\n}\n","export type ExactEIP3009Payload = {\n signature?: `0x${string}`;\n authorization: {\n from: `0x${string}`;\n to: `0x${string}`;\n value: string;\n validAfter: string;\n validBefore: string;\n nonce: `0x${string}`;\n };\n};\n\nexport type ExactEvmPayloadV1 = ExactEIP3009Payload;\n\nexport type ExactEvmPayloadV2 = ExactEIP3009Payload;\n\n/**\n * Payload for exact-legacy scheme (approve + transferFrom pattern)\n * Used for legacy USDT and other tokens without EIP-3009 support\n */\nexport type ExactLegacyPayload = {\n signature?: `0x${string}`;\n authorization: {\n /** Payer address */\n from: `0x${string}`;\n /** Recipient address */\n to: `0x${string}`;\n /** Payment amount in token units */\n value: string;\n /** Unix timestamp after which the authorization is valid */\n validAfter: string;\n /** Unix timestamp before which the authorization is valid */\n validBefore: string;\n /** Unique nonce to prevent replay attacks */\n nonce: `0x${string}`;\n /** Facilitator address that will call transferFrom */\n spender: `0x${string}`;\n };\n};\n\n// ============================================================================\n// Up-To Scheme Types (EIP-2612 Permit)\n// ============================================================================\n\n/**\n * EIP-2612 Permit signature components\n */\nexport type PermitSignature = {\n v: number;\n r: `0x${string}`;\n s: `0x${string}`;\n};\n\n/**\n * EIP-2612 Permit authorization parameters\n */\nexport type PermitAuthorization = {\n /** Token owner address */\n owner: `0x${string}`;\n /** Spender address (router contract or facilitator) */\n spender: `0x${string}`;\n /** Maximum authorized value */\n value: string;\n /** Permit deadline (unix timestamp) */\n deadline: string;\n /** Permit nonce from token contract */\n nonce: number;\n};\n\n/**\n * Payload for upto scheme using EIP-2612 Permit\n */\nexport type UptoEIP2612Payload = {\n /** EIP-2612 permit signature */\n signature: PermitSignature;\n /** Permit authorization parameters */\n authorization: PermitAuthorization;\n /** Unique payment nonce (separate from permit nonce) */\n paymentNonce: `0x${string}`;\n};\n\n/**\n * Compact payload with combined signature bytes\n */\nexport type UptoEIP2612PayloadCompact = {\n /** Combined permit signature (65 bytes) */\n signature: `0x${string}`;\n /** Permit authorization parameters */\n authorization: PermitAuthorization;\n /** Unique payment nonce */\n paymentNonce: `0x${string}`;\n};\n\nexport type UptoEvmPayloadV2 = UptoEIP2612Payload | UptoEIP2612PayloadCompact;\n\n/**\n * Extra fields for upto scheme requirements on EVM\n */\nexport type UptoEvmExtra = {\n /** EIP-712 domain name (from token contract) */\n name: string;\n /** EIP-712 domain version */\n version: string;\n /** Router contract address for settlement */\n routerAddress?: `0x${string}`;\n /** Billing unit */\n unit?: string;\n /** Price per unit */\n unitPrice?: string;\n};\n\n/**\n * Settlement data for upto scheme\n */\nexport type UptoEvmSettlement = {\n /** Actual amount to settle (must be <= maxAmount) */\n settleAmount: string;\n /** Usage details for auditing */\n usageDetails?: {\n unitsConsumed?: number;\n unitPrice?: string;\n unitType?: string;\n startTime?: number;\n endTime?: number;\n };\n};\n\n/**\n * EIP-712 typed data for EIP-2612 Permit\n */\nexport const permitTypes = {\n Permit: [\n { name: \"owner\", type: \"address\" },\n { name: \"spender\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"nonce\", type: \"uint256\" },\n { name: \"deadline\", type: \"uint256\" },\n ],\n} as const;\n\n/**\n * Type guard for UptoEIP2612Payload\n *\n * @param payload - The payload to check\n * @returns True if the payload is a valid UptoEIP2612Payload\n */\nexport function isUptoEIP2612Payload(payload: unknown): payload is UptoEIP2612Payload {\n if (typeof payload !== \"object\" || payload === null) return false;\n const p = payload as Record<string, unknown>;\n return (\n \"signature\" in p &&\n \"authorization\" in p &&\n \"paymentNonce\" in p &&\n typeof p.authorization === \"object\" &&\n p.authorization !== null &&\n \"owner\" in (p.authorization as Record<string, unknown>) &&\n \"spender\" in (p.authorization as Record<string, unknown>) &&\n \"value\" in (p.authorization as Record<string, unknown>) &&\n \"deadline\" in (p.authorization as Record<string, unknown>) &&\n \"nonce\" in (p.authorization as Record<string, unknown>)\n );\n}\n","import { toHex } from \"viem\";\nimport { Network } from \"@t402/core/types\";\n\n/**\n * Extract chain ID from network string (e.g., \"base-sepolia\" -> 84532)\n * Used by v1 implementations\n *\n * @param network - The network identifier\n * @returns The numeric chain ID\n */\nexport function getEvmChainId(network: Network): number {\n const networkMap: Record<string, number> = {\n base: 8453,\n \"base-sepolia\": 84532,\n ethereum: 1,\n sepolia: 11155111,\n polygon: 137,\n \"polygon-amoy\": 80002,\n };\n return networkMap[network] || 1;\n}\n\n/**\n * Create a random 32-byte nonce for authorization\n *\n * @returns A hex-encoded 32-byte nonce\n */\nexport function createNonce(): `0x${string}` {\n // Use dynamic import to avoid require() in ESM context\n const cryptoObj =\n typeof globalThis.crypto !== \"undefined\"\n ? globalThis.crypto\n : (globalThis as { crypto?: Crypto }).crypto;\n\n if (!cryptoObj) {\n throw new Error(\"Crypto API not available\");\n }\n\n return toHex(cryptoObj.getRandomValues(new Uint8Array(32)));\n}\n","import {\n AssetAmount,\n Network,\n PaymentRequirements,\n Price,\n SchemeNetworkServer,\n MoneyParser,\n UPTO_DEFAULTS,\n} from \"@t402/core/types\";\nimport {\n getDefaultToken,\n getTokenConfig,\n getTokenByAddress,\n TokenConfig,\n TOKEN_REGISTRY,\n} from \"../../tokens.js\";\n\n/**\n * Configuration options for UptoEvmServerScheme\n */\nexport interface UptoEvmServerSchemeConfig {\n /** Preferred token symbol (e.g., \"USDT0\", \"USDC\"). Defaults to network's highest priority token. */\n preferredToken?: string;\n\n /** Router contract address for upto payments. If not set, payTo address is used as spender. */\n routerAddress?: string;\n\n /** Default billing unit */\n defaultUnit?: string;\n\n /** Default unit price in smallest denomination */\n defaultUnitPrice?: string;\n}\n\n/**\n * EVM server implementation for the Up-To payment scheme.\n *\n * Enables usage-based billing by creating payment requirements\n * that authorize up to a maximum amount, with actual settlement\n * determined by usage.\n *\n * @example\n * ```typescript\n * import { UptoEvmServerScheme } from \"@t402/evm/upto/server\";\n *\n * const scheme = new UptoEvmServerScheme({\n * routerAddress: \"0x...\", // T402UptoRouter contract\n * defaultUnit: \"token\",\n * defaultUnitPrice: \"100\", // $0.0001 per token\n * });\n *\n * server.registerScheme(\"eip155:8453\", scheme);\n * ```\n */\nexport class UptoEvmServerScheme implements SchemeNetworkServer {\n readonly scheme = \"upto\";\n private moneyParsers: MoneyParser[] = [];\n private config: UptoEvmServerSchemeConfig;\n\n /**\n * Creates a new UptoEvmServerScheme instance.\n *\n * @param config - Optional configuration options for the scheme\n */\n constructor(config: UptoEvmServerSchemeConfig = {}) {\n this.config = config;\n }\n\n /**\n * Get all supported networks\n *\n * @returns Array of network identifiers in CAIP-2 format\n */\n static getSupportedNetworks(): string[] {\n return Object.keys(TOKEN_REGISTRY);\n }\n\n /**\n * Check if a network is supported\n *\n * @param network - The network identifier to check\n * @returns True if the network is supported\n */\n static isNetworkSupported(network: string): boolean {\n return network in TOKEN_REGISTRY;\n }\n\n /**\n * Register a custom money parser in the parser chain.\n *\n * @param parser - Custom function to convert amount to AssetAmount\n * @returns The server instance for chaining\n */\n registerMoneyParser(parser: MoneyParser): UptoEvmServerScheme {\n this.moneyParsers.push(parser);\n return this;\n }\n\n /**\n * Parses a price into an asset amount for maxAmount.\n *\n * @param price - The price to parse (represents maxAmount)\n * @param network - The network to use\n * @returns Promise resolving 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 const token = this.getPreferredToken(network);\n return { amount: price.amount, asset: token.address };\n }\n return price as AssetAmount;\n }\n\n // Parse string/number price to decimal\n const decimalAmount = this.parseToDecimal(price);\n\n // Try custom parsers first\n for (const parser of this.moneyParsers) {\n const result = await parser(decimalAmount, network);\n if (result !== null) {\n return result;\n }\n }\n\n // Default: convert to token's smallest denomination\n const token = this.getPreferredToken(network);\n const amount = Math.floor(decimalAmount * 10 ** token.decimals).toString();\n\n return {\n amount,\n asset: token.address,\n };\n }\n\n /**\n * Enhance payment requirements for the upto scheme.\n *\n * @param paymentRequirements - Base payment requirements\n * @param supportedKind - The supported kind from facilitator\n * @param supportedKind.t402Version - T402 protocol version\n * @param supportedKind.scheme - Payment scheme\n * @param supportedKind.network - Network identifier\n * @param supportedKind.extra - Extra configuration\n * @param facilitatorExtensions - Extensions supported by the facilitator\n * @returns Enhanced payment requirements for upto scheme\n */\n async enhancePaymentRequirements(\n paymentRequirements: PaymentRequirements,\n supportedKind: {\n t402Version: number;\n scheme: string;\n network: Network;\n extra?: Record<string, unknown>;\n },\n facilitatorExtensions: string[],\n ): Promise<PaymentRequirements> {\n // Mark unused parameter to satisfy linter\n void facilitatorExtensions;\n\n const network = supportedKind.network;\n const token = getTokenByAddress(network, paymentRequirements.asset as `0x${string}`);\n\n if (!token) {\n throw new Error(`Unknown token ${paymentRequirements.asset} on ${network}`);\n }\n\n // Build extra with EIP-712 domain and upto-specific fields\n const extra: Record<string, unknown> = {\n // EIP-712 domain (required for permit signing)\n name: token.name,\n version: token.version,\n\n // Router address (optional - if set, permits go to router)\n ...(this.config.routerAddress && { routerAddress: this.config.routerAddress }),\n\n // Billing unit info (optional)\n ...(this.config.defaultUnit && { unit: this.config.defaultUnit }),\n ...(this.config.defaultUnitPrice && { unitPrice: this.config.defaultUnitPrice }),\n\n // Upto-specific fields\n maxAmount: paymentRequirements.amount,\n minAmount: UPTO_DEFAULTS.MIN_AMOUNT,\n\n // Merge any facilitator extra\n ...supportedKind.extra,\n };\n\n return {\n ...paymentRequirements,\n scheme: \"upto\",\n extra,\n };\n }\n\n /**\n * Get the preferred token for a network.\n *\n * @param network - The network identifier\n * @returns Token configuration\n * @throws Error if no token is found for the network\n */\n private getPreferredToken(network: Network): TokenConfig {\n if (this.config.preferredToken) {\n const token = getTokenConfig(network, this.config.preferredToken);\n if (token) return token;\n }\n const defaultToken = getDefaultToken(network);\n if (!defaultToken) {\n throw new Error(`No token configured for network ${network}`);\n }\n return defaultToken;\n }\n\n /**\n * Parse price to decimal value.\n *\n * @param price - Price string or number\n * @returns Decimal amount\n */\n private parseToDecimal(price: string | number): number {\n if (typeof price === \"number\") {\n return price;\n }\n\n // Remove currency symbols and parse\n const cleaned = price.replace(/[$,]/g, \"\").trim();\n const parsed = parseFloat(cleaned);\n\n if (isNaN(parsed)) {\n throw new Error(`Invalid price format: ${price}`);\n }\n\n return parsed;\n }\n}\n\n/**\n * Factory function to create an UptoEvmServerScheme.\n *\n * @param config - Configuration options\n * @returns A new UptoEvmServerScheme instance\n */\nexport function createUptoEvmServerScheme(config?: UptoEvmServerSchemeConfig): UptoEvmServerScheme {\n return new UptoEvmServerScheme(config);\n}\n","/**\n * Token configuration for T402 EVM payments\n *\n * This module provides comprehensive token definitions including:\n * - USDT0 (Tether's new omnichain token with EIP-3009 support)\n * - USDC (USD Coin with EIP-3009 support)\n * - Legacy tokens configuration\n */\n\nimport type { Address } from \"viem\";\n\n/**\n * Token type classification for payment scheme selection\n */\nexport type TokenType = \"eip3009\" | \"legacy\";\n\n/**\n * Token configuration with EIP-712 domain parameters\n */\nexport interface TokenConfig {\n /** Token contract address */\n address: Address;\n /** Token symbol (e.g., \"USDT0\", \"USDC\") */\n symbol: string;\n /** EIP-712 domain name for signing */\n name: string;\n /** EIP-712 domain version for signing */\n version: string;\n /** Number of decimal places */\n decimals: number;\n /** Token type for scheme selection */\n tokenType: TokenType;\n /** Payment priority (lower = higher priority) */\n priority: number;\n}\n\n/**\n * Network token registry mapping network -> symbol -> config\n */\nexport type NetworkTokenRegistry = Record<string, Record<string, TokenConfig>>;\n\n/**\n * USDT0 Contract Addresses by Network\n * Source: https://docs.tether.io/usdt0/integration-guide/deployed-contracts\n *\n * USDT0 is Tether's new omnichain token using LayerZero OFT standard.\n * Key features:\n * - Supports EIP-3009 transferWithAuthorization (gasless transfers)\n * - Supports EIP-2612 permit\n * - Native cross-chain via LayerZero\n */\nexport const USDT0_ADDRESSES: Record<string, Address> = {\n // === Existing Networks ===\n // Ethereum Mainnet - OFT Adapter (bridge endpoint)\n \"eip155:1\": \"0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee\",\n // Arbitrum One - Native USDT0\n \"eip155:42161\": \"0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9\",\n // Ink Mainnet\n \"eip155:57073\": \"0x0200C29006150606B650577BBE7B6248F58470c1\",\n // Berachain Mainnet\n \"eip155:80094\": \"0x779Ded0c9e1022225f8E0630b35a9b54bE713736\",\n // Unichain Mainnet (updated address)\n \"eip155:130\": \"0x9151434b16b9763660705744891fA906F660EcC5\",\n\n // === Phase 1: High Priority Networks ===\n // Polygon PoS\n \"eip155:137\": \"0xc2132D05D31c914a87C6611C10748AEb04B58e8F\",\n // Mantle\n \"eip155:5000\": \"0x779Ded0c9e1022225f8E0630b35a9b54bE713736\",\n // Optimism\n \"eip155:10\": \"0x01bFF41798a0BcF287b996046Ca68b395DbC1071\",\n // Plasma\n \"eip155:9745\": \"0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb\",\n // Sei\n \"eip155:1329\": \"0x9151434b16b9763660705744891fA906F660EcC5\",\n // Conflux eSpace\n \"eip155:1030\": \"0xaf37E8B6C9ED7f6318979f56Fc287d76c30847ff\",\n // Monad\n \"eip155:143\": \"0xe7cd86e13AC4309349F30B3435a9d337750fC82D\",\n\n // === Phase 2: Medium Priority Networks ===\n // Rootstock (Bitcoin sidechain)\n \"eip155:30\": \"0x779dED0C9e1022225F8e0630b35A9B54Be713736\",\n // XLayer (OKX L2)\n \"eip155:196\": \"0x779Ded0c9e1022225f8E0630b35a9b54bE713736\",\n // Flare\n \"eip155:14\": \"0xe7cd86e13AC4309349F30B3435a9d337750fC82D\",\n // Corn\n \"eip155:21000000\": \"0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb\",\n // HyperEVM\n \"eip155:999\": \"0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb\",\n // MegaETH\n \"eip155:4326\": \"0xb8ce59fc3717ada4c02eadf9682a9e934f625ebb\",\n // Stable\n \"eip155:988\": \"0x779Ded0c9e1022225f8E0630b35a9b54bE713736\",\n};\n\n/**\n * USDC Contract Addresses by Network\n * Native USDC with EIP-3009 support\n */\nexport const USDC_ADDRESSES: Record<string, Address> = {\n // Ethereum Mainnet\n \"eip155:1\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n // Base Mainnet\n \"eip155:8453\": \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n // Base Sepolia (testnet)\n \"eip155:84532\": \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\",\n // Sepolia (testnet)\n \"eip155:11155111\": \"0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238\",\n // Arbitrum One\n \"eip155:42161\": \"0xaf88d065e77c8cC2239327C5EDb3A432268e5831\",\n // Polygon Mainnet\n \"eip155:137\": \"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359\",\n};\n\n/**\n * Traditional USDT Addresses (Legacy - no EIP-3009 support)\n * These require the approve + transferFrom pattern\n */\nexport const USDT_LEGACY_ADDRESSES: Record<string, Address> = {\n // Ethereum Mainnet\n \"eip155:1\": \"0xdAC17F958D2ee523a2206206994597C13D831ec7\",\n // Polygon Mainnet (native USDT, not USDT0)\n \"eip155:137\": \"0xc2132D05D31c914a87C6611C10748AEb04B58e8F\",\n // BNB Chain (BSC) - BEP-20 USDT\n \"eip155:56\": \"0x55d398326f99059fF775485246999027B3197955\",\n // Avalanche C-Chain\n \"eip155:43114\": \"0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7\",\n // Fantom\n \"eip155:250\": \"0x049d68029688eabf473097a2fc38ef61633a3c7a\",\n // Celo\n \"eip155:42220\": \"0x48065fbBE25f71C9282ddf5e1cD6D6A887483D5e\",\n // Kaia (formerly Klaytn)\n \"eip155:8217\": \"0xcee8faf64bb97a73bb51e115aa89c17ffa8dd167\",\n};\n\n/**\n * Complete token registry with all supported tokens per network\n */\nexport const TOKEN_REGISTRY: NetworkTokenRegistry = {\n // Ethereum Mainnet\n \"eip155:1\": {\n USDT0: {\n address: USDT0_ADDRESSES[\"eip155:1\"],\n symbol: \"USDT0\",\n name: \"TetherToken\",\n version: \"1\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 1,\n },\n USDC: {\n address: USDC_ADDRESSES[\"eip155:1\"],\n symbol: \"USDC\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 2,\n },\n USDT: {\n address: USDT_LEGACY_ADDRESSES[\"eip155:1\"],\n symbol: \"USDT\",\n name: \"TetherUSD\",\n version: \"1\",\n decimals: 6,\n tokenType: \"legacy\",\n priority: 10, // Lower priority due to legacy flow\n },\n },\n\n // Arbitrum One\n \"eip155:42161\": {\n USDT0: {\n address: USDT0_ADDRESSES[\"eip155:42161\"],\n symbol: \"USDT0\",\n name: \"TetherToken\",\n version: \"1\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 1,\n },\n USDC: {\n address: USDC_ADDRESSES[\"eip155:42161\"],\n symbol: \"USDC\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 2,\n },\n },\n\n // Ink Mainnet\n \"eip155:57073\": {\n USDT0: {\n address: USDT0_ADDRESSES[\"eip155:57073\"],\n symbol: \"USDT0\",\n name: \"TetherToken\",\n version: \"1\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 1,\n },\n },\n\n // Berachain Mainnet\n \"eip155:80094\": {\n USDT0: {\n address: USDT0_ADDRESSES[\"eip155:80094\"],\n symbol: \"USDT0\",\n name: \"TetherToken\",\n version: \"1\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 1,\n },\n },\n\n // Unichain Mainnet\n \"eip155:130\": {\n USDT0: {\n address: USDT0_ADDRESSES[\"eip155:130\"],\n symbol: \"USDT0\",\n name: \"TetherToken\",\n version: \"1\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 1,\n },\n },\n\n // Base Mainnet\n \"eip155:8453\": {\n USDC: {\n address: USDC_ADDRESSES[\"eip155:8453\"],\n symbol: \"USDC\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 2,\n },\n },\n\n // Base Sepolia (testnet)\n \"eip155:84532\": {\n USDC: {\n address: USDC_ADDRESSES[\"eip155:84532\"],\n symbol: \"USDC\",\n name: \"USDC\",\n version: \"2\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 2,\n },\n },\n\n // Sepolia (testnet)\n \"eip155:11155111\": {\n USDC: {\n address: USDC_ADDRESSES[\"eip155:11155111\"],\n symbol: \"USDC\",\n name: \"USDC\",\n version: \"2\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 2,\n },\n },\n\n // Polygon Mainnet\n \"eip155:137\": {\n USDT0: {\n address: USDT0_ADDRESSES[\"eip155:137\"],\n symbol: \"USDT0\",\n name: \"TetherToken\",\n version: \"1\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 1,\n },\n USDC: {\n address: USDC_ADDRESSES[\"eip155:137\"],\n symbol: \"USDC\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 2,\n },\n USDT: {\n address: USDT_LEGACY_ADDRESSES[\"eip155:137\"],\n symbol: \"USDT\",\n name: \"TetherUSD\",\n version: \"1\",\n decimals: 6,\n tokenType: \"legacy\",\n priority: 10,\n },\n },\n\n // === Phase 1: High Priority USDT0 Networks ===\n\n // Optimism Mainnet\n \"eip155:10\": {\n USDT0: {\n address: USDT0_ADDRESSES[\"eip155:10\"],\n symbol: \"USDT0\",\n name: \"TetherToken\",\n version: \"1\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 1,\n },\n },\n\n // Mantle Mainnet\n \"eip155:5000\": {\n USDT0: {\n address: USDT0_ADDRESSES[\"eip155:5000\"],\n symbol: \"USDT0\",\n name: \"TetherToken\",\n version: \"1\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 1,\n },\n },\n\n // Plasma Mainnet\n \"eip155:9745\": {\n USDT0: {\n address: USDT0_ADDRESSES[\"eip155:9745\"],\n symbol: \"USDT0\",\n name: \"TetherToken\",\n version: \"1\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 1,\n },\n },\n\n // Sei Mainnet\n \"eip155:1329\": {\n USDT0: {\n address: USDT0_ADDRESSES[\"eip155:1329\"],\n symbol: \"USDT0\",\n name: \"TetherToken\",\n version: \"1\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 1,\n },\n },\n\n // Conflux eSpace Mainnet\n \"eip155:1030\": {\n USDT0: {\n address: USDT0_ADDRESSES[\"eip155:1030\"],\n symbol: \"USDT0\",\n name: \"TetherToken\",\n version: \"1\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 1,\n },\n },\n\n // Monad Mainnet\n \"eip155:143\": {\n USDT0: {\n address: USDT0_ADDRESSES[\"eip155:143\"],\n symbol: \"USDT0\",\n name: \"TetherToken\",\n version: \"1\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 1,\n },\n },\n\n // === Phase 2: Medium Priority USDT0 Networks ===\n\n // Flare Mainnet\n \"eip155:14\": {\n USDT0: {\n address: USDT0_ADDRESSES[\"eip155:14\"],\n symbol: \"USDT0\",\n name: \"TetherToken\",\n version: \"1\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 1,\n },\n },\n\n // Rootstock Mainnet (Bitcoin sidechain)\n \"eip155:30\": {\n USDT0: {\n address: USDT0_ADDRESSES[\"eip155:30\"],\n symbol: \"USDT0\",\n name: \"TetherToken\",\n version: \"1\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 1,\n },\n },\n\n // XLayer Mainnet (OKX L2)\n \"eip155:196\": {\n USDT0: {\n address: USDT0_ADDRESSES[\"eip155:196\"],\n symbol: \"USDT0\",\n name: \"TetherToken\",\n version: \"1\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 1,\n },\n },\n\n // Stable Mainnet\n \"eip155:988\": {\n USDT0: {\n address: USDT0_ADDRESSES[\"eip155:988\"],\n symbol: \"USDT0\",\n name: \"TetherToken\",\n version: \"1\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 1,\n },\n },\n\n // HyperEVM Mainnet\n \"eip155:999\": {\n USDT0: {\n address: USDT0_ADDRESSES[\"eip155:999\"],\n symbol: \"USDT0\",\n name: \"TetherToken\",\n version: \"1\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 1,\n },\n },\n\n // MegaETH Mainnet\n \"eip155:4326\": {\n USDT0: {\n address: USDT0_ADDRESSES[\"eip155:4326\"],\n symbol: \"USDT0\",\n name: \"TetherToken\",\n version: \"1\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 1,\n },\n },\n\n // Corn Mainnet\n \"eip155:21000000\": {\n USDT0: {\n address: USDT0_ADDRESSES[\"eip155:21000000\"],\n symbol: \"USDT0\",\n name: \"TetherToken\",\n version: \"1\",\n decimals: 6,\n tokenType: \"eip3009\",\n priority: 1,\n },\n },\n\n // === Legacy USDT Networks (no EIP-3009 support) ===\n\n // BNB Chain (BSC) - BEP-20 USDT\n \"eip155:56\": {\n USDT: {\n address: USDT_LEGACY_ADDRESSES[\"eip155:56\"],\n symbol: \"USDT\",\n name: \"Tether USD\",\n version: \"1\",\n decimals: 18, // BSC USDT uses 18 decimals\n tokenType: \"legacy\",\n priority: 10,\n },\n },\n\n // Avalanche C-Chain\n \"eip155:43114\": {\n USDT: {\n address: USDT_LEGACY_ADDRESSES[\"eip155:43114\"],\n symbol: \"USDT\",\n name: \"TetherToken\",\n version: \"1\",\n decimals: 6,\n tokenType: \"legacy\",\n priority: 10,\n },\n },\n\n // Fantom\n \"eip155:250\": {\n USDT: {\n address: USDT_LEGACY_ADDRESSES[\"eip155:250\"],\n symbol: \"USDT\",\n name: \"Frapped USDT\",\n version: \"1\",\n decimals: 6,\n tokenType: \"legacy\",\n priority: 10,\n },\n },\n\n // Celo\n \"eip155:42220\": {\n USDT: {\n address: USDT_LEGACY_ADDRESSES[\"eip155:42220\"],\n symbol: \"USDT\",\n name: \"Tether USD\",\n version: \"1\",\n decimals: 18,\n tokenType: \"legacy\",\n priority: 10,\n },\n },\n\n // Kaia (formerly Klaytn)\n \"eip155:8217\": {\n USDT: {\n address: USDT_LEGACY_ADDRESSES[\"eip155:8217\"],\n symbol: \"USDT\",\n name: \"Tether USD\",\n version: \"1\",\n decimals: 6,\n tokenType: \"legacy\",\n priority: 10,\n },\n },\n};\n\n/**\n * Token priority for payment method selection\n * Lower number = higher priority\n */\nexport const TOKEN_PRIORITY: Record<string, number> = {\n USDT0: 1, // Highest priority - gasless, cross-chain\n USDC: 2, // Second - wide support, EIP-3009\n USDT: 10, // Lower - requires approval transaction\n DAI: 5, // Medium - good support\n};\n\n/**\n * Get token configuration for a specific token on a network\n *\n * @param network - The network identifier in CAIP-2 format\n * @param symbol - The token symbol (e.g., \"USDT0\", \"USDC\")\n * @returns The token configuration if found, undefined otherwise\n */\nexport function getTokenConfig(network: string, symbol: string): TokenConfig | undefined {\n return TOKEN_REGISTRY[network]?.[symbol.toUpperCase()];\n}\n\n/**\n * Get all tokens available on a network\n *\n * @param network - The network identifier in CAIP-2 format\n * @returns Array of token configurations sorted by priority\n */\nexport function getNetworkTokens(network: string): TokenConfig[] {\n const tokens = TOKEN_REGISTRY[network];\n if (!tokens) return [];\n return Object.values(tokens).sort((a, b) => a.priority - b.priority);\n}\n\n/**\n * Get the default/preferred token for a network\n * Prefers USDT0 > USDC > others based on priority\n *\n * @param network - The network identifier in CAIP-2 format\n * @returns The highest priority token configuration, or undefined if none found\n */\nexport function getDefaultToken(network: string): TokenConfig | undefined {\n const tokens = getNetworkTokens(network);\n return tokens[0]; // Already sorted by priority\n}\n\n/**\n * Get token by contract address on a network\n *\n * @param network - The network identifier in CAIP-2 format\n * @param address - The token contract address\n * @returns The token configuration if found, undefined otherwise\n */\nexport function getTokenByAddress(network: string, address: Address): TokenConfig | undefined {\n const tokens = TOKEN_REGISTRY[network];\n if (!tokens) return undefined;\n\n const lowerAddress = address.toLowerCase();\n return Object.values(tokens).find(t => t.address.toLowerCase() === lowerAddress);\n}\n\n/**\n * Check if a token supports EIP-3009 (gasless transfers)\n *\n * @param network - The network identifier in CAIP-2 format\n * @param symbol - The token symbol to check\n * @returns True if the token supports EIP-3009 gasless transfers\n */\nexport function supportsEIP3009(network: string, symbol: string): boolean {\n const config = getTokenConfig(network, symbol);\n return config?.tokenType === \"eip3009\";\n}\n\n/**\n * Get all networks that support a specific token\n *\n * @param symbol - The token symbol to search for\n * @returns Array of network identifiers that support the token\n */\nexport function getNetworksForToken(symbol: string): string[] {\n const networks: string[] = [];\n for (const [network, tokens] of Object.entries(TOKEN_REGISTRY)) {\n if (tokens[symbol.toUpperCase()]) {\n networks.push(network);\n }\n }\n return networks;\n}\n\n/**\n * Get USDT0 networks (primary T402 token)\n *\n * @returns Array of network identifiers that support USDT0\n */\nexport function getUsdt0Networks(): string[] {\n return getNetworksForToken(\"USDT0\");\n}\n\n/**\n * EIP-712 domain configuration for a token\n *\n * @param network - The network identifier in CAIP-2 format\n * @param tokenAddress - The token contract address\n * @param chainId - The numeric chain ID\n * @returns The EIP-712 domain configuration, or undefined if token not found\n */\nexport function getEIP712Domain(\n network: string,\n tokenAddress: Address,\n chainId: number,\n): { name: string; version: string; chainId: number; verifyingContract: Address } | undefined {\n const token = getTokenByAddress(network, tokenAddress);\n if (!token) return undefined;\n\n return {\n name: token.name,\n version: token.version,\n chainId,\n verifyingContract: token.address,\n };\n}\n","import {\n PaymentPayload,\n PaymentRequirements,\n SchemeNetworkFacilitator,\n SettleResponse,\n VerifyResponse,\n} from \"@t402/core/types\";\nimport { getAddress, Hex, encodeFunctionData, parseAbi } from \"viem\";\nimport { permitTypes, UptoEIP2612Payload, isUptoEIP2612Payload } from \"../../types.js\";\nimport { FacilitatorEvmSigner } from \"../../signer.js\";\n\n/**\n * T402UptoRouter contract ABI (only the functions we need)\n */\nconst T402_UPTO_ROUTER_ABI = parseAbi([\n \"function executeUptoTransfer(address token, address from, address to, uint256 maxAmount, uint256 settleAmount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external\",\n \"function isFacilitator(address facilitator) external view returns (bool)\",\n \"function checkPermitValidity(address token, address from, uint256 maxAmount) external view returns (bool valid, uint256 balance)\",\n]);\n\n/**\n * Configuration for UptoEvmFacilitatorScheme\n */\nexport interface UptoEvmFacilitatorSchemeConfig {\n /**\n * Router contract addresses by network (CAIP-2 format)\n *\n * @example { \"eip155:8453\": \"0x...\" }\n */\n routerAddresses?: Record<string, string>;\n}\n\n/**\n * EVM facilitator implementation for the Up-To payment scheme.\n *\n * Handles verification and settlement of upto payments using\n * the T402UptoRouter contract.\n *\n * @example\n * ```typescript\n * import { UptoEvmFacilitatorScheme } from \"@t402/evm/upto/facilitator\";\n *\n * const facilitator = new UptoEvmFacilitatorScheme(signer, {\n * routerAddresses: {\n * \"eip155:8453\": \"0x...\", // Base mainnet router\n * \"eip155:84532\": \"0x...\", // Base Sepolia router\n * },\n * });\n *\n * facilitatorServer.registerScheme(facilitator);\n * ```\n */\nexport class UptoEvmFacilitatorScheme implements SchemeNetworkFacilitator {\n readonly scheme = \"upto\";\n readonly caipFamily = \"eip155:*\";\n private readonly config: UptoEvmFacilitatorSchemeConfig;\n\n /**\n * Creates a new UptoEvmFacilitatorScheme instance.\n *\n * @param signer - The EVM signer for facilitator operations\n * @param config - Optional configuration\n */\n constructor(\n private readonly signer: FacilitatorEvmSigner,\n config?: UptoEvmFacilitatorSchemeConfig,\n ) {\n this.config = config ?? {};\n }\n\n /**\n * Get mechanism-specific extra data for the supported kinds endpoint.\n *\n * @param network - The network identifier\n * @returns Extra data including router address if configured\n */\n getExtra(network: string): Record<string, unknown> | undefined {\n const routerAddress = this.config.routerAddresses?.[network];\n if (routerAddress) {\n return { routerAddress };\n }\n return undefined;\n }\n\n /**\n * Get signer addresses used by this facilitator.\n *\n * @param _ - The network identifier (unused for EVM)\n * @returns Array of facilitator wallet addresses\n */\n getSigners(_: string): string[] {\n return [...this.signer.getAddresses()];\n }\n\n /**\n * Verifies an upto payment payload.\n *\n * @param payload - The payment payload to verify\n * @param requirements - The payment requirements\n * @returns Promise resolving to verification response\n */\n async verify(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<VerifyResponse> {\n const uptoPayload = payload.payload as UptoEIP2612Payload | undefined;\n\n // Validate payload structure\n if (!uptoPayload || !isUptoEIP2612Payload(uptoPayload)) {\n return {\n isValid: false,\n invalidReason: \"invalid_payload_structure\",\n payer: undefined,\n };\n }\n\n // Verify scheme matches\n if (payload.accepted.scheme !== \"upto\" || requirements.scheme !== \"upto\") {\n return {\n isValid: false,\n invalidReason: \"unsupported_scheme\",\n payer: uptoPayload.authorization.owner,\n };\n }\n\n // Verify EIP-712 domain parameters exist\n if (!requirements.extra?.name || !requirements.extra?.version) {\n return {\n isValid: false,\n invalidReason: \"missing_eip712_domain\",\n payer: uptoPayload.authorization.owner,\n };\n }\n\n // Get maxAmount from extra\n const maxAmount = requirements.extra?.maxAmount as string | undefined;\n if (!maxAmount) {\n return {\n isValid: false,\n invalidReason: \"missing_maxAmount\",\n payer: uptoPayload.authorization.owner,\n };\n }\n\n // Verify network matches\n if (payload.accepted.network !== requirements.network) {\n return {\n isValid: false,\n invalidReason: \"network_mismatch\",\n payer: uptoPayload.authorization.owner,\n };\n }\n\n // Verify deadline hasn't passed\n const deadline = parseInt(uptoPayload.authorization.deadline);\n const now = Math.floor(Date.now() / 1000);\n if (deadline <= now) {\n return {\n isValid: false,\n invalidReason: \"permit_expired\",\n payer: uptoPayload.authorization.owner,\n };\n }\n\n // Verify maxAmount matches\n if (uptoPayload.authorization.value !== maxAmount) {\n return {\n isValid: false,\n invalidReason: \"amount_mismatch\",\n payer: uptoPayload.authorization.owner,\n };\n }\n\n // Build typed data for signature verification\n const chainId = parseInt(requirements.network.split(\":\")[1]);\n const permitTypedData = {\n types: permitTypes,\n primaryType: \"Permit\" as const,\n domain: {\n name: requirements.extra.name as string,\n version: requirements.extra.version as string,\n chainId,\n verifyingContract: getAddress(requirements.asset),\n },\n message: {\n owner: getAddress(uptoPayload.authorization.owner),\n spender: getAddress(uptoPayload.authorization.spender),\n value: BigInt(uptoPayload.authorization.value),\n nonce: BigInt(uptoPayload.authorization.nonce),\n deadline: BigInt(uptoPayload.authorization.deadline),\n },\n };\n\n // Reconstruct signature\n const signature =\n `0x${uptoPayload.signature.r.slice(2)}${uptoPayload.signature.s.slice(2)}${uptoPayload.signature.v.toString(16).padStart(2, \"0\")}` as Hex;\n\n // Verify signature\n try {\n const isValid = await this.signer.verifyTypedData({\n address: uptoPayload.authorization.owner,\n ...permitTypedData,\n signature,\n });\n\n if (!isValid) {\n return {\n isValid: false,\n invalidReason: \"invalid_signature\",\n payer: uptoPayload.authorization.owner,\n };\n }\n } catch (error) {\n return {\n isValid: false,\n invalidReason: `signature_verification_failed: ${error instanceof Error ? error.message : \"unknown\"}`,\n payer: uptoPayload.authorization.owner,\n };\n }\n\n return {\n isValid: true,\n payer: uptoPayload.authorization.owner,\n };\n }\n\n /**\n * Settles an upto payment by calling the T402UptoRouter contract.\n *\n * @param payload - The verified payment payload\n * @param requirements - The payment requirements\n * @returns Promise resolving to settlement response\n */\n async settle(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<SettleResponse> {\n const uptoPayload = payload.payload as UptoEIP2612Payload;\n\n // Get upto-specific fields from extra\n const maxAmount = requirements.extra?.maxAmount as string;\n const minAmount = requirements.extra?.minAmount as string | undefined;\n const routerAddress = requirements.extra?.routerAddress as string | undefined;\n\n if (!maxAmount) {\n return {\n success: false,\n errorReason: \"maxAmount not found in payment requirements\",\n transaction: \"\",\n network: requirements.network,\n payer: uptoPayload.authorization.owner,\n };\n }\n\n // For upto scheme, settle the maxAmount (actual usage-based settlement\n // would require additional parameters passed via extension)\n const settleAmount = maxAmount;\n\n // Validate minimum amount\n if (minAmount && BigInt(settleAmount) < BigInt(minAmount)) {\n return {\n success: false,\n errorReason: `Settle amount ${settleAmount} below minimum ${minAmount}`,\n transaction: \"\",\n network: requirements.network,\n payer: uptoPayload.authorization.owner,\n };\n }\n\n // Get router address\n if (!routerAddress) {\n return {\n success: false,\n errorReason: \"Router address not configured\",\n transaction: \"\",\n network: requirements.network,\n payer: uptoPayload.authorization.owner,\n };\n }\n\n try {\n // Execute the transfer through the router\n const txHash = await this.signer.sendTransaction({\n to: getAddress(routerAddress),\n data: encodeFunctionData({\n abi: T402_UPTO_ROUTER_ABI,\n functionName: \"executeUptoTransfer\",\n args: [\n getAddress(requirements.asset),\n getAddress(uptoPayload.authorization.owner),\n getAddress(requirements.payTo),\n BigInt(maxAmount),\n BigInt(settleAmount),\n BigInt(uptoPayload.authorization.deadline),\n uptoPayload.signature.v,\n uptoPayload.signature.r as Hex,\n uptoPayload.signature.s as Hex,\n ],\n }),\n });\n\n // Wait for confirmation\n const receipt = await this.signer.waitForTransactionReceipt({ hash: txHash });\n\n if (receipt.status !== \"success\") {\n return {\n success: false,\n errorReason: \"transaction_reverted\",\n transaction: txHash,\n network: requirements.network,\n payer: uptoPayload.authorization.owner,\n };\n }\n\n return {\n success: true,\n transaction: txHash,\n network: requirements.network,\n payer: uptoPayload.authorization.owner,\n };\n } catch (error) {\n return {\n success: false,\n errorReason: `Settlement failed: ${error instanceof Error ? error.message : \"unknown\"}`,\n transaction: \"\",\n network: requirements.network,\n payer: uptoPayload.authorization.owner,\n };\n }\n }\n}\n\n/**\n * Factory function to create an UptoEvmFacilitatorScheme.\n *\n * @param signer - The EVM signer\n * @param config - Configuration options\n * @returns A new UptoEvmFacilitatorScheme instance\n */\nexport function createUptoEvmFacilitatorScheme(\n signer: FacilitatorEvmSigner,\n config?: UptoEvmFacilitatorSchemeConfig,\n): UptoEvmFacilitatorScheme {\n return new UptoEvmFacilitatorScheme(signer, config);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCA,IAAAA,eAA2B;;;ACiIpB,IAAM,cAAc;AAAA,EACzB,QAAQ;AAAA,IACN,EAAE,MAAM,SAAS,MAAM,UAAU;AAAA,IACjC,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,IACnC,EAAE,MAAM,SAAS,MAAM,UAAU;AAAA,IACjC,EAAE,MAAM,SAAS,MAAM,UAAU;AAAA,IACjC,EAAE,MAAM,YAAY,MAAM,UAAU;AAAA,EACtC;AACF;AAQO,SAAS,qBAAqB,SAAiD;AACpF,MAAI,OAAO,YAAY,YAAY,YAAY,KAAM,QAAO;AAC5D,QAAM,IAAI;AACV,SACE,eAAe,KACf,mBAAmB,KACnB,kBAAkB,KAClB,OAAO,EAAE,kBAAkB,YAC3B,EAAE,kBAAkB,QACpB,WAAY,EAAE,iBACd,aAAc,EAAE,iBAChB,WAAY,EAAE,iBACd,cAAe,EAAE,iBACjB,WAAY,EAAE;AAElB;;;ACjKA,kBAAsB;AA2Bf,SAAS,cAA6B;AAE3C,QAAM,YACJ,OAAO,WAAW,WAAW,cACzB,WAAW,SACV,WAAmC;AAE1C,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,MAAM,0BAA0B;AAAA,EAC5C;AAEA,aAAO,mBAAM,UAAU,gBAAgB,IAAI,WAAW,EAAE,CAAC,CAAC;AAC5D;;;AFdO,IAAM,gBAAN,MAAmD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQxD,YAA6B,QAAyB;AAAzB;AAP7B,wBAAS,UAAS;AAAA,EAOqC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAavD,MAAM,qBACJ,aACA,qBAC0D;AAE1D,QAAI,oBAAoB,WAAW,QAAQ;AACzC,YAAM,IAAI,MAAM,6BAA6B,oBAAoB,MAAM,EAAE;AAAA,IAC3E;AAEA,UAAM,QAAQ,oBAAoB;AAClC,QAAI,CAAC,OAAO,QAAQ,CAAC,OAAO,SAAS;AACnC,YAAM,IAAI,MAAM,wEAAwE;AAAA,IAC1F;AAGA,UAAM,YAAa,oBAAyD;AAC5E,QAAI,CAAC,WAAW;AACd,YAAM,IAAI,MAAM,uCAAuC;AAAA,IACzD;AAGA,UAAM,UAAU,MAAM,oBAClB,yBAAW,MAAM,aAAa,QAC9B,yBAAW,oBAAoB,KAAK;AAGxC,UAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,UAAM,WAAW,MAAM,oBAAoB;AAK3C,UAAM,cAAe,MAAmC,eAAe;AAGvE,UAAM,gBAAqD;AAAA,MACzD,OAAO,KAAK,OAAO;AAAA,MACnB;AAAA,MACA,OAAO;AAAA,MACP,UAAU,SAAS,SAAS;AAAA,MAC5B,OAAO;AAAA,IACT;AAGA,UAAM,YAAY,MAAM,KAAK,WAAW,eAAe,mBAAmB;AAG1E,UAAM,eAAe,YAAY;AAEjC,UAAM,UAA8B;AAAA,MAClC;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,WACZ,eACA,cAC0C;AAC1C,UAAM,UAAU,SAAS,aAAa,QAAQ,MAAM,GAAG,EAAE,CAAC,CAAC;AAC3D,UAAM,QAAQ,aAAa;AAE3B,UAAM,SAAS;AAAA,MACb,MAAM,MAAM;AAAA,MACZ,SAAS,MAAM;AAAA,MACf;AAAA,MACA,uBAAmB,yBAAW,aAAa,KAAK;AAAA,IAClD;AAEA,UAAM,UAAU;AAAA,MACd,WAAO,yBAAW,cAAc,KAAK;AAAA,MACrC,aAAS,yBAAW,cAAc,OAAO;AAAA,MACzC,OAAO,OAAO,cAAc,KAAK;AAAA,MACjC,OAAO,OAAO,cAAc,KAAK;AAAA,MACjC,UAAU,OAAO,cAAc,QAAQ;AAAA,IACzC;AAGA,UAAM,YAAY,MAAM,KAAK,OAAO,cAAc;AAAA,MAChD;AAAA,MACA,OAAO;AAAA,MACP,aAAa;AAAA,MACb;AAAA,IACF,CAAC;AAGD,UAAM,IAAI,KAAK,UAAU,MAAM,GAAG,EAAE,CAAC;AACrC,UAAM,IAAI,KAAK,UAAU,MAAM,IAAI,GAAG,CAAC;AACvC,UAAM,IAAI,SAAS,UAAU,MAAM,KAAK,GAAG,GAAG,EAAE;AAEhD,WAAO,EAAE,GAAG,GAAG,EAAE;AAAA,EACnB;AACF;AAQO,SAAS,oBAAoB,QAAwC;AAC1E,SAAO,IAAI,cAAc,MAAM;AACjC;;;AGjKA,IAAAC,gBAQO;;;AC2CA,IAAM,kBAA2C;AAAA;AAAA;AAAA,EAGtD,YAAY;AAAA;AAAA,EAEZ,gBAAgB;AAAA;AAAA,EAEhB,gBAAgB;AAAA;AAAA,EAEhB,gBAAgB;AAAA;AAAA,EAEhB,cAAc;AAAA;AAAA;AAAA,EAId,cAAc;AAAA;AAAA,EAEd,eAAe;AAAA;AAAA,EAEf,aAAa;AAAA;AAAA,EAEb,eAAe;AAAA;AAAA,EAEf,eAAe;AAAA;AAAA,EAEf,eAAe;AAAA;AAAA,EAEf,cAAc;AAAA;AAAA;AAAA,EAId,aAAa;AAAA;AAAA,EAEb,cAAc;AAAA;AAAA,EAEd,aAAa;AAAA;AAAA,EAEb,mBAAmB;AAAA;AAAA,EAEnB,cAAc;AAAA;AAAA,EAEd,eAAe;AAAA;AAAA,EAEf,cAAc;AAChB;AAMO,IAAM,iBAA0C;AAAA;AAAA,EAErD,YAAY;AAAA;AAAA,EAEZ,eAAe;AAAA;AAAA,EAEf,gBAAgB;AAAA;AAAA,EAEhB,mBAAmB;AAAA;AAAA,EAEnB,gBAAgB;AAAA;AAAA,EAEhB,cAAc;AAChB;AAMO,IAAM,wBAAiD;AAAA;AAAA,EAE5D,YAAY;AAAA;AAAA,EAEZ,cAAc;AAAA;AAAA,EAEd,aAAa;AAAA;AAAA,EAEb,gBAAgB;AAAA;AAAA,EAEhB,cAAc;AAAA;AAAA,EAEd,gBAAgB;AAAA;AAAA,EAEhB,eAAe;AACjB;AAKO,IAAM,iBAAuC;AAAA;AAAA,EAElD,YAAY;AAAA,IACV,OAAO;AAAA,MACL,SAAS,gBAAgB,UAAU;AAAA,MACnC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,IACA,MAAM;AAAA,MACJ,SAAS,eAAe,UAAU;AAAA,MAClC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,IACA,MAAM;AAAA,MACJ,SAAS,sBAAsB,UAAU;AAAA,MACzC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,gBAAgB;AAAA,IACd,OAAO;AAAA,MACL,SAAS,gBAAgB,cAAc;AAAA,MACvC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,IACA,MAAM;AAAA,MACJ,SAAS,eAAe,cAAc;AAAA,MACtC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,gBAAgB;AAAA,IACd,OAAO;AAAA,MACL,SAAS,gBAAgB,cAAc;AAAA,MACvC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,gBAAgB;AAAA,IACd,OAAO;AAAA,MACL,SAAS,gBAAgB,cAAc;AAAA,MACvC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,cAAc;AAAA,IACZ,OAAO;AAAA,MACL,SAAS,gBAAgB,YAAY;AAAA,MACrC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,eAAe;AAAA,IACb,MAAM;AAAA,MACJ,SAAS,eAAe,aAAa;AAAA,MACrC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,gBAAgB;AAAA,IACd,MAAM;AAAA,MACJ,SAAS,eAAe,cAAc;AAAA,MACtC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,mBAAmB;AAAA,IACjB,MAAM;AAAA,MACJ,SAAS,eAAe,iBAAiB;AAAA,MACzC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,cAAc;AAAA,IACZ,OAAO;AAAA,MACL,SAAS,gBAAgB,YAAY;AAAA,MACrC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,IACA,MAAM;AAAA,MACJ,SAAS,eAAe,YAAY;AAAA,MACpC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,IACA,MAAM;AAAA,MACJ,SAAS,sBAAsB,YAAY;AAAA,MAC3C,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA;AAAA,EAKA,aAAa;AAAA,IACX,OAAO;AAAA,MACL,SAAS,gBAAgB,WAAW;AAAA,MACpC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,eAAe;AAAA,IACb,OAAO;AAAA,MACL,SAAS,gBAAgB,aAAa;AAAA,MACtC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,eAAe;AAAA,IACb,OAAO;AAAA,MACL,SAAS,gBAAgB,aAAa;AAAA,MACtC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,eAAe;AAAA,IACb,OAAO;AAAA,MACL,SAAS,gBAAgB,aAAa;AAAA,MACtC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,eAAe;AAAA,IACb,OAAO;AAAA,MACL,SAAS,gBAAgB,aAAa;AAAA,MACtC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,cAAc;AAAA,IACZ,OAAO;AAAA,MACL,SAAS,gBAAgB,YAAY;AAAA,MACrC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA;AAAA,EAKA,aAAa;AAAA,IACX,OAAO;AAAA,MACL,SAAS,gBAAgB,WAAW;AAAA,MACpC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,aAAa;AAAA,IACX,OAAO;AAAA,MACL,SAAS,gBAAgB,WAAW;AAAA,MACpC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,cAAc;AAAA,IACZ,OAAO;AAAA,MACL,SAAS,gBAAgB,YAAY;AAAA,MACrC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,cAAc;AAAA,IACZ,OAAO;AAAA,MACL,SAAS,gBAAgB,YAAY;AAAA,MACrC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,cAAc;AAAA,IACZ,OAAO;AAAA,MACL,SAAS,gBAAgB,YAAY;AAAA,MACrC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,eAAe;AAAA,IACb,OAAO;AAAA,MACL,SAAS,gBAAgB,aAAa;AAAA,MACtC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,mBAAmB;AAAA,IACjB,OAAO;AAAA,MACL,SAAS,gBAAgB,iBAAiB;AAAA,MAC1C,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA;AAAA,EAKA,aAAa;AAAA,IACX,MAAM;AAAA,MACJ,SAAS,sBAAsB,WAAW;AAAA,MAC1C,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,gBAAgB;AAAA,IACd,MAAM;AAAA,MACJ,SAAS,sBAAsB,cAAc;AAAA,MAC7C,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,cAAc;AAAA,IACZ,MAAM;AAAA,MACJ,SAAS,sBAAsB,YAAY;AAAA,MAC3C,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,gBAAgB;AAAA,IACd,MAAM;AAAA,MACJ,SAAS,sBAAsB,cAAc;AAAA,MAC7C,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,eAAe;AAAA,IACb,MAAM;AAAA,MACJ,SAAS,sBAAsB,aAAa;AAAA,MAC5C,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AACF;AAoBO,SAAS,eAAe,SAAiB,QAAyC;AACvF,SAAO,eAAe,OAAO,IAAI,OAAO,YAAY,CAAC;AACvD;AAQO,SAAS,iBAAiB,SAAgC;AAC/D,QAAM,SAAS,eAAe,OAAO;AACrC,MAAI,CAAC,OAAQ,QAAO,CAAC;AACrB,SAAO,OAAO,OAAO,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ;AACrE;AASO,SAAS,gBAAgB,SAA0C;AACxE,QAAM,SAAS,iBAAiB,OAAO;AACvC,SAAO,OAAO,CAAC;AACjB;AASO,SAAS,kBAAkB,SAAiB,SAA2C;AAC5F,QAAM,SAAS,eAAe,OAAO;AACrC,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,eAAe,QAAQ,YAAY;AACzC,SAAO,OAAO,OAAO,MAAM,EAAE,KAAK,OAAK,EAAE,QAAQ,YAAY,MAAM,YAAY;AACjF;;;ADriBO,IAAM,sBAAN,MAAyD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU9D,YAAY,SAAoC,CAAC,GAAG;AATpD,wBAAS,UAAS;AAClB,wBAAQ,gBAA8B,CAAC;AACvC,wBAAQ;AAQN,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,uBAAiC;AACtC,WAAO,OAAO,KAAK,cAAc;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,mBAAmB,SAA0B;AAClD,WAAO,WAAW;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,oBAAoB,QAA0C;AAC5D,SAAK,aAAa,KAAK,MAAM;AAC7B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,WAAW,OAAc,SAAwC;AAErE,QAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,YAAY,OAAO;AACpE,UAAI,CAAC,MAAM,OAAO;AAChB,cAAMC,SAAQ,KAAK,kBAAkB,OAAO;AAC5C,eAAO,EAAE,QAAQ,MAAM,QAAQ,OAAOA,OAAM,QAAQ;AAAA,MACtD;AACA,aAAO;AAAA,IACT;AAGA,UAAM,gBAAgB,KAAK,eAAe,KAAK;AAG/C,eAAW,UAAU,KAAK,cAAc;AACtC,YAAM,SAAS,MAAM,OAAO,eAAe,OAAO;AAClD,UAAI,WAAW,MAAM;AACnB,eAAO;AAAA,MACT;AAAA,IACF;AAGA,UAAM,QAAQ,KAAK,kBAAkB,OAAO;AAC5C,UAAM,SAAS,KAAK,MAAM,gBAAgB,MAAM,MAAM,QAAQ,EAAE,SAAS;AAEzE,WAAO;AAAA,MACL;AAAA,MACA,OAAO,MAAM;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,2BACJ,qBACA,eAMA,uBAC8B;AAE9B,SAAK;AAEL,UAAM,UAAU,cAAc;AAC9B,UAAM,QAAQ,kBAAkB,SAAS,oBAAoB,KAAsB;AAEnF,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,MAAM,iBAAiB,oBAAoB,KAAK,OAAO,OAAO,EAAE;AAAA,IAC5E;AAGA,UAAM,QAAiC;AAAA;AAAA,MAErC,MAAM,MAAM;AAAA,MACZ,SAAS,MAAM;AAAA;AAAA,MAGf,GAAI,KAAK,OAAO,iBAAiB,EAAE,eAAe,KAAK,OAAO,cAAc;AAAA;AAAA,MAG5E,GAAI,KAAK,OAAO,eAAe,EAAE,MAAM,KAAK,OAAO,YAAY;AAAA,MAC/D,GAAI,KAAK,OAAO,oBAAoB,EAAE,WAAW,KAAK,OAAO,iBAAiB;AAAA;AAAA,MAG9E,WAAW,oBAAoB;AAAA,MAC/B,WAAW,4BAAc;AAAA;AAAA,MAGzB,GAAG,cAAc;AAAA,IACnB;AAEA,WAAO;AAAA,MACL,GAAG;AAAA,MACH,QAAQ;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,kBAAkB,SAA+B;AACvD,QAAI,KAAK,OAAO,gBAAgB;AAC9B,YAAM,QAAQ,eAAe,SAAS,KAAK,OAAO,cAAc;AAChE,UAAI,MAAO,QAAO;AAAA,IACpB;AACA,UAAM,eAAe,gBAAgB,OAAO;AAC5C,QAAI,CAAC,cAAc;AACjB,YAAM,IAAI,MAAM,mCAAmC,OAAO,EAAE;AAAA,IAC9D;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,eAAe,OAAgC;AACrD,QAAI,OAAO,UAAU,UAAU;AAC7B,aAAO;AAAA,IACT;AAGA,UAAM,UAAU,MAAM,QAAQ,SAAS,EAAE,EAAE,KAAK;AAChD,UAAM,SAAS,WAAW,OAAO;AAEjC,QAAI,MAAM,MAAM,GAAG;AACjB,YAAM,IAAI,MAAM,yBAAyB,KAAK,EAAE;AAAA,IAClD;AAEA,WAAO;AAAA,EACT;AACF;AAQO,SAAS,0BAA0B,QAAyD;AACjG,SAAO,IAAI,oBAAoB,MAAM;AACvC;;;AE/OA,IAAAC,eAA8D;AAO9D,IAAM,2BAAuB,uBAAS;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAkCM,IAAM,2BAAN,MAAmE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWxE,YACmB,QACjB,QACA;AAFiB;AAXnB,wBAAS,UAAS;AAClB,wBAAS,cAAa;AACtB,wBAAiB;AAYf,SAAK,SAAS,UAAU,CAAC;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,SAAS,SAAsD;AAC7D,UAAM,gBAAgB,KAAK,OAAO,kBAAkB,OAAO;AAC3D,QAAI,eAAe;AACjB,aAAO,EAAE,cAAc;AAAA,IACzB;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,WAAW,GAAqB;AAC9B,WAAO,CAAC,GAAG,KAAK,OAAO,aAAa,CAAC;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OACJ,SACA,cACyB;AACzB,UAAM,cAAc,QAAQ;AAG5B,QAAI,CAAC,eAAe,CAAC,qBAAqB,WAAW,GAAG;AACtD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,QACf,OAAO;AAAA,MACT;AAAA,IACF;AAGA,QAAI,QAAQ,SAAS,WAAW,UAAU,aAAa,WAAW,QAAQ;AACxE,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,QACf,OAAO,YAAY,cAAc;AAAA,MACnC;AAAA,IACF;AAGA,QAAI,CAAC,aAAa,OAAO,QAAQ,CAAC,aAAa,OAAO,SAAS;AAC7D,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,QACf,OAAO,YAAY,cAAc;AAAA,MACnC;AAAA,IACF;AAGA,UAAM,YAAY,aAAa,OAAO;AACtC,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,QACf,OAAO,YAAY,cAAc;AAAA,MACnC;AAAA,IACF;AAGA,QAAI,QAAQ,SAAS,YAAY,aAAa,SAAS;AACrD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,QACf,OAAO,YAAY,cAAc;AAAA,MACnC;AAAA,IACF;AAGA,UAAM,WAAW,SAAS,YAAY,cAAc,QAAQ;AAC5D,UAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,QAAI,YAAY,KAAK;AACnB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,QACf,OAAO,YAAY,cAAc;AAAA,MACnC;AAAA,IACF;AAGA,QAAI,YAAY,cAAc,UAAU,WAAW;AACjD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,QACf,OAAO,YAAY,cAAc;AAAA,MACnC;AAAA,IACF;AAGA,UAAM,UAAU,SAAS,aAAa,QAAQ,MAAM,GAAG,EAAE,CAAC,CAAC;AAC3D,UAAM,kBAAkB;AAAA,MACtB,OAAO;AAAA,MACP,aAAa;AAAA,MACb,QAAQ;AAAA,QACN,MAAM,aAAa,MAAM;AAAA,QACzB,SAAS,aAAa,MAAM;AAAA,QAC5B;AAAA,QACA,uBAAmB,yBAAW,aAAa,KAAK;AAAA,MAClD;AAAA,MACA,SAAS;AAAA,QACP,WAAO,yBAAW,YAAY,cAAc,KAAK;AAAA,QACjD,aAAS,yBAAW,YAAY,cAAc,OAAO;AAAA,QACrD,OAAO,OAAO,YAAY,cAAc,KAAK;AAAA,QAC7C,OAAO,OAAO,YAAY,cAAc,KAAK;AAAA,QAC7C,UAAU,OAAO,YAAY,cAAc,QAAQ;AAAA,MACrD;AAAA,IACF;AAGA,UAAM,YACJ,KAAK,YAAY,UAAU,EAAE,MAAM,CAAC,CAAC,GAAG,YAAY,UAAU,EAAE,MAAM,CAAC,CAAC,GAAG,YAAY,UAAU,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC;AAGlI,QAAI;AACF,YAAM,UAAU,MAAM,KAAK,OAAO,gBAAgB;AAAA,QAChD,SAAS,YAAY,cAAc;AAAA,QACnC,GAAG;AAAA,QACH;AAAA,MACF,CAAC;AAED,UAAI,CAAC,SAAS;AACZ,eAAO;AAAA,UACL,SAAS;AAAA,UACT,eAAe;AAAA,UACf,OAAO,YAAY,cAAc;AAAA,QACnC;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe,kCAAkC,iBAAiB,QAAQ,MAAM,UAAU,SAAS;AAAA,QACnG,OAAO,YAAY,cAAc;AAAA,MACnC;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO,YAAY,cAAc;AAAA,IACnC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OACJ,SACA,cACyB;AACzB,UAAM,cAAc,QAAQ;AAG5B,UAAM,YAAY,aAAa,OAAO;AACtC,UAAM,YAAY,aAAa,OAAO;AACtC,UAAM,gBAAgB,aAAa,OAAO;AAE1C,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,QACL,SAAS;AAAA,QACT,aAAa;AAAA,QACb,aAAa;AAAA,QACb,SAAS,aAAa;AAAA,QACtB,OAAO,YAAY,cAAc;AAAA,MACnC;AAAA,IACF;AAIA,UAAM,eAAe;AAGrB,QAAI,aAAa,OAAO,YAAY,IAAI,OAAO,SAAS,GAAG;AACzD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,aAAa,iBAAiB,YAAY,kBAAkB,SAAS;AAAA,QACrE,aAAa;AAAA,QACb,SAAS,aAAa;AAAA,QACtB,OAAO,YAAY,cAAc;AAAA,MACnC;AAAA,IACF;AAGA,QAAI,CAAC,eAAe;AAClB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,aAAa;AAAA,QACb,aAAa;AAAA,QACb,SAAS,aAAa;AAAA,QACtB,OAAO,YAAY,cAAc;AAAA,MACnC;AAAA,IACF;AAEA,QAAI;AAEF,YAAM,SAAS,MAAM,KAAK,OAAO,gBAAgB;AAAA,QAC/C,QAAI,yBAAW,aAAa;AAAA,QAC5B,UAAM,iCAAmB;AAAA,UACvB,KAAK;AAAA,UACL,cAAc;AAAA,UACd,MAAM;AAAA,gBACJ,yBAAW,aAAa,KAAK;AAAA,gBAC7B,yBAAW,YAAY,cAAc,KAAK;AAAA,gBAC1C,yBAAW,aAAa,KAAK;AAAA,YAC7B,OAAO,SAAS;AAAA,YAChB,OAAO,YAAY;AAAA,YACnB,OAAO,YAAY,cAAc,QAAQ;AAAA,YACzC,YAAY,UAAU;AAAA,YACtB,YAAY,UAAU;AAAA,YACtB,YAAY,UAAU;AAAA,UACxB;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAGD,YAAM,UAAU,MAAM,KAAK,OAAO,0BAA0B,EAAE,MAAM,OAAO,CAAC;AAE5E,UAAI,QAAQ,WAAW,WAAW;AAChC,eAAO;AAAA,UACL,SAAS;AAAA,UACT,aAAa;AAAA,UACb,aAAa;AAAA,UACb,SAAS,aAAa;AAAA,UACtB,OAAO,YAAY,cAAc;AAAA,QACnC;AAAA,MACF;AAEA,aAAO;AAAA,QACL,SAAS;AAAA,QACT,aAAa;AAAA,QACb,SAAS,aAAa;AAAA,QACtB,OAAO,YAAY,cAAc;AAAA,MACnC;AAAA,IACF,SAAS,OAAO;AACd,aAAO;AAAA,QACL,SAAS;AAAA,QACT,aAAa,sBAAsB,iBAAiB,QAAQ,MAAM,UAAU,SAAS;AAAA,QACrF,aAAa;AAAA,QACb,SAAS,aAAa;AAAA,QACtB,OAAO,YAAY,cAAc;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AACF;AASO,SAAS,+BACd,QACA,QAC0B;AAC1B,SAAO,IAAI,yBAAyB,QAAQ,MAAM;AACpD;","names":["import_viem","import_types","token","import_viem"]}
|
package/dist/cjs/v1/index.d.ts
CHANGED
package/dist/cjs/v1/index.js
CHANGED
|
@@ -3,6 +3,7 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6
7
|
var __export = (target, all) => {
|
|
7
8
|
for (var name in all)
|
|
8
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -16,6 +17,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
17
|
return to;
|
|
17
18
|
};
|
|
18
19
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
19
21
|
|
|
20
22
|
// src/v1/index.ts
|
|
21
23
|
var v1_exports = {};
|
|
@@ -70,7 +72,7 @@ var ExactEvmSchemeV1 = class {
|
|
|
70
72
|
*/
|
|
71
73
|
constructor(signer) {
|
|
72
74
|
this.signer = signer;
|
|
73
|
-
this
|
|
75
|
+
__publicField(this, "scheme", "exact");
|
|
74
76
|
}
|
|
75
77
|
/**
|
|
76
78
|
* Creates a payment payload for the Exact scheme (V1).
|
package/dist/cjs/v1/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/v1/index.ts","../../../src/exact/v1/client/scheme.ts","../../../src/constants.ts","../../../src/utils.ts","../../../src/exact/v1/facilitator/scheme.ts"],"sourcesContent":["export { ExactEvmSchemeV1 } from \"../exact/v1\";\n\nexport const NETWORKS: string[] = [\n \"abstract\",\n \"abstract-testnet\",\n \"base-sepolia\",\n \"base\",\n \"avalanche-fuji\",\n \"avalanche\",\n \"iotex\",\n \"sei\",\n \"sei-testnet\",\n \"polygon\",\n \"polygon-amoy\",\n \"peaq\",\n \"story\",\n \"educhain\",\n \"skale-base-sepolia\",\n];\n","import {\n Network,\n PaymentPayload,\n PaymentRequirements,\n SchemeNetworkClient,\n} from \"@t402/core/types\";\nimport { PaymentRequirementsV1 } from \"@t402/core/types/v1\";\nimport { getAddress } from \"viem\";\nimport { authorizationTypes } from \"../../../constants\";\nimport { ClientEvmSigner } from \"../../../signer\";\nimport { ExactEvmPayloadV1 } from \"../../../types\";\nimport { createNonce, getEvmChainId } from \"../../../utils\";\n\n/**\n * EVM client implementation for the Exact payment scheme (V1).\n */\nexport class ExactEvmSchemeV1 implements SchemeNetworkClient {\n readonly scheme = \"exact\";\n\n /**\n * Creates a new ExactEvmClientV1 instance.\n *\n * @param signer - The EVM signer for client operations\n */\n constructor(private readonly signer: ClientEvmSigner) {}\n\n /**\n * Creates a payment payload for the Exact scheme (V1).\n *\n * @param t402Version - The t402 protocol version\n * @param paymentRequirements - The payment requirements\n * @returns Promise resolving to a payment payload\n */\n async createPaymentPayload(\n t402Version: number,\n paymentRequirements: PaymentRequirements,\n ): Promise<\n Pick<PaymentPayload, \"t402Version\" | \"payload\"> & { scheme: string; network: Network }\n > {\n const selectedV1 = paymentRequirements as unknown as PaymentRequirementsV1;\n const nonce = createNonce();\n const now = Math.floor(Date.now() / 1000);\n\n const authorization: ExactEvmPayloadV1[\"authorization\"] = {\n from: this.signer.address,\n to: getAddress(selectedV1.payTo),\n value: selectedV1.maxAmountRequired,\n validAfter: (now - 600).toString(), // 10 minutes before\n validBefore: (now + selectedV1.maxTimeoutSeconds).toString(),\n nonce,\n };\n\n // Sign the authorization\n const signature = await this.signAuthorization(authorization, selectedV1);\n\n const payload: ExactEvmPayloadV1 = {\n authorization,\n signature,\n };\n\n return {\n t402Version,\n scheme: selectedV1.scheme,\n network: selectedV1.network,\n payload,\n };\n }\n\n /**\n * Sign the EIP-3009 authorization using EIP-712\n *\n * @param authorization - The authorization to sign\n * @param requirements - The payment requirements\n * @returns Promise resolving to the signature\n */\n private async signAuthorization(\n authorization: ExactEvmPayloadV1[\"authorization\"],\n requirements: PaymentRequirementsV1,\n ): Promise<`0x${string}`> {\n const chainId = getEvmChainId(requirements.network);\n\n if (!requirements.extra?.name || !requirements.extra?.version) {\n throw new Error(\n `EIP-712 domain parameters (name, version) are required in payment requirements for asset ${requirements.asset}`,\n );\n }\n\n const { name, version } = requirements.extra;\n\n const domain = {\n name,\n version,\n chainId,\n verifyingContract: getAddress(requirements.asset),\n };\n\n const message = {\n from: getAddress(authorization.from),\n to: getAddress(authorization.to),\n value: BigInt(authorization.value),\n validAfter: BigInt(authorization.validAfter),\n validBefore: BigInt(authorization.validBefore),\n nonce: authorization.nonce,\n };\n\n return await this.signer.signTypedData({\n domain,\n types: authorizationTypes,\n primaryType: \"TransferWithAuthorization\",\n message,\n });\n }\n}\n","// EIP-3009 TransferWithAuthorization types for EIP-712 signing\nexport const authorizationTypes = {\n TransferWithAuthorization: [\n { name: \"from\", type: \"address\" },\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"validAfter\", type: \"uint256\" },\n { name: \"validBefore\", type: \"uint256\" },\n { name: \"nonce\", type: \"bytes32\" },\n ],\n} as const;\n\n// Legacy transfer authorization types for EIP-712 signing\n// Used for tokens without EIP-3009 support (approve + transferFrom pattern)\nexport const legacyAuthorizationTypes = {\n LegacyTransferAuthorization: [\n { name: \"from\", type: \"address\" },\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"validAfter\", type: \"uint256\" },\n { name: \"validBefore\", type: \"uint256\" },\n { name: \"nonce\", type: \"bytes32\" },\n { name: \"spender\", type: \"address\" },\n ],\n} as const;\n\n// EIP3009 ABI for transferWithAuthorization function\nexport const eip3009ABI = [\n {\n inputs: [\n { name: \"from\", type: \"address\" },\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"validAfter\", type: \"uint256\" },\n { name: \"validBefore\", type: \"uint256\" },\n { name: \"nonce\", type: \"bytes32\" },\n { name: \"v\", type: \"uint8\" },\n { name: \"r\", type: \"bytes32\" },\n { name: \"s\", type: \"bytes32\" },\n ],\n name: \"transferWithAuthorization\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"from\", type: \"address\" },\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"validAfter\", type: \"uint256\" },\n { name: \"validBefore\", type: \"uint256\" },\n { name: \"nonce\", type: \"bytes32\" },\n { name: \"signature\", type: \"bytes\" },\n ],\n name: \"transferWithAuthorization\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [{ name: \"account\", type: \"address\" }],\n name: \"balanceOf\",\n outputs: [{ name: \"\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [],\n name: \"version\",\n outputs: [{ name: \"\", type: \"string\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const;\n\n// Standard ERC20 ABI for legacy token operations (approve + transferFrom pattern)\nexport const erc20LegacyABI = [\n {\n inputs: [{ name: \"account\", type: \"address\" }],\n name: \"balanceOf\",\n outputs: [{ name: \"\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"owner\", type: \"address\" },\n { name: \"spender\", type: \"address\" },\n ],\n name: \"allowance\",\n outputs: [{ name: \"\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"spender\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n name: \"approve\",\n outputs: [{ name: \"\", type: \"bool\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"from\", type: \"address\" },\n { name: \"to\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n name: \"transferFrom\",\n outputs: [{ name: \"\", type: \"bool\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n","import { toHex } from \"viem\";\nimport { Network } from \"@t402/core/types\";\n\n/**\n * Extract chain ID from network string (e.g., \"base-sepolia\" -> 84532)\n * Used by v1 implementations\n *\n * @param network - The network identifier\n * @returns The numeric chain ID\n */\nexport function getEvmChainId(network: Network): number {\n const networkMap: Record<string, number> = {\n base: 8453,\n \"base-sepolia\": 84532,\n ethereum: 1,\n sepolia: 11155111,\n polygon: 137,\n \"polygon-amoy\": 80002,\n };\n return networkMap[network] || 1;\n}\n\n/**\n * Create a random 32-byte nonce for authorization\n *\n * @returns A hex-encoded 32-byte nonce\n */\nexport function createNonce(): `0x${string}` {\n // Use dynamic import to avoid require() in ESM context\n const cryptoObj =\n typeof globalThis.crypto !== \"undefined\"\n ? globalThis.crypto\n : (globalThis as { crypto?: Crypto }).crypto;\n\n if (!cryptoObj) {\n throw new Error(\"Crypto API not available\");\n }\n\n return toHex(cryptoObj.getRandomValues(new Uint8Array(32)));\n}\n","import {\n PaymentPayload,\n PaymentPayloadV1,\n PaymentRequirements,\n SchemeNetworkFacilitator,\n SettleResponse,\n VerifyResponse,\n} from \"@t402/core/types\";\nimport { PaymentRequirementsV1 } from \"@t402/core/types/v1\";\nimport { getAddress, Hex, isAddressEqual, parseErc6492Signature, parseSignature } from \"viem\";\nimport { authorizationTypes, eip3009ABI } from \"../../../constants\";\nimport { FacilitatorEvmSigner } from \"../../../signer\";\nimport { ExactEvmPayloadV1 } from \"../../../types\";\nimport { getEvmChainId } from \"../../../utils\";\n\nexport interface ExactEvmSchemeV1Config {\n /**\n * If enabled, the facilitator will deploy ERC-4337 smart wallets\n * via EIP-6492 when encountering undeployed contract signatures.\n *\n * @default false\n */\n deployERC4337WithEIP6492?: boolean;\n}\n\n/**\n * EVM facilitator implementation for the Exact payment scheme (V1).\n */\nexport class ExactEvmSchemeV1 implements SchemeNetworkFacilitator {\n readonly scheme = \"exact\";\n readonly caipFamily = \"eip155:*\";\n private readonly config: Required<ExactEvmSchemeV1Config>;\n\n /**\n * Creates a new ExactEvmFacilitatorV1 instance.\n *\n * @param signer - The EVM signer for facilitator operations\n * @param config - Optional configuration for the facilitator\n */\n constructor(\n private readonly signer: FacilitatorEvmSigner,\n config?: ExactEvmSchemeV1Config,\n ) {\n this.config = {\n deployERC4337WithEIP6492: config?.deployERC4337WithEIP6492 ?? false,\n };\n }\n\n /**\n * Get mechanism-specific extra data for the supported kinds endpoint.\n * For EVM, no extra data is needed.\n *\n * @param _ - The network identifier (unused for EVM)\n * @returns undefined (EVM has no extra data)\n */\n getExtra(_: string): Record<string, unknown> | undefined {\n return undefined;\n }\n\n /**\n * Get signer addresses used by this facilitator.\n * Returns all addresses this facilitator can use for signing/settling transactions.\n *\n * @param _ - The network identifier (unused for EVM, addresses are network-agnostic)\n * @returns Array of facilitator wallet addresses\n */\n getSigners(_: string): string[] {\n return [...this.signer.getAddresses()];\n }\n\n /**\n * Verifies a payment payload (V1).\n *\n * @param payload - The payment payload to verify\n * @param requirements - The payment requirements\n * @returns Promise resolving to verification response\n */\n async verify(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<VerifyResponse> {\n const requirementsV1 = requirements as unknown as PaymentRequirementsV1;\n const payloadV1 = payload as unknown as PaymentPayloadV1;\n const exactEvmPayload = payload.payload as ExactEvmPayloadV1;\n\n // Verify scheme matches\n if (payloadV1.scheme !== \"exact\" || requirements.scheme !== \"exact\") {\n return {\n isValid: false,\n invalidReason: \"unsupported_scheme\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n // Get chain configuration\n const chainId = getEvmChainId(payloadV1.network);\n\n if (!requirements.extra?.name || !requirements.extra?.version) {\n return {\n isValid: false,\n invalidReason: \"missing_eip712_domain\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n const { name, version } = requirements.extra;\n const erc20Address = getAddress(requirements.asset);\n\n // Verify network matches\n if (payloadV1.network !== requirements.network) {\n return {\n isValid: false,\n invalidReason: \"network_mismatch\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n // Build typed data for signature verification\n const permitTypedData = {\n types: authorizationTypes,\n primaryType: \"TransferWithAuthorization\" as const,\n domain: {\n name,\n version,\n chainId,\n verifyingContract: erc20Address,\n },\n message: {\n from: exactEvmPayload.authorization.from,\n to: exactEvmPayload.authorization.to,\n value: BigInt(exactEvmPayload.authorization.value),\n validAfter: BigInt(exactEvmPayload.authorization.validAfter),\n validBefore: BigInt(exactEvmPayload.authorization.validBefore),\n nonce: exactEvmPayload.authorization.nonce,\n },\n };\n\n // Verify signature\n try {\n const recoveredAddress = await this.signer.verifyTypedData({\n address: exactEvmPayload.authorization.from,\n ...permitTypedData,\n signature: exactEvmPayload.signature!,\n });\n\n if (!recoveredAddress) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_signature\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n } catch {\n // Signature verification failed - could be an undeployed smart wallet\n // Check if smart wallet is deployed\n const signature = exactEvmPayload.signature!;\n const signatureLength = signature.startsWith(\"0x\") ? signature.length - 2 : signature.length;\n const isSmartWallet = signatureLength > 130; // 65 bytes = 130 hex chars for EOA\n\n if (isSmartWallet) {\n const payerAddress = exactEvmPayload.authorization.from;\n const bytecode = await this.signer.getCode({ address: payerAddress });\n\n if (!bytecode || bytecode === \"0x\") {\n // Wallet is not deployed. Check if it's EIP-6492 with deployment info.\n // EIP-6492 signatures contain factory address and calldata needed for deployment.\n // Non-EIP-6492 undeployed wallets cannot succeed (no way to deploy them).\n const erc6492Data = parseErc6492Signature(signature);\n const hasDeploymentInfo =\n erc6492Data.address &&\n erc6492Data.data &&\n !isAddressEqual(erc6492Data.address, \"0x0000000000000000000000000000000000000000\");\n\n if (!hasDeploymentInfo) {\n // Non-EIP-6492 undeployed smart wallet - will always fail at settlement\n // since EIP-3009 requires on-chain EIP-1271 validation\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_undeployed_smart_wallet\",\n payer: payerAddress,\n };\n }\n // EIP-6492 signature with deployment info - allow through\n // Facilitators with sponsored deployment support can handle this in settle()\n } else {\n // Wallet is deployed but signature still failed - invalid signature\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_signature\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n } else {\n // EOA signature failed\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_signature\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n }\n\n // Verify payment recipient matches\n if (getAddress(exactEvmPayload.authorization.to) !== getAddress(requirements.payTo)) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_recipient_mismatch\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n // Verify validBefore is in the future (with 6 second buffer for block time)\n const now = Math.floor(Date.now() / 1000);\n if (BigInt(exactEvmPayload.authorization.validBefore) < BigInt(now + 6)) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_authorization_valid_before\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n // Verify validAfter is not in the future\n if (BigInt(exactEvmPayload.authorization.validAfter) > BigInt(now)) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_authorization_valid_after\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n // Check balance\n try {\n const balance = (await this.signer.readContract({\n address: erc20Address,\n abi: eip3009ABI,\n functionName: \"balanceOf\",\n args: [exactEvmPayload.authorization.from],\n })) as bigint;\n\n if (BigInt(balance) < BigInt(requirementsV1.maxAmountRequired)) {\n return {\n isValid: false,\n invalidReason: \"insufficient_funds\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n } catch {\n // If we can't check balance, continue with other validations\n }\n\n // Verify amount is sufficient\n if (BigInt(exactEvmPayload.authorization.value) < BigInt(requirementsV1.maxAmountRequired)) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_authorization_value\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n return {\n isValid: true,\n invalidReason: undefined,\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n /**\n * Settles a payment by executing the transfer (V1).\n *\n * @param payload - The payment payload to settle\n * @param requirements - The payment requirements\n * @returns Promise resolving to settlement response\n */\n async settle(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<SettleResponse> {\n const payloadV1 = payload as unknown as PaymentPayloadV1;\n const exactEvmPayload = payload.payload as ExactEvmPayloadV1;\n\n // Re-verify before settling\n const valid = await this.verify(payload, requirements);\n if (!valid.isValid) {\n return {\n success: false,\n network: payloadV1.network,\n transaction: \"\",\n errorReason: valid.invalidReason ?? \"invalid_scheme\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n try {\n // Parse ERC-6492 signature if applicable\n const parseResult = parseErc6492Signature(exactEvmPayload.signature!);\n const { signature, address: factoryAddress, data: factoryCalldata } = parseResult;\n\n // Deploy ERC-4337 smart wallet via EIP-6492 if configured and needed\n if (\n this.config.deployERC4337WithEIP6492 &&\n factoryAddress &&\n factoryCalldata &&\n !isAddressEqual(factoryAddress, \"0x0000000000000000000000000000000000000000\")\n ) {\n // Check if smart wallet is already deployed\n const payerAddress = exactEvmPayload.authorization.from;\n const bytecode = await this.signer.getCode({ address: payerAddress });\n\n if (!bytecode || bytecode === \"0x\") {\n // Wallet not deployed - attempt deployment\n try {\n console.log(`Deploying ERC-4337 smart wallet for ${payerAddress} via EIP-6492`);\n\n // Send the factory calldata directly as a transaction\n // The factoryCalldata already contains the complete encoded function call\n const deployTx = await this.signer.sendTransaction({\n to: factoryAddress as Hex,\n data: factoryCalldata as Hex,\n });\n\n // Wait for deployment transaction\n await this.signer.waitForTransactionReceipt({ hash: deployTx });\n console.log(`Successfully deployed smart wallet for ${payerAddress}`);\n } catch (deployError) {\n console.error(\"Smart wallet deployment failed:\", deployError);\n // Deployment failed - cannot proceed\n throw deployError;\n }\n } else {\n console.log(`Smart wallet for ${payerAddress} already deployed, skipping deployment`);\n }\n }\n\n // Determine if this is an ECDSA signature (EOA) or smart wallet signature\n // ECDSA signatures are exactly 65 bytes (130 hex chars without 0x)\n const signatureLength = signature.startsWith(\"0x\") ? signature.length - 2 : signature.length;\n const isECDSA = signatureLength === 130;\n\n let tx: Hex;\n if (isECDSA) {\n // For EOA wallets, parse signature into v, r, s and use that overload\n const parsedSig = parseSignature(signature);\n\n tx = await this.signer.writeContract({\n address: getAddress(requirements.asset),\n abi: eip3009ABI,\n functionName: \"transferWithAuthorization\",\n args: [\n getAddress(exactEvmPayload.authorization.from),\n getAddress(exactEvmPayload.authorization.to),\n BigInt(exactEvmPayload.authorization.value),\n BigInt(exactEvmPayload.authorization.validAfter),\n BigInt(exactEvmPayload.authorization.validBefore),\n exactEvmPayload.authorization.nonce,\n (parsedSig.v as number | undefined) || parsedSig.yParity,\n parsedSig.r,\n parsedSig.s,\n ],\n });\n } else {\n // For smart wallets, use the bytes signature overload\n // The signature contains WebAuthn/P256 or other ERC-1271 compatible signature data\n tx = await this.signer.writeContract({\n address: getAddress(requirements.asset),\n abi: eip3009ABI,\n functionName: \"transferWithAuthorization\",\n args: [\n getAddress(exactEvmPayload.authorization.from),\n getAddress(exactEvmPayload.authorization.to),\n BigInt(exactEvmPayload.authorization.value),\n BigInt(exactEvmPayload.authorization.validAfter),\n BigInt(exactEvmPayload.authorization.validBefore),\n exactEvmPayload.authorization.nonce,\n signature,\n ],\n });\n }\n\n // Wait for transaction confirmation\n const receipt = await this.signer.waitForTransactionReceipt({ hash: tx });\n\n if (receipt.status !== \"success\") {\n return {\n success: false,\n errorReason: \"invalid_transaction_state\",\n transaction: tx,\n network: payloadV1.network,\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n return {\n success: true,\n transaction: tx,\n network: payloadV1.network,\n payer: exactEvmPayload.authorization.from,\n };\n } catch (error) {\n console.error(\"Failed to settle transaction:\", error);\n return {\n success: false,\n errorReason: \"transaction_failed\",\n transaction: \"\",\n network: payloadV1.network,\n payer: exactEvmPayload.authorization.from,\n };\n }\n }\n}\n"],"mappings":"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","names":["import_viem","import_viem"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/v1/index.ts","../../../src/exact/v1/client/scheme.ts","../../../src/constants.ts","../../../src/utils.ts","../../../src/exact/v1/facilitator/scheme.ts"],"sourcesContent":["export { ExactEvmSchemeV1 } from \"../exact/v1\";\n\nexport const NETWORKS: string[] = [\n \"abstract\",\n \"abstract-testnet\",\n \"base-sepolia\",\n \"base\",\n \"avalanche-fuji\",\n \"avalanche\",\n \"iotex\",\n \"sei\",\n \"sei-testnet\",\n \"polygon\",\n \"polygon-amoy\",\n \"peaq\",\n \"story\",\n \"educhain\",\n \"skale-base-sepolia\",\n];\n","import {\n Network,\n PaymentPayload,\n PaymentRequirements,\n SchemeNetworkClient,\n} from \"@t402/core/types\";\nimport { PaymentRequirementsV1 } from \"@t402/core/types/v1\";\nimport { getAddress } from \"viem\";\nimport { authorizationTypes } from \"../../../constants\";\nimport { ClientEvmSigner } from \"../../../signer\";\nimport { ExactEvmPayloadV1 } from \"../../../types\";\nimport { createNonce, getEvmChainId } from \"../../../utils\";\n\n/**\n * EVM client implementation for the Exact payment scheme (V1).\n */\nexport class ExactEvmSchemeV1 implements SchemeNetworkClient {\n readonly scheme = \"exact\";\n\n /**\n * Creates a new ExactEvmClientV1 instance.\n *\n * @param signer - The EVM signer for client operations\n */\n constructor(private readonly signer: ClientEvmSigner) {}\n\n /**\n * Creates a payment payload for the Exact scheme (V1).\n *\n * @param t402Version - The t402 protocol version\n * @param paymentRequirements - The payment requirements\n * @returns Promise resolving to a payment payload\n */\n async createPaymentPayload(\n t402Version: number,\n paymentRequirements: PaymentRequirements,\n ): Promise<\n Pick<PaymentPayload, \"t402Version\" | \"payload\"> & { scheme: string; network: Network }\n > {\n const selectedV1 = paymentRequirements as unknown as PaymentRequirementsV1;\n const nonce = createNonce();\n const now = Math.floor(Date.now() / 1000);\n\n const authorization: ExactEvmPayloadV1[\"authorization\"] = {\n from: this.signer.address,\n to: getAddress(selectedV1.payTo),\n value: selectedV1.maxAmountRequired,\n validAfter: (now - 600).toString(), // 10 minutes before\n validBefore: (now + selectedV1.maxTimeoutSeconds).toString(),\n nonce,\n };\n\n // Sign the authorization\n const signature = await this.signAuthorization(authorization, selectedV1);\n\n const payload: ExactEvmPayloadV1 = {\n authorization,\n signature,\n };\n\n return {\n t402Version,\n scheme: selectedV1.scheme,\n network: selectedV1.network,\n payload,\n };\n }\n\n /**\n * Sign the EIP-3009 authorization using EIP-712\n *\n * @param authorization - The authorization to sign\n * @param requirements - The payment requirements\n * @returns Promise resolving to the signature\n */\n private async signAuthorization(\n authorization: ExactEvmPayloadV1[\"authorization\"],\n requirements: PaymentRequirementsV1,\n ): Promise<`0x${string}`> {\n const chainId = getEvmChainId(requirements.network);\n\n if (!requirements.extra?.name || !requirements.extra?.version) {\n throw new Error(\n `EIP-712 domain parameters (name, version) are required in payment requirements for asset ${requirements.asset}`,\n );\n }\n\n const { name, version } = requirements.extra;\n\n const domain = {\n name,\n version,\n chainId,\n verifyingContract: getAddress(requirements.asset),\n };\n\n const message = {\n from: getAddress(authorization.from),\n to: getAddress(authorization.to),\n value: BigInt(authorization.value),\n validAfter: BigInt(authorization.validAfter),\n validBefore: BigInt(authorization.validBefore),\n nonce: authorization.nonce,\n };\n\n return await this.signer.signTypedData({\n domain,\n types: authorizationTypes,\n primaryType: \"TransferWithAuthorization\",\n message,\n });\n }\n}\n","// EIP-3009 TransferWithAuthorization types for EIP-712 signing\nexport const authorizationTypes = {\n TransferWithAuthorization: [\n { name: \"from\", type: \"address\" },\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"validAfter\", type: \"uint256\" },\n { name: \"validBefore\", type: \"uint256\" },\n { name: \"nonce\", type: \"bytes32\" },\n ],\n} as const;\n\n// Legacy transfer authorization types for EIP-712 signing\n// Used for tokens without EIP-3009 support (approve + transferFrom pattern)\nexport const legacyAuthorizationTypes = {\n LegacyTransferAuthorization: [\n { name: \"from\", type: \"address\" },\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"validAfter\", type: \"uint256\" },\n { name: \"validBefore\", type: \"uint256\" },\n { name: \"nonce\", type: \"bytes32\" },\n { name: \"spender\", type: \"address\" },\n ],\n} as const;\n\n// EIP3009 ABI for transferWithAuthorization function\nexport const eip3009ABI = [\n {\n inputs: [\n { name: \"from\", type: \"address\" },\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"validAfter\", type: \"uint256\" },\n { name: \"validBefore\", type: \"uint256\" },\n { name: \"nonce\", type: \"bytes32\" },\n { name: \"v\", type: \"uint8\" },\n { name: \"r\", type: \"bytes32\" },\n { name: \"s\", type: \"bytes32\" },\n ],\n name: \"transferWithAuthorization\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"from\", type: \"address\" },\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"validAfter\", type: \"uint256\" },\n { name: \"validBefore\", type: \"uint256\" },\n { name: \"nonce\", type: \"bytes32\" },\n { name: \"signature\", type: \"bytes\" },\n ],\n name: \"transferWithAuthorization\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [{ name: \"account\", type: \"address\" }],\n name: \"balanceOf\",\n outputs: [{ name: \"\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [],\n name: \"version\",\n outputs: [{ name: \"\", type: \"string\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const;\n\n// Standard ERC20 ABI for legacy token operations (approve + transferFrom pattern)\nexport const erc20LegacyABI = [\n {\n inputs: [{ name: \"account\", type: \"address\" }],\n name: \"balanceOf\",\n outputs: [{ name: \"\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"owner\", type: \"address\" },\n { name: \"spender\", type: \"address\" },\n ],\n name: \"allowance\",\n outputs: [{ name: \"\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"spender\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n name: \"approve\",\n outputs: [{ name: \"\", type: \"bool\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"from\", type: \"address\" },\n { name: \"to\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n name: \"transferFrom\",\n outputs: [{ name: \"\", type: \"bool\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n","import { toHex } from \"viem\";\nimport { Network } from \"@t402/core/types\";\n\n/**\n * Extract chain ID from network string (e.g., \"base-sepolia\" -> 84532)\n * Used by v1 implementations\n *\n * @param network - The network identifier\n * @returns The numeric chain ID\n */\nexport function getEvmChainId(network: Network): number {\n const networkMap: Record<string, number> = {\n base: 8453,\n \"base-sepolia\": 84532,\n ethereum: 1,\n sepolia: 11155111,\n polygon: 137,\n \"polygon-amoy\": 80002,\n };\n return networkMap[network] || 1;\n}\n\n/**\n * Create a random 32-byte nonce for authorization\n *\n * @returns A hex-encoded 32-byte nonce\n */\nexport function createNonce(): `0x${string}` {\n // Use dynamic import to avoid require() in ESM context\n const cryptoObj =\n typeof globalThis.crypto !== \"undefined\"\n ? globalThis.crypto\n : (globalThis as { crypto?: Crypto }).crypto;\n\n if (!cryptoObj) {\n throw new Error(\"Crypto API not available\");\n }\n\n return toHex(cryptoObj.getRandomValues(new Uint8Array(32)));\n}\n","import {\n PaymentPayload,\n PaymentPayloadV1,\n PaymentRequirements,\n SchemeNetworkFacilitator,\n SettleResponse,\n VerifyResponse,\n} from \"@t402/core/types\";\nimport { PaymentRequirementsV1 } from \"@t402/core/types/v1\";\nimport { getAddress, Hex, isAddressEqual, parseErc6492Signature, parseSignature } from \"viem\";\nimport { authorizationTypes, eip3009ABI } from \"../../../constants\";\nimport { FacilitatorEvmSigner } from \"../../../signer\";\nimport { ExactEvmPayloadV1 } from \"../../../types\";\nimport { getEvmChainId } from \"../../../utils\";\n\nexport interface ExactEvmSchemeV1Config {\n /**\n * If enabled, the facilitator will deploy ERC-4337 smart wallets\n * via EIP-6492 when encountering undeployed contract signatures.\n *\n * @default false\n */\n deployERC4337WithEIP6492?: boolean;\n}\n\n/**\n * EVM facilitator implementation for the Exact payment scheme (V1).\n */\nexport class ExactEvmSchemeV1 implements SchemeNetworkFacilitator {\n readonly scheme = \"exact\";\n readonly caipFamily = \"eip155:*\";\n private readonly config: Required<ExactEvmSchemeV1Config>;\n\n /**\n * Creates a new ExactEvmFacilitatorV1 instance.\n *\n * @param signer - The EVM signer for facilitator operations\n * @param config - Optional configuration for the facilitator\n */\n constructor(\n private readonly signer: FacilitatorEvmSigner,\n config?: ExactEvmSchemeV1Config,\n ) {\n this.config = {\n deployERC4337WithEIP6492: config?.deployERC4337WithEIP6492 ?? false,\n };\n }\n\n /**\n * Get mechanism-specific extra data for the supported kinds endpoint.\n * For EVM, no extra data is needed.\n *\n * @param _ - The network identifier (unused for EVM)\n * @returns undefined (EVM has no extra data)\n */\n getExtra(_: string): Record<string, unknown> | undefined {\n return undefined;\n }\n\n /**\n * Get signer addresses used by this facilitator.\n * Returns all addresses this facilitator can use for signing/settling transactions.\n *\n * @param _ - The network identifier (unused for EVM, addresses are network-agnostic)\n * @returns Array of facilitator wallet addresses\n */\n getSigners(_: string): string[] {\n return [...this.signer.getAddresses()];\n }\n\n /**\n * Verifies a payment payload (V1).\n *\n * @param payload - The payment payload to verify\n * @param requirements - The payment requirements\n * @returns Promise resolving to verification response\n */\n async verify(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<VerifyResponse> {\n const requirementsV1 = requirements as unknown as PaymentRequirementsV1;\n const payloadV1 = payload as unknown as PaymentPayloadV1;\n const exactEvmPayload = payload.payload as ExactEvmPayloadV1 | undefined;\n\n // Validate payload structure\n if (!exactEvmPayload?.authorization?.from) {\n return {\n isValid: false,\n invalidReason: \"invalid_payload_structure\",\n payer: undefined,\n };\n }\n\n // Verify scheme matches\n if (payloadV1.scheme !== \"exact\" || requirements.scheme !== \"exact\") {\n return {\n isValid: false,\n invalidReason: \"unsupported_scheme\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n // Get chain configuration\n const chainId = getEvmChainId(payloadV1.network);\n\n if (!requirements.extra?.name || !requirements.extra?.version) {\n return {\n isValid: false,\n invalidReason: \"missing_eip712_domain\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n const { name, version } = requirements.extra;\n const erc20Address = getAddress(requirements.asset);\n\n // Verify network matches\n if (payloadV1.network !== requirements.network) {\n return {\n isValid: false,\n invalidReason: \"network_mismatch\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n // Build typed data for signature verification\n const permitTypedData = {\n types: authorizationTypes,\n primaryType: \"TransferWithAuthorization\" as const,\n domain: {\n name,\n version,\n chainId,\n verifyingContract: erc20Address,\n },\n message: {\n from: exactEvmPayload.authorization.from,\n to: exactEvmPayload.authorization.to,\n value: BigInt(exactEvmPayload.authorization.value),\n validAfter: BigInt(exactEvmPayload.authorization.validAfter),\n validBefore: BigInt(exactEvmPayload.authorization.validBefore),\n nonce: exactEvmPayload.authorization.nonce,\n },\n };\n\n // Verify signature\n try {\n const recoveredAddress = await this.signer.verifyTypedData({\n address: exactEvmPayload.authorization.from,\n ...permitTypedData,\n signature: exactEvmPayload.signature!,\n });\n\n if (!recoveredAddress) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_signature\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n } catch {\n // Signature verification failed - could be an undeployed smart wallet\n // Check if smart wallet is deployed\n const signature = exactEvmPayload.signature!;\n const signatureLength = signature.startsWith(\"0x\") ? signature.length - 2 : signature.length;\n const isSmartWallet = signatureLength > 130; // 65 bytes = 130 hex chars for EOA\n\n if (isSmartWallet) {\n const payerAddress = exactEvmPayload.authorization.from;\n const bytecode = await this.signer.getCode({ address: payerAddress });\n\n if (!bytecode || bytecode === \"0x\") {\n // Wallet is not deployed. Check if it's EIP-6492 with deployment info.\n // EIP-6492 signatures contain factory address and calldata needed for deployment.\n // Non-EIP-6492 undeployed wallets cannot succeed (no way to deploy them).\n const erc6492Data = parseErc6492Signature(signature);\n const hasDeploymentInfo =\n erc6492Data.address &&\n erc6492Data.data &&\n !isAddressEqual(erc6492Data.address, \"0x0000000000000000000000000000000000000000\");\n\n if (!hasDeploymentInfo) {\n // Non-EIP-6492 undeployed smart wallet - will always fail at settlement\n // since EIP-3009 requires on-chain EIP-1271 validation\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_undeployed_smart_wallet\",\n payer: payerAddress,\n };\n }\n // EIP-6492 signature with deployment info - allow through\n // Facilitators with sponsored deployment support can handle this in settle()\n } else {\n // Wallet is deployed but signature still failed - invalid signature\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_signature\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n } else {\n // EOA signature failed\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_signature\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n }\n\n // Verify payment recipient matches\n if (getAddress(exactEvmPayload.authorization.to) !== getAddress(requirements.payTo)) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_recipient_mismatch\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n // Verify validBefore is in the future (with 6 second buffer for block time)\n const now = Math.floor(Date.now() / 1000);\n if (BigInt(exactEvmPayload.authorization.validBefore) < BigInt(now + 6)) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_authorization_valid_before\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n // Verify validAfter is not in the future\n if (BigInt(exactEvmPayload.authorization.validAfter) > BigInt(now)) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_authorization_valid_after\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n // Check balance\n try {\n const balance = (await this.signer.readContract({\n address: erc20Address,\n abi: eip3009ABI,\n functionName: \"balanceOf\",\n args: [exactEvmPayload.authorization.from],\n })) as bigint;\n\n if (BigInt(balance) < BigInt(requirementsV1.maxAmountRequired)) {\n return {\n isValid: false,\n invalidReason: \"insufficient_funds\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n } catch {\n // If we can't check balance, continue with other validations\n }\n\n // Verify amount is sufficient\n if (BigInt(exactEvmPayload.authorization.value) < BigInt(requirementsV1.maxAmountRequired)) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_authorization_value\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n return {\n isValid: true,\n invalidReason: undefined,\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n /**\n * Settles a payment by executing the transfer (V1).\n *\n * @param payload - The payment payload to settle\n * @param requirements - The payment requirements\n * @returns Promise resolving to settlement response\n */\n async settle(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<SettleResponse> {\n const payloadV1 = payload as unknown as PaymentPayloadV1;\n const exactEvmPayload = payload.payload as ExactEvmPayloadV1 | undefined;\n\n // Validate payload structure\n if (!exactEvmPayload?.authorization?.from) {\n return {\n success: false,\n network: payloadV1.network,\n transaction: \"\",\n errorReason: \"invalid_payload_structure\",\n payer: undefined,\n };\n }\n\n // Re-verify before settling\n const valid = await this.verify(payload, requirements);\n if (!valid.isValid) {\n return {\n success: false,\n network: payloadV1.network,\n transaction: \"\",\n errorReason: valid.invalidReason ?? \"invalid_scheme\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n try {\n // Parse ERC-6492 signature if applicable\n const parseResult = parseErc6492Signature(exactEvmPayload.signature!);\n const { signature, address: factoryAddress, data: factoryCalldata } = parseResult;\n\n // Deploy ERC-4337 smart wallet via EIP-6492 if configured and needed\n if (\n this.config.deployERC4337WithEIP6492 &&\n factoryAddress &&\n factoryCalldata &&\n !isAddressEqual(factoryAddress, \"0x0000000000000000000000000000000000000000\")\n ) {\n // Check if smart wallet is already deployed\n const payerAddress = exactEvmPayload.authorization.from;\n const bytecode = await this.signer.getCode({ address: payerAddress });\n\n if (!bytecode || bytecode === \"0x\") {\n // Wallet not deployed - attempt deployment\n try {\n console.log(`Deploying ERC-4337 smart wallet for ${payerAddress} via EIP-6492`);\n\n // Send the factory calldata directly as a transaction\n // The factoryCalldata already contains the complete encoded function call\n const deployTx = await this.signer.sendTransaction({\n to: factoryAddress as Hex,\n data: factoryCalldata as Hex,\n });\n\n // Wait for deployment transaction\n await this.signer.waitForTransactionReceipt({ hash: deployTx });\n console.log(`Successfully deployed smart wallet for ${payerAddress}`);\n } catch (deployError) {\n console.error(\"Smart wallet deployment failed:\", deployError);\n // Deployment failed - cannot proceed\n throw deployError;\n }\n } else {\n console.log(`Smart wallet for ${payerAddress} already deployed, skipping deployment`);\n }\n }\n\n // Determine if this is an ECDSA signature (EOA) or smart wallet signature\n // ECDSA signatures are exactly 65 bytes (130 hex chars without 0x)\n const signatureLength = signature.startsWith(\"0x\") ? signature.length - 2 : signature.length;\n const isECDSA = signatureLength === 130;\n\n let tx: Hex;\n if (isECDSA) {\n // For EOA wallets, parse signature into v, r, s and use that overload\n const parsedSig = parseSignature(signature);\n\n tx = await this.signer.writeContract({\n address: getAddress(requirements.asset),\n abi: eip3009ABI,\n functionName: \"transferWithAuthorization\",\n args: [\n getAddress(exactEvmPayload.authorization.from),\n getAddress(exactEvmPayload.authorization.to),\n BigInt(exactEvmPayload.authorization.value),\n BigInt(exactEvmPayload.authorization.validAfter),\n BigInt(exactEvmPayload.authorization.validBefore),\n exactEvmPayload.authorization.nonce,\n (parsedSig.v as number | undefined) || parsedSig.yParity,\n parsedSig.r,\n parsedSig.s,\n ],\n });\n } else {\n // For smart wallets, use the bytes signature overload\n // The signature contains WebAuthn/P256 or other ERC-1271 compatible signature data\n tx = await this.signer.writeContract({\n address: getAddress(requirements.asset),\n abi: eip3009ABI,\n functionName: \"transferWithAuthorization\",\n args: [\n getAddress(exactEvmPayload.authorization.from),\n getAddress(exactEvmPayload.authorization.to),\n BigInt(exactEvmPayload.authorization.value),\n BigInt(exactEvmPayload.authorization.validAfter),\n BigInt(exactEvmPayload.authorization.validBefore),\n exactEvmPayload.authorization.nonce,\n signature,\n ],\n });\n }\n\n // Wait for transaction confirmation\n const receipt = await this.signer.waitForTransactionReceipt({ hash: tx });\n\n if (receipt.status !== \"success\") {\n return {\n success: false,\n errorReason: \"invalid_transaction_state\",\n transaction: tx,\n network: payloadV1.network,\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n return {\n success: true,\n transaction: tx,\n network: payloadV1.network,\n payer: exactEvmPayload.authorization.from,\n };\n } catch (error) {\n console.error(\"Failed to settle transaction:\", error);\n return {\n success: false,\n errorReason: \"transaction_failed\",\n transaction: \"\",\n network: payloadV1.network,\n payer: exactEvmPayload.authorization.from,\n };\n }\n }\n}\n"],"mappings":"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","names":["import_viem","import_viem"]}
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
authorizationTypes,
|
|
3
|
-
eip3009ABI
|
|
3
|
+
eip3009ABI
|
|
4
|
+
} from "./chunk-Y4U7Q543.mjs";
|
|
5
|
+
import {
|
|
4
6
|
getEvmChainId
|
|
5
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-SYVPLXYV.mjs";
|
|
8
|
+
import {
|
|
9
|
+
__publicField
|
|
10
|
+
} from "./chunk-NSSMTXJJ.mjs";
|
|
6
11
|
|
|
7
12
|
// src/exact/v1/facilitator/scheme.ts
|
|
8
13
|
import { getAddress, isAddressEqual, parseErc6492Signature, parseSignature } from "viem";
|
|
@@ -15,8 +20,9 @@ var ExactEvmSchemeV1 = class {
|
|
|
15
20
|
*/
|
|
16
21
|
constructor(signer, config) {
|
|
17
22
|
this.signer = signer;
|
|
18
|
-
this
|
|
19
|
-
this
|
|
23
|
+
__publicField(this, "scheme", "exact");
|
|
24
|
+
__publicField(this, "caipFamily", "eip155:*");
|
|
25
|
+
__publicField(this, "config");
|
|
20
26
|
this.config = {
|
|
21
27
|
deployERC4337WithEIP6492: config?.deployERC4337WithEIP6492 ?? false
|
|
22
28
|
};
|
|
@@ -52,6 +58,13 @@ var ExactEvmSchemeV1 = class {
|
|
|
52
58
|
const requirementsV1 = requirements;
|
|
53
59
|
const payloadV1 = payload;
|
|
54
60
|
const exactEvmPayload = payload.payload;
|
|
61
|
+
if (!exactEvmPayload?.authorization?.from) {
|
|
62
|
+
return {
|
|
63
|
+
isValid: false,
|
|
64
|
+
invalidReason: "invalid_payload_structure",
|
|
65
|
+
payer: void 0
|
|
66
|
+
};
|
|
67
|
+
}
|
|
55
68
|
if (payloadV1.scheme !== "exact" || requirements.scheme !== "exact") {
|
|
56
69
|
return {
|
|
57
70
|
isValid: false,
|
|
@@ -200,6 +213,15 @@ var ExactEvmSchemeV1 = class {
|
|
|
200
213
|
async settle(payload, requirements) {
|
|
201
214
|
const payloadV1 = payload;
|
|
202
215
|
const exactEvmPayload = payload.payload;
|
|
216
|
+
if (!exactEvmPayload?.authorization?.from) {
|
|
217
|
+
return {
|
|
218
|
+
success: false,
|
|
219
|
+
network: payloadV1.network,
|
|
220
|
+
transaction: "",
|
|
221
|
+
errorReason: "invalid_payload_structure",
|
|
222
|
+
payer: void 0
|
|
223
|
+
};
|
|
224
|
+
}
|
|
203
225
|
const valid = await this.verify(payload, requirements);
|
|
204
226
|
if (!valid.isValid) {
|
|
205
227
|
return {
|
|
@@ -302,4 +324,4 @@ var ExactEvmSchemeV1 = class {
|
|
|
302
324
|
export {
|
|
303
325
|
ExactEvmSchemeV1
|
|
304
326
|
};
|
|
305
|
-
//# sourceMappingURL=chunk-
|
|
327
|
+
//# sourceMappingURL=chunk-4FBTQTNM.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/exact/v1/facilitator/scheme.ts"],"sourcesContent":["import {\n PaymentPayload,\n PaymentPayloadV1,\n PaymentRequirements,\n SchemeNetworkFacilitator,\n SettleResponse,\n VerifyResponse,\n} from \"@t402/core/types\";\nimport { PaymentRequirementsV1 } from \"@t402/core/types/v1\";\nimport { getAddress, Hex, isAddressEqual, parseErc6492Signature, parseSignature } from \"viem\";\nimport { authorizationTypes, eip3009ABI } from \"../../../constants\";\nimport { FacilitatorEvmSigner } from \"../../../signer\";\nimport { ExactEvmPayloadV1 } from \"../../../types\";\nimport { getEvmChainId } from \"../../../utils\";\n\nexport interface ExactEvmSchemeV1Config {\n /**\n * If enabled, the facilitator will deploy ERC-4337 smart wallets\n * via EIP-6492 when encountering undeployed contract signatures.\n *\n * @default false\n */\n deployERC4337WithEIP6492?: boolean;\n}\n\n/**\n * EVM facilitator implementation for the Exact payment scheme (V1).\n */\nexport class ExactEvmSchemeV1 implements SchemeNetworkFacilitator {\n readonly scheme = \"exact\";\n readonly caipFamily = \"eip155:*\";\n private readonly config: Required<ExactEvmSchemeV1Config>;\n\n /**\n * Creates a new ExactEvmFacilitatorV1 instance.\n *\n * @param signer - The EVM signer for facilitator operations\n * @param config - Optional configuration for the facilitator\n */\n constructor(\n private readonly signer: FacilitatorEvmSigner,\n config?: ExactEvmSchemeV1Config,\n ) {\n this.config = {\n deployERC4337WithEIP6492: config?.deployERC4337WithEIP6492 ?? false,\n };\n }\n\n /**\n * Get mechanism-specific extra data for the supported kinds endpoint.\n * For EVM, no extra data is needed.\n *\n * @param _ - The network identifier (unused for EVM)\n * @returns undefined (EVM has no extra data)\n */\n getExtra(_: string): Record<string, unknown> | undefined {\n return undefined;\n }\n\n /**\n * Get signer addresses used by this facilitator.\n * Returns all addresses this facilitator can use for signing/settling transactions.\n *\n * @param _ - The network identifier (unused for EVM, addresses are network-agnostic)\n * @returns Array of facilitator wallet addresses\n */\n getSigners(_: string): string[] {\n return [...this.signer.getAddresses()];\n }\n\n /**\n * Verifies a payment payload (V1).\n *\n * @param payload - The payment payload to verify\n * @param requirements - The payment requirements\n * @returns Promise resolving to verification response\n */\n async verify(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<VerifyResponse> {\n const requirementsV1 = requirements as unknown as PaymentRequirementsV1;\n const payloadV1 = payload as unknown as PaymentPayloadV1;\n const exactEvmPayload = payload.payload as ExactEvmPayloadV1 | undefined;\n\n // Validate payload structure\n if (!exactEvmPayload?.authorization?.from) {\n return {\n isValid: false,\n invalidReason: \"invalid_payload_structure\",\n payer: undefined,\n };\n }\n\n // Verify scheme matches\n if (payloadV1.scheme !== \"exact\" || requirements.scheme !== \"exact\") {\n return {\n isValid: false,\n invalidReason: \"unsupported_scheme\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n // Get chain configuration\n const chainId = getEvmChainId(payloadV1.network);\n\n if (!requirements.extra?.name || !requirements.extra?.version) {\n return {\n isValid: false,\n invalidReason: \"missing_eip712_domain\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n const { name, version } = requirements.extra;\n const erc20Address = getAddress(requirements.asset);\n\n // Verify network matches\n if (payloadV1.network !== requirements.network) {\n return {\n isValid: false,\n invalidReason: \"network_mismatch\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n // Build typed data for signature verification\n const permitTypedData = {\n types: authorizationTypes,\n primaryType: \"TransferWithAuthorization\" as const,\n domain: {\n name,\n version,\n chainId,\n verifyingContract: erc20Address,\n },\n message: {\n from: exactEvmPayload.authorization.from,\n to: exactEvmPayload.authorization.to,\n value: BigInt(exactEvmPayload.authorization.value),\n validAfter: BigInt(exactEvmPayload.authorization.validAfter),\n validBefore: BigInt(exactEvmPayload.authorization.validBefore),\n nonce: exactEvmPayload.authorization.nonce,\n },\n };\n\n // Verify signature\n try {\n const recoveredAddress = await this.signer.verifyTypedData({\n address: exactEvmPayload.authorization.from,\n ...permitTypedData,\n signature: exactEvmPayload.signature!,\n });\n\n if (!recoveredAddress) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_signature\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n } catch {\n // Signature verification failed - could be an undeployed smart wallet\n // Check if smart wallet is deployed\n const signature = exactEvmPayload.signature!;\n const signatureLength = signature.startsWith(\"0x\") ? signature.length - 2 : signature.length;\n const isSmartWallet = signatureLength > 130; // 65 bytes = 130 hex chars for EOA\n\n if (isSmartWallet) {\n const payerAddress = exactEvmPayload.authorization.from;\n const bytecode = await this.signer.getCode({ address: payerAddress });\n\n if (!bytecode || bytecode === \"0x\") {\n // Wallet is not deployed. Check if it's EIP-6492 with deployment info.\n // EIP-6492 signatures contain factory address and calldata needed for deployment.\n // Non-EIP-6492 undeployed wallets cannot succeed (no way to deploy them).\n const erc6492Data = parseErc6492Signature(signature);\n const hasDeploymentInfo =\n erc6492Data.address &&\n erc6492Data.data &&\n !isAddressEqual(erc6492Data.address, \"0x0000000000000000000000000000000000000000\");\n\n if (!hasDeploymentInfo) {\n // Non-EIP-6492 undeployed smart wallet - will always fail at settlement\n // since EIP-3009 requires on-chain EIP-1271 validation\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_undeployed_smart_wallet\",\n payer: payerAddress,\n };\n }\n // EIP-6492 signature with deployment info - allow through\n // Facilitators with sponsored deployment support can handle this in settle()\n } else {\n // Wallet is deployed but signature still failed - invalid signature\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_signature\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n } else {\n // EOA signature failed\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_signature\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n }\n\n // Verify payment recipient matches\n if (getAddress(exactEvmPayload.authorization.to) !== getAddress(requirements.payTo)) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_recipient_mismatch\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n // Verify validBefore is in the future (with 6 second buffer for block time)\n const now = Math.floor(Date.now() / 1000);\n if (BigInt(exactEvmPayload.authorization.validBefore) < BigInt(now + 6)) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_authorization_valid_before\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n // Verify validAfter is not in the future\n if (BigInt(exactEvmPayload.authorization.validAfter) > BigInt(now)) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_authorization_valid_after\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n // Check balance\n try {\n const balance = (await this.signer.readContract({\n address: erc20Address,\n abi: eip3009ABI,\n functionName: \"balanceOf\",\n args: [exactEvmPayload.authorization.from],\n })) as bigint;\n\n if (BigInt(balance) < BigInt(requirementsV1.maxAmountRequired)) {\n return {\n isValid: false,\n invalidReason: \"insufficient_funds\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n } catch {\n // If we can't check balance, continue with other validations\n }\n\n // Verify amount is sufficient\n if (BigInt(exactEvmPayload.authorization.value) < BigInt(requirementsV1.maxAmountRequired)) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_authorization_value\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n return {\n isValid: true,\n invalidReason: undefined,\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n /**\n * Settles a payment by executing the transfer (V1).\n *\n * @param payload - The payment payload to settle\n * @param requirements - The payment requirements\n * @returns Promise resolving to settlement response\n */\n async settle(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<SettleResponse> {\n const payloadV1 = payload as unknown as PaymentPayloadV1;\n const exactEvmPayload = payload.payload as ExactEvmPayloadV1 | undefined;\n\n // Validate payload structure\n if (!exactEvmPayload?.authorization?.from) {\n return {\n success: false,\n network: payloadV1.network,\n transaction: \"\",\n errorReason: \"invalid_payload_structure\",\n payer: undefined,\n };\n }\n\n // Re-verify before settling\n const valid = await this.verify(payload, requirements);\n if (!valid.isValid) {\n return {\n success: false,\n network: payloadV1.network,\n transaction: \"\",\n errorReason: valid.invalidReason ?? \"invalid_scheme\",\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n try {\n // Parse ERC-6492 signature if applicable\n const parseResult = parseErc6492Signature(exactEvmPayload.signature!);\n const { signature, address: factoryAddress, data: factoryCalldata } = parseResult;\n\n // Deploy ERC-4337 smart wallet via EIP-6492 if configured and needed\n if (\n this.config.deployERC4337WithEIP6492 &&\n factoryAddress &&\n factoryCalldata &&\n !isAddressEqual(factoryAddress, \"0x0000000000000000000000000000000000000000\")\n ) {\n // Check if smart wallet is already deployed\n const payerAddress = exactEvmPayload.authorization.from;\n const bytecode = await this.signer.getCode({ address: payerAddress });\n\n if (!bytecode || bytecode === \"0x\") {\n // Wallet not deployed - attempt deployment\n try {\n console.log(`Deploying ERC-4337 smart wallet for ${payerAddress} via EIP-6492`);\n\n // Send the factory calldata directly as a transaction\n // The factoryCalldata already contains the complete encoded function call\n const deployTx = await this.signer.sendTransaction({\n to: factoryAddress as Hex,\n data: factoryCalldata as Hex,\n });\n\n // Wait for deployment transaction\n await this.signer.waitForTransactionReceipt({ hash: deployTx });\n console.log(`Successfully deployed smart wallet for ${payerAddress}`);\n } catch (deployError) {\n console.error(\"Smart wallet deployment failed:\", deployError);\n // Deployment failed - cannot proceed\n throw deployError;\n }\n } else {\n console.log(`Smart wallet for ${payerAddress} already deployed, skipping deployment`);\n }\n }\n\n // Determine if this is an ECDSA signature (EOA) or smart wallet signature\n // ECDSA signatures are exactly 65 bytes (130 hex chars without 0x)\n const signatureLength = signature.startsWith(\"0x\") ? signature.length - 2 : signature.length;\n const isECDSA = signatureLength === 130;\n\n let tx: Hex;\n if (isECDSA) {\n // For EOA wallets, parse signature into v, r, s and use that overload\n const parsedSig = parseSignature(signature);\n\n tx = await this.signer.writeContract({\n address: getAddress(requirements.asset),\n abi: eip3009ABI,\n functionName: \"transferWithAuthorization\",\n args: [\n getAddress(exactEvmPayload.authorization.from),\n getAddress(exactEvmPayload.authorization.to),\n BigInt(exactEvmPayload.authorization.value),\n BigInt(exactEvmPayload.authorization.validAfter),\n BigInt(exactEvmPayload.authorization.validBefore),\n exactEvmPayload.authorization.nonce,\n (parsedSig.v as number | undefined) || parsedSig.yParity,\n parsedSig.r,\n parsedSig.s,\n ],\n });\n } else {\n // For smart wallets, use the bytes signature overload\n // The signature contains WebAuthn/P256 or other ERC-1271 compatible signature data\n tx = await this.signer.writeContract({\n address: getAddress(requirements.asset),\n abi: eip3009ABI,\n functionName: \"transferWithAuthorization\",\n args: [\n getAddress(exactEvmPayload.authorization.from),\n getAddress(exactEvmPayload.authorization.to),\n BigInt(exactEvmPayload.authorization.value),\n BigInt(exactEvmPayload.authorization.validAfter),\n BigInt(exactEvmPayload.authorization.validBefore),\n exactEvmPayload.authorization.nonce,\n signature,\n ],\n });\n }\n\n // Wait for transaction confirmation\n const receipt = await this.signer.waitForTransactionReceipt({ hash: tx });\n\n if (receipt.status !== \"success\") {\n return {\n success: false,\n errorReason: \"invalid_transaction_state\",\n transaction: tx,\n network: payloadV1.network,\n payer: exactEvmPayload.authorization.from,\n };\n }\n\n return {\n success: true,\n transaction: tx,\n network: payloadV1.network,\n payer: exactEvmPayload.authorization.from,\n };\n } catch (error) {\n console.error(\"Failed to settle transaction:\", error);\n return {\n success: false,\n errorReason: \"transaction_failed\",\n transaction: \"\",\n network: payloadV1.network,\n payer: exactEvmPayload.authorization.from,\n };\n }\n }\n}\n"],"mappings":"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","names":[]}
|