@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.
Files changed (83) hide show
  1. package/dist/cjs/exact/client/index.d.ts +2 -2
  2. package/dist/cjs/exact/client/index.js +4 -2
  3. package/dist/cjs/exact/client/index.js.map +1 -1
  4. package/dist/cjs/exact/facilitator/index.d.ts +1 -1
  5. package/dist/cjs/exact/facilitator/index.js +40 -4
  6. package/dist/cjs/exact/facilitator/index.js.map +1 -1
  7. package/dist/cjs/exact/server/index.d.ts +1 -1
  8. package/dist/cjs/exact/server/index.js +301 -33
  9. package/dist/cjs/exact/server/index.js.map +1 -1
  10. package/dist/cjs/exact/v1/client/index.d.ts +1 -1
  11. package/dist/cjs/exact/v1/client/index.js +3 -1
  12. package/dist/cjs/exact/v1/client/index.js.map +1 -1
  13. package/dist/cjs/exact/v1/facilitator/index.d.ts +1 -1
  14. package/dist/cjs/exact/v1/facilitator/index.js +21 -2
  15. package/dist/cjs/exact/v1/facilitator/index.js.map +1 -1
  16. package/dist/cjs/index.d.ts +606 -352
  17. package/dist/cjs/index.js +1436 -268
  18. package/dist/cjs/index.js.map +1 -1
  19. package/dist/{esm/scheme-yqGaK9rK.d.mts → cjs/scheme-B4rXSKCN.d.ts} +18 -16
  20. package/dist/cjs/scheme-CIar5W2B.d.ts +200 -0
  21. package/dist/cjs/{scheme-OojTBKAz.d.ts → scheme-CjijeY7y.d.ts} +1 -1
  22. package/dist/{esm/signer-BkcAzwYi.d.mts → cjs/signer-DcavxxZt.d.ts} +1 -18
  23. package/dist/cjs/upto/client/index.d.ts +61 -0
  24. package/dist/cjs/upto/client/index.js +154 -0
  25. package/dist/cjs/upto/client/index.js.map +1 -0
  26. package/dist/cjs/upto/index.d.ts +111 -0
  27. package/dist/cjs/upto/index.js +1030 -0
  28. package/dist/cjs/upto/index.js.map +1 -0
  29. package/dist/cjs/v1/index.d.ts +1 -1
  30. package/dist/cjs/v1/index.js +3 -1
  31. package/dist/cjs/v1/index.js.map +1 -1
  32. package/dist/esm/{chunk-ACDQ5QNT.mjs → chunk-4FBTQTNM.mjs} +27 -5
  33. package/dist/esm/chunk-4FBTQTNM.mjs.map +1 -0
  34. package/dist/esm/chunk-IWSDEZKI.mjs +477 -0
  35. package/dist/esm/chunk-IWSDEZKI.mjs.map +1 -0
  36. package/dist/esm/{chunk-LGSG73NJ.mjs → chunk-LM5RZBVP.mjs} +9 -4
  37. package/dist/esm/{chunk-LGSG73NJ.mjs.map → chunk-LM5RZBVP.mjs.map} +1 -1
  38. package/dist/esm/chunk-NSSMTXJJ.mjs +8 -0
  39. package/dist/esm/chunk-NSSMTXJJ.mjs.map +1 -0
  40. package/dist/esm/chunk-SJ52GTJJ.mjs +411 -0
  41. package/dist/esm/chunk-SJ52GTJJ.mjs.map +1 -0
  42. package/dist/esm/chunk-SURTCHSX.mjs +129 -0
  43. package/dist/esm/chunk-SURTCHSX.mjs.map +1 -0
  44. package/dist/esm/chunk-SYVPLXYV.mjs +26 -0
  45. package/dist/esm/chunk-SYVPLXYV.mjs.map +1 -0
  46. package/dist/esm/{chunk-XYKAO6KJ.mjs → chunk-Y4U7Q543.mjs} +2 -25
  47. package/dist/esm/chunk-Y4U7Q543.mjs.map +1 -0
  48. package/dist/esm/{chunk-JBWWBRYY.mjs → chunk-ZWEYARER.mjs} +9 -4
  49. package/dist/esm/{chunk-JBWWBRYY.mjs.map → chunk-ZWEYARER.mjs.map} +1 -1
  50. package/dist/esm/exact/client/index.d.mts +2 -2
  51. package/dist/esm/exact/client/index.mjs +6 -4
  52. package/dist/esm/exact/client/index.mjs.map +1 -1
  53. package/dist/esm/exact/facilitator/index.d.mts +1 -1
  54. package/dist/esm/exact/facilitator/index.mjs +26 -5
  55. package/dist/esm/exact/facilitator/index.mjs.map +1 -1
  56. package/dist/esm/exact/server/index.d.mts +1 -1
  57. package/dist/esm/exact/server/index.mjs +29 -30
  58. package/dist/esm/exact/server/index.mjs.map +1 -1
  59. package/dist/esm/exact/v1/client/index.d.mts +1 -1
  60. package/dist/esm/exact/v1/client/index.mjs +4 -2
  61. package/dist/esm/exact/v1/facilitator/index.d.mts +1 -1
  62. package/dist/esm/exact/v1/facilitator/index.mjs +4 -2
  63. package/dist/esm/index.d.mts +606 -352
  64. package/dist/esm/index.mjs +626 -138
  65. package/dist/esm/index.mjs.map +1 -1
  66. package/dist/{cjs/scheme-yqGaK9rK.d.ts → esm/scheme-B4rXSKCN.d.mts} +18 -16
  67. package/dist/esm/scheme-DATfd6oM.d.mts +200 -0
  68. package/dist/esm/{scheme-D4mOqq9l.d.mts → scheme-Ddb0dG_F.d.mts} +1 -1
  69. package/dist/{cjs/signer-BkcAzwYi.d.ts → esm/signer-DcavxxZt.d.mts} +1 -18
  70. package/dist/esm/upto/client/index.d.mts +61 -0
  71. package/dist/esm/upto/client/index.mjs +11 -0
  72. package/dist/esm/upto/client/index.mjs.map +1 -0
  73. package/dist/esm/upto/index.d.mts +111 -0
  74. package/dist/esm/upto/index.mjs +26 -0
  75. package/dist/esm/upto/index.mjs.map +1 -0
  76. package/dist/esm/v1/index.d.mts +1 -1
  77. package/dist/esm/v1/index.mjs +5 -3
  78. package/package.json +30 -6
  79. package/dist/cjs/scheme-C6uD7PdY.d.ts +0 -130
  80. package/dist/esm/chunk-ACDQ5QNT.mjs.map +0 -1
  81. package/dist/esm/chunk-OEXW2OK2.mjs +0 -251
  82. package/dist/esm/chunk-OEXW2OK2.mjs.map +0 -1
  83. package/dist/esm/chunk-XYKAO6KJ.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/exact-legacy/client/scheme.ts","../../src/exact-legacy/server/scheme.ts","../../src/exact-legacy/facilitator/scheme.ts","../../src/signer.ts","../../src/bridge/client.ts","../../src/bridge/constants.ts","../../src/erc4337/constants.ts","../../src/erc4337/builder.ts","../../src/erc4337/bundler.ts","../../src/erc4337/paymaster.ts","../../src/erc4337/paymasters/pimlico.ts","../../src/erc4337/accounts/safe.ts","../../src/erc4337/t402.ts"],"sourcesContent":["import { PaymentPayload, PaymentRequirements, SchemeNetworkClient } from \"@t402/core/types\";\nimport { getAddress } from \"viem\";\nimport { legacyAuthorizationTypes } from \"../../constants.js\";\nimport { ClientEvmSigner } from \"../../signer.js\";\nimport { ExactLegacyPayload } from \"../../types.js\";\nimport { createNonce } from \"../../utils.js\";\n\n/**\n * EVM client implementation for the exact-legacy payment scheme.\n * Used for legacy tokens (like USDT) that don't support EIP-3009.\n *\n * This scheme uses the approve + transferFrom pattern:\n * 1. Client must first approve the facilitator to spend tokens\n * 2. Client signs an authorization message\n * 3. Facilitator verifies the signature and calls transferFrom\n *\n * Note: The client must have already approved the facilitator (spender)\n * for at least the payment amount before creating a payment payload.\n */\nexport class ExactLegacyEvmScheme implements SchemeNetworkClient {\n readonly scheme = \"exact-legacy\";\n\n /**\n * Creates a new ExactLegacyEvmScheme 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-legacy scheme.\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<Pick<PaymentPayload, \"t402Version\" | \"payload\">> {\n // Validate that we have the spender (facilitator) address\n if (!paymentRequirements.extra?.spender) {\n throw new Error(\n \"exact-legacy scheme requires 'spender' (facilitator address) in payment requirements extra field\",\n );\n }\n\n const spender = getAddress(paymentRequirements.extra.spender as string);\n const nonce = createNonce();\n const now = Math.floor(Date.now() / 1000);\n\n const authorization: ExactLegacyPayload[\"authorization\"] = {\n from: this.signer.address,\n to: getAddress(paymentRequirements.payTo),\n value: paymentRequirements.amount,\n validAfter: (now - 600).toString(), // 10 minutes before\n validBefore: (now + paymentRequirements.maxTimeoutSeconds).toString(),\n nonce,\n spender,\n };\n\n // Sign the authorization\n const signature = await this.signAuthorization(authorization, paymentRequirements);\n\n const payload: ExactLegacyPayload = {\n authorization,\n signature,\n };\n\n return {\n t402Version,\n payload,\n };\n }\n\n /**\n * Sign the legacy transfer 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: ExactLegacyPayload[\"authorization\"],\n requirements: PaymentRequirements,\n ): Promise<`0x${string}`> {\n const chainId = parseInt(requirements.network.split(\":\")[1]);\n\n // For legacy tokens, we use a simple domain with the token address\n // The name and version can be provided in extra, or we use defaults\n const name = (requirements.extra?.name as string) || \"T402LegacyTransfer\";\n const version = (requirements.extra?.version as string) || \"1\";\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 spender: getAddress(authorization.spender),\n };\n\n return await this.signer.signTypedData({\n domain,\n types: legacyAuthorizationTypes,\n primaryType: \"LegacyTransferAuthorization\",\n message,\n });\n }\n}\n","import {\n AssetAmount,\n Network,\n PaymentRequirements,\n Price,\n SchemeNetworkServer,\n MoneyParser,\n} from \"@t402/core/types\";\nimport {\n getTokenConfig,\n getTokenByAddress,\n TokenConfig,\n TOKEN_REGISTRY,\n USDT_LEGACY_ADDRESSES,\n} from \"../../tokens.js\";\n\n/**\n * Configuration options for ExactLegacyEvmScheme\n */\nexport interface ExactLegacyEvmSchemeConfig {\n /** Preferred token symbol. Defaults to \"USDT\" (legacy USDT) */\n preferredToken?: string;\n}\n\n/**\n * EVM server implementation for the exact-legacy payment scheme.\n * Supports legacy tokens that use approve + transferFrom pattern.\n */\nexport class ExactLegacyEvmScheme implements SchemeNetworkServer {\n readonly scheme = \"exact-legacy\";\n private moneyParsers: MoneyParser[] = [];\n private config: ExactLegacyEvmSchemeConfig;\n\n constructor(config: ExactLegacyEvmSchemeConfig = {}) {\n this.config = config;\n }\n\n /**\n * Register a custom money parser in the parser chain.\n */\n registerMoneyParser(parser: MoneyParser): ExactLegacyEvmScheme {\n this.moneyParsers.push(parser);\n return this;\n }\n\n /**\n * Parses a price into an asset amount for legacy tokens.\n */\n async parsePrice(price: Price, network: Network): Promise<AssetAmount> {\n // If already an AssetAmount, return it directly\n if (typeof price === \"object\" && price !== null && \"amount\" in price) {\n if (!price.asset) {\n throw new Error(`Asset address must be specified for AssetAmount on network ${network}`);\n }\n return {\n amount: price.amount,\n asset: price.asset,\n extra: {\n ...price.extra,\n tokenType: \"legacy\",\n },\n };\n }\n\n // Parse Money to decimal number\n const amount = this.parseMoneyToDecimal(price);\n\n // Try each custom money parser in order\n for (const parser of this.moneyParsers) {\n const result = await parser(amount, network);\n if (result !== null) {\n return result;\n }\n }\n\n // All custom parsers returned null, use default conversion\n return this.defaultMoneyConversion(amount, network);\n }\n\n /**\n * Build payment requirements for this scheme/network combination.\n * Adds the spender (facilitator) address to the extra field.\n */\n enhancePaymentRequirements(\n paymentRequirements: PaymentRequirements,\n supportedKind: {\n t402Version: number;\n scheme: string;\n network: Network;\n extra?: Record<string, unknown>;\n },\n extensionKeys: string[],\n ): Promise<PaymentRequirements> {\n void extensionKeys;\n\n // Add spender (facilitator) address from supportedKind.extra\n // The facilitator should provide its address in the extra field\n const spender = supportedKind.extra?.spender as string | undefined;\n\n return Promise.resolve({\n ...paymentRequirements,\n extra: {\n ...paymentRequirements.extra,\n tokenType: \"legacy\",\n ...(spender && { spender }),\n },\n });\n }\n\n /**\n * Parse Money (string | number) to a decimal number.\n */\n private parseMoneyToDecimal(money: string | number): number {\n if (typeof money === \"number\") {\n return money;\n }\n\n const cleanMoney = money.replace(/^\\$/, \"\").trim();\n const amount = parseFloat(cleanMoney);\n\n if (isNaN(amount)) {\n throw new Error(`Invalid money format: ${money}`);\n }\n\n return amount;\n }\n\n /**\n * Default money conversion implementation for legacy tokens.\n */\n private defaultMoneyConversion(amount: number, network: Network): AssetAmount {\n const token = this.getDefaultAsset(network);\n\n const tokenAmount = this.convertToTokenAmount(amount.toString(), token.decimals);\n\n return {\n amount: tokenAmount,\n asset: token.address,\n extra: {\n name: token.name,\n version: token.version,\n symbol: token.symbol,\n tokenType: \"legacy\",\n },\n };\n }\n\n /**\n * Convert decimal amount to token units\n */\n private convertToTokenAmount(decimalAmount: string, decimals: number): string {\n const amount = parseFloat(decimalAmount);\n if (isNaN(amount)) {\n throw new Error(`Invalid amount: ${decimalAmount}`);\n }\n const tokenAmount = Math.floor(amount * Math.pow(10, decimals));\n return tokenAmount.toString();\n }\n\n /**\n * Get the default legacy token for a network.\n */\n private getDefaultAsset(network: Network): TokenConfig {\n // If a preferred token is configured, try to use it\n if (this.config.preferredToken) {\n const preferred = getTokenConfig(network, this.config.preferredToken);\n if (preferred && preferred.tokenType === \"legacy\") {\n return preferred;\n }\n }\n\n // Look for legacy USDT on this network\n const usdt = getTokenConfig(network, \"USDT\");\n if (usdt && usdt.tokenType === \"legacy\") {\n return usdt;\n }\n\n // Fallback: find any legacy token on this network\n const tokens = TOKEN_REGISTRY[network];\n if (tokens) {\n const legacyToken = Object.values(tokens).find((t) => t.tokenType === \"legacy\");\n if (legacyToken) return legacyToken;\n }\n\n throw new Error(`No legacy tokens configured for network ${network}`);\n }\n\n /**\n * Get all supported networks that have legacy tokens\n */\n static getSupportedNetworks(): string[] {\n return Object.keys(USDT_LEGACY_ADDRESSES);\n }\n\n /**\n * Check if a network has legacy token support\n */\n static isNetworkSupported(network: string): boolean {\n return network in USDT_LEGACY_ADDRESSES;\n }\n}\n","import {\n PaymentPayload,\n PaymentRequirements,\n SchemeNetworkFacilitator,\n SettleResponse,\n VerifyResponse,\n} from \"@t402/core/types\";\nimport { getAddress, isAddressEqual } from \"viem\";\nimport { legacyAuthorizationTypes, erc20LegacyABI } from \"../../constants.js\";\nimport { FacilitatorEvmSigner } from \"../../signer.js\";\nimport { ExactLegacyPayload } from \"../../types.js\";\n\nexport interface ExactLegacyEvmSchemeConfig {\n /**\n * Minimum allowance ratio required (0.0 to 1.0)\n * If the allowance is less than this ratio of the payment amount,\n * verification will fail.\n *\n * @default 1.0 (exact allowance required)\n */\n minAllowanceRatio?: number;\n}\n\n/**\n * EVM facilitator implementation for the exact-legacy payment scheme.\n * Uses the approve + transferFrom pattern for legacy tokens.\n */\nexport class ExactLegacyEvmScheme implements SchemeNetworkFacilitator {\n readonly scheme = \"exact-legacy\";\n readonly caipFamily = \"eip155:*\";\n private readonly config: Required<ExactLegacyEvmSchemeConfig>;\n\n /**\n * Creates a new ExactLegacyEvmScheme 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?: ExactLegacyEvmSchemeConfig,\n ) {\n this.config = {\n minAllowanceRatio: config?.minAllowanceRatio ?? 1.0,\n };\n }\n\n /**\n * Get mechanism-specific extra data for the supported kinds endpoint.\n * For exact-legacy, returns the spender (facilitator) addresses.\n *\n * @param network - The network identifier\n * @returns Extra data including spender addresses\n */\n getExtra(network: string): Record<string, unknown> | undefined {\n void network;\n // Return the first facilitator address as the spender\n const addresses = this.signer.getAddresses();\n if (addresses.length > 0) {\n return {\n spender: addresses[0],\n tokenType: \"legacy\",\n };\n }\n return { tokenType: \"legacy\" };\n }\n\n /**\n * Get signer addresses used by this facilitator.\n */\n getSigners(network: string): string[] {\n void network;\n return [...this.signer.getAddresses()];\n }\n\n /**\n * Verifies a payment payload.\n */\n async verify(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<VerifyResponse> {\n const legacyPayload = payload.payload as ExactLegacyPayload;\n\n // Verify scheme matches\n if (payload.accepted.scheme !== \"exact-legacy\" || requirements.scheme !== \"exact-legacy\") {\n return {\n isValid: false,\n invalidReason: \"unsupported_scheme\",\n payer: legacyPayload.authorization.from,\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: legacyPayload.authorization.from,\n };\n }\n\n const erc20Address = getAddress(requirements.asset);\n\n // Verify the spender is one of our addresses\n const spender = getAddress(legacyPayload.authorization.spender);\n const facilitatorAddresses = this.signer.getAddresses();\n const isValidSpender = facilitatorAddresses.some((addr) => isAddressEqual(addr, spender));\n\n if (!isValidSpender) {\n return {\n isValid: false,\n invalidReason: \"invalid_spender\",\n payer: legacyPayload.authorization.from,\n };\n }\n\n // Build domain for signature verification\n const name = (requirements.extra?.name as string) || \"T402LegacyTransfer\";\n const version = (requirements.extra?.version as string) || \"1\";\n const chainId = parseInt(requirements.network.split(\":\")[1]);\n\n const domain = {\n name,\n version,\n chainId,\n verifyingContract: erc20Address,\n };\n\n const message = {\n from: legacyPayload.authorization.from,\n to: legacyPayload.authorization.to,\n value: BigInt(legacyPayload.authorization.value),\n validAfter: BigInt(legacyPayload.authorization.validAfter),\n validBefore: BigInt(legacyPayload.authorization.validBefore),\n nonce: legacyPayload.authorization.nonce,\n spender: legacyPayload.authorization.spender,\n };\n\n // Verify signature\n try {\n const isValid = await this.signer.verifyTypedData({\n address: legacyPayload.authorization.from,\n domain,\n types: legacyAuthorizationTypes,\n primaryType: \"LegacyTransferAuthorization\",\n message,\n signature: legacyPayload.signature!,\n });\n\n if (!isValid) {\n return {\n isValid: false,\n invalidReason: \"invalid_signature\",\n payer: legacyPayload.authorization.from,\n };\n }\n } catch {\n return {\n isValid: false,\n invalidReason: \"signature_verification_failed\",\n payer: legacyPayload.authorization.from,\n };\n }\n\n // Verify payment recipient matches\n if (getAddress(legacyPayload.authorization.to) !== getAddress(requirements.payTo)) {\n return {\n isValid: false,\n invalidReason: \"recipient_mismatch\",\n payer: legacyPayload.authorization.from,\n };\n }\n\n // Verify validBefore is in the future\n const now = Math.floor(Date.now() / 1000);\n if (BigInt(legacyPayload.authorization.validBefore) < BigInt(now + 6)) {\n return {\n isValid: false,\n invalidReason: \"authorization_expired\",\n payer: legacyPayload.authorization.from,\n };\n }\n\n // Verify validAfter is not in the future\n if (BigInt(legacyPayload.authorization.validAfter) > BigInt(now)) {\n return {\n isValid: false,\n invalidReason: \"authorization_not_yet_valid\",\n payer: legacyPayload.authorization.from,\n };\n }\n\n // Check balance\n try {\n const balance = (await this.signer.readContract({\n address: erc20Address,\n abi: erc20LegacyABI,\n functionName: \"balanceOf\",\n args: [legacyPayload.authorization.from],\n })) as bigint;\n\n if (BigInt(balance) < BigInt(requirements.amount)) {\n return {\n isValid: false,\n invalidReason: \"insufficient_balance\",\n payer: legacyPayload.authorization.from,\n };\n }\n } catch {\n // If we can't check balance, continue with other validations\n }\n\n // Check allowance\n try {\n const allowance = (await this.signer.readContract({\n address: erc20Address,\n abi: erc20LegacyABI,\n functionName: \"allowance\",\n args: [legacyPayload.authorization.from, spender],\n })) as bigint;\n\n const requiredAllowance = BigInt(\n Math.floor(Number(requirements.amount) * this.config.minAllowanceRatio),\n );\n\n if (allowance < requiredAllowance) {\n return {\n isValid: false,\n invalidReason: \"insufficient_allowance\",\n payer: legacyPayload.authorization.from,\n };\n }\n } catch {\n return {\n isValid: false,\n invalidReason: \"allowance_check_failed\",\n payer: legacyPayload.authorization.from,\n };\n }\n\n // Verify amount is sufficient\n if (BigInt(legacyPayload.authorization.value) < BigInt(requirements.amount)) {\n return {\n isValid: false,\n invalidReason: \"insufficient_amount\",\n payer: legacyPayload.authorization.from,\n };\n }\n\n return {\n isValid: true,\n invalidReason: undefined,\n payer: legacyPayload.authorization.from,\n };\n }\n\n /**\n * Settles a payment by executing transferFrom.\n */\n async settle(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<SettleResponse> {\n const legacyPayload = payload.payload as ExactLegacyPayload;\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: payload.accepted.network,\n transaction: \"\",\n errorReason: valid.invalidReason ?? \"invalid_payment\",\n payer: legacyPayload.authorization.from,\n };\n }\n\n try {\n // Execute transferFrom\n const tx = await this.signer.writeContract({\n address: getAddress(requirements.asset),\n abi: erc20LegacyABI,\n functionName: \"transferFrom\",\n args: [\n getAddress(legacyPayload.authorization.from),\n getAddress(legacyPayload.authorization.to),\n BigInt(legacyPayload.authorization.value),\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: \"transaction_failed\",\n transaction: tx,\n network: payload.accepted.network,\n payer: legacyPayload.authorization.from,\n };\n }\n\n return {\n success: true,\n transaction: tx,\n network: payload.accepted.network,\n payer: legacyPayload.authorization.from,\n };\n } catch (error) {\n console.error(\"Failed to settle legacy transaction:\", error);\n return {\n success: false,\n errorReason: \"settlement_failed\",\n transaction: \"\",\n network: payload.accepted.network,\n payer: legacyPayload.authorization.from,\n };\n }\n }\n}\n","/**\n * ClientEvmSigner - Used by t402 clients to sign payment authorizations\n * This is typically a LocalAccount or wallet that holds private keys\n * and can sign EIP-712 typed data for payment authorizations\n */\nexport type ClientEvmSigner = {\n readonly address: `0x${string}`;\n signTypedData(message: {\n domain: Record<string, unknown>;\n types: Record<string, unknown>;\n primaryType: string;\n message: Record<string, unknown>;\n }): Promise<`0x${string}`>;\n};\n\n/**\n * FacilitatorEvmSigner - Used by t402 facilitators to verify and settle payments\n * This is typically a viem PublicClient + WalletClient combination that can\n * read contract state, verify signatures, write transactions, and wait for receipts\n *\n * Supports multiple addresses for load balancing, key rotation, and high availability\n */\nexport type FacilitatorEvmSigner = {\n /**\n * Get all addresses this facilitator can use for signing\n * Enables dynamic address selection for load balancing and key rotation\n */\n getAddresses(): readonly `0x${string}`[];\n\n readContract(args: {\n address: `0x${string}`;\n abi: readonly unknown[];\n functionName: string;\n args?: readonly unknown[];\n }): Promise<unknown>;\n verifyTypedData(args: {\n address: `0x${string}`;\n domain: Record<string, unknown>;\n types: Record<string, unknown>;\n primaryType: string;\n message: Record<string, unknown>;\n signature: `0x${string}`;\n }): Promise<boolean>;\n writeContract(args: {\n address: `0x${string}`;\n abi: readonly unknown[];\n functionName: string;\n args: readonly unknown[];\n }): Promise<`0x${string}`>;\n sendTransaction(args: { to: `0x${string}`; data: `0x${string}` }): Promise<`0x${string}`>;\n waitForTransactionReceipt(args: { hash: `0x${string}` }): Promise<{ status: string }>;\n getCode(args: { address: `0x${string}` }): Promise<`0x${string}` | undefined>;\n};\n\n/**\n * Converts a signer to a ClientEvmSigner\n *\n * @param signer - The signer to convert to a ClientEvmSigner\n * @returns The converted signer\n */\nexport function toClientEvmSigner(signer: ClientEvmSigner): ClientEvmSigner {\n return signer;\n}\n\n/**\n * Converts a viem client with single address to a FacilitatorEvmSigner\n * Wraps the single address in a getAddresses() function for compatibility\n *\n * @param client - The client to convert (must have 'address' property)\n * @returns FacilitatorEvmSigner with getAddresses() support\n */\nexport function toFacilitatorEvmSigner(\n client: Omit<FacilitatorEvmSigner, \"getAddresses\"> & { address: `0x${string}` },\n): FacilitatorEvmSigner {\n return {\n ...client,\n getAddresses: () => [client.address],\n };\n}\n","/**\n * USDT0 Bridge Client\n *\n * Provides cross-chain USDT0 transfers using LayerZero OFT standard.\n *\n * @example\n * ```typescript\n * import { Usdt0Bridge } from '@t402/evm';\n * import { createWalletClient, http } from 'viem';\n * import { arbitrum } from 'viem/chains';\n *\n * const walletClient = createWalletClient({\n * chain: arbitrum,\n * transport: http(),\n * account: privateKeyToAccount(privateKey),\n * });\n *\n * const bridge = new Usdt0Bridge(walletClient, 'arbitrum');\n *\n * // Get quote\n * const quote = await bridge.quote({\n * fromChain: 'arbitrum',\n * toChain: 'ethereum',\n * amount: 100_000000n, // 100 USDT0\n * recipient: '0x...',\n * });\n *\n * // Execute bridge\n * const result = await bridge.send({\n * fromChain: 'arbitrum',\n * toChain: 'ethereum',\n * amount: 100_000000n,\n * recipient: '0x...',\n * });\n * ```\n */\n\nimport type { Address } from \"viem\";\nimport { keccak256, toBytes } from \"viem\";\nimport {\n getEndpointId,\n getUsdt0OftAddress,\n supportsBridging,\n addressToBytes32,\n OFT_SEND_ABI,\n ERC20_APPROVE_ABI,\n DEFAULT_EXTRA_OPTIONS,\n getBridgeableChains,\n} from \"./constants.js\";\nimport type {\n BridgeQuoteParams,\n BridgeQuote,\n BridgeExecuteParams,\n BridgeResult,\n BridgeSigner,\n SendParam,\n MessagingFee,\n TransactionReceipt,\n} from \"./types.js\";\n\n/**\n * OFTSent event signature for GUID extraction\n * Event: OFTSent(bytes32 indexed guid, uint32 dstEid, address indexed from, uint256 amountSentLD, uint256 amountReceivedLD)\n */\nconst OFT_SENT_EVENT_TOPIC = keccak256(\n toBytes(\"OFTSent(bytes32,uint32,address,uint256,uint256)\")\n);\n\n/**\n * Default slippage tolerance (0.5%)\n */\nconst DEFAULT_SLIPPAGE = 0.5;\n\n/**\n * Estimated bridge completion time in seconds\n */\nconst ESTIMATED_BRIDGE_TIME = 300; // ~5 minutes\n\n/**\n * USDT0 Bridge Client for LayerZero OFT transfers\n */\nexport class Usdt0Bridge {\n private readonly signer: BridgeSigner;\n private readonly chain: string;\n\n /**\n * Create a new bridge client\n *\n * @param signer - Wallet signer with read/write capabilities\n * @param chain - Source chain name (e.g., \"arbitrum\", \"ethereum\")\n */\n constructor(signer: BridgeSigner, chain: string) {\n if (!supportsBridging(chain)) {\n throw new Error(\n `Chain \"${chain}\" does not support USDT0 bridging. Supported chains: ${getBridgeableChains().join(\", \")}`,\n );\n }\n\n this.signer = signer;\n this.chain = chain;\n }\n\n /**\n * Get a quote for bridging USDT0\n *\n * @param params - Bridge parameters\n * @returns Quote with fee and amount information\n */\n async quote(params: BridgeQuoteParams): Promise<BridgeQuote> {\n this.validateBridgeParams(params);\n\n const sendParam = this.buildSendParam(params);\n const oftAddress = getUsdt0OftAddress(params.fromChain)!;\n\n // Get quote from contract\n const fee = (await this.signer.readContract({\n address: oftAddress,\n abi: OFT_SEND_ABI,\n functionName: \"quoteSend\",\n args: [sendParam, false],\n })) as MessagingFee;\n\n return {\n nativeFee: fee.nativeFee,\n amountToSend: params.amount,\n minAmountToReceive: sendParam.minAmountLD,\n estimatedTime: ESTIMATED_BRIDGE_TIME,\n fromChain: params.fromChain,\n toChain: params.toChain,\n };\n }\n\n /**\n * Execute a bridge transaction\n *\n * @param params - Bridge execution parameters\n * @returns Bridge result with transaction hash\n */\n async send(params: BridgeExecuteParams): Promise<BridgeResult> {\n this.validateBridgeParams(params);\n\n const oftAddress = getUsdt0OftAddress(params.fromChain)!;\n const sendParam = this.buildSendParam(params);\n const refundAddress = params.refundAddress ?? this.signer.address;\n\n // Get fee quote\n const fee = (await this.signer.readContract({\n address: oftAddress,\n abi: OFT_SEND_ABI,\n functionName: \"quoteSend\",\n args: [sendParam, false],\n })) as MessagingFee;\n\n // Check and approve allowance if needed\n await this.ensureAllowance(oftAddress, params.amount);\n\n // Execute bridge transaction\n const txHash = await this.signer.writeContract({\n address: oftAddress,\n abi: OFT_SEND_ABI,\n functionName: \"send\",\n args: [sendParam, fee, refundAddress],\n value: fee.nativeFee,\n });\n\n // Wait for transaction confirmation\n const receipt = await this.signer.waitForTransactionReceipt({ hash: txHash });\n\n if (receipt.status !== \"success\") {\n throw new Error(`Bridge transaction failed: ${txHash}`);\n }\n\n // Extract message GUID from OFTSent event logs\n const messageGuid = this.extractMessageGuid(receipt);\n\n return {\n txHash,\n messageGuid,\n amountSent: params.amount,\n amountToReceive: sendParam.minAmountLD,\n fromChain: params.fromChain,\n toChain: params.toChain,\n estimatedTime: ESTIMATED_BRIDGE_TIME,\n };\n }\n\n /**\n * Extract LayerZero message GUID from OFTSent event logs\n *\n * @param receipt - Transaction receipt with logs\n * @returns Message GUID as hex string\n */\n private extractMessageGuid(receipt: TransactionReceipt): `0x${string}` {\n for (const log of receipt.logs) {\n // Check if this is an OFTSent event\n if (log.topics[0] === OFT_SENT_EVENT_TOPIC && log.topics[1]) {\n // GUID is the first indexed parameter (topics[1])\n return log.topics[1];\n }\n }\n\n throw new Error(\n \"Failed to extract message GUID from transaction logs. \" +\n \"The OFTSent event was not found in the transaction receipt.\",\n );\n }\n\n /**\n * Ensure sufficient token allowance for the OFT contract\n */\n private async ensureAllowance(oftAddress: Address, amount: bigint): Promise<void> {\n // Check current allowance\n const allowance = (await this.signer.readContract({\n address: oftAddress,\n abi: ERC20_APPROVE_ABI,\n functionName: \"allowance\",\n args: [this.signer.address, oftAddress],\n })) as bigint;\n\n // Approve if needed\n if (allowance < amount) {\n const approveTx = await this.signer.writeContract({\n address: oftAddress,\n abi: ERC20_APPROVE_ABI,\n functionName: \"approve\",\n args: [oftAddress, amount],\n });\n\n await this.signer.waitForTransactionReceipt({ hash: approveTx });\n }\n }\n\n /**\n * Build SendParam struct for LayerZero\n */\n private buildSendParam(params: BridgeQuoteParams | BridgeExecuteParams): SendParam {\n const dstEid = getEndpointId(params.toChain);\n if (!dstEid) {\n throw new Error(`Unknown destination chain: ${params.toChain}`);\n }\n\n const slippage = \"slippageTolerance\" in params\n ? (params as BridgeExecuteParams).slippageTolerance ?? DEFAULT_SLIPPAGE\n : DEFAULT_SLIPPAGE;\n\n // Calculate minimum amount with slippage\n const minAmount = params.amount - (params.amount * BigInt(Math.floor(slippage * 100))) / 10000n;\n\n return {\n dstEid,\n to: addressToBytes32(params.recipient),\n amountLD: params.amount,\n minAmountLD: minAmount,\n extraOptions: DEFAULT_EXTRA_OPTIONS,\n composeMsg: \"0x\" as `0x${string}`,\n oftCmd: \"0x\" as `0x${string}`,\n };\n }\n\n /**\n * Validate bridge parameters\n */\n private validateBridgeParams(params: BridgeQuoteParams): void {\n if (params.fromChain !== this.chain) {\n throw new Error(\n `Source chain mismatch: bridge initialized for \"${this.chain}\" but got \"${params.fromChain}\"`,\n );\n }\n\n if (!supportsBridging(params.fromChain)) {\n throw new Error(`Source chain \"${params.fromChain}\" does not support USDT0 bridging`);\n }\n\n if (!supportsBridging(params.toChain)) {\n throw new Error(`Destination chain \"${params.toChain}\" does not support USDT0 bridging`);\n }\n\n if (params.fromChain === params.toChain) {\n throw new Error(\"Source and destination chains must be different\");\n }\n\n if (params.amount <= 0n) {\n throw new Error(\"Amount must be greater than 0\");\n }\n }\n\n /**\n * Get all supported destination chains from current chain\n */\n getSupportedDestinations(): string[] {\n return getBridgeableChains().filter((chain) => chain !== this.chain);\n }\n\n /**\n * Check if a destination chain is supported\n */\n supportsDestination(toChain: string): boolean {\n return toChain !== this.chain && supportsBridging(toChain);\n }\n}\n\n/**\n * Create a bridge client for a specific chain\n */\nexport function createUsdt0Bridge(signer: BridgeSigner, chain: string): Usdt0Bridge {\n return new Usdt0Bridge(signer, chain);\n}\n","/**\n * LayerZero OFT Bridge Constants for USDT0\n *\n * USDT0 uses LayerZero's OFT (Omnichain Fungible Token) standard\n * for cross-chain transfers.\n *\n * @see https://docs.layerzero.network/v2/developers/evm/oft/quickstart\n */\n\nimport type { Address } from \"viem\";\n\n/**\n * LayerZero V2 Endpoint IDs (EIDs) for supported chains\n * These are unique identifiers used by LayerZero to route messages\n *\n * @see https://docs.layerzero.network/v2/deployments/deployed-contracts\n */\nexport const LAYERZERO_ENDPOINT_IDS: Record<string, number> = {\n // Mainnets\n ethereum: 30101,\n arbitrum: 30110,\n base: 30184,\n optimism: 30111,\n polygon: 30109,\n avalanche: 30106,\n bsc: 30102,\n // USDT0 specific chains\n ink: 30291, // Ink mainnet\n berachain: 30362, // Berachain mainnet\n unichain: 30320, // Unichain mainnet\n // Testnets\n sepolia: 40161,\n arbitrumSepolia: 40231,\n baseSepolia: 40245,\n};\n\n/**\n * Map from CAIP-2 network ID to chain name\n */\nexport const NETWORK_TO_CHAIN: Record<string, string> = {\n \"eip155:1\": \"ethereum\",\n \"eip155:42161\": \"arbitrum\",\n \"eip155:8453\": \"base\",\n \"eip155:10\": \"optimism\",\n \"eip155:137\": \"polygon\",\n \"eip155:43114\": \"avalanche\",\n \"eip155:56\": \"bsc\",\n \"eip155:57073\": \"ink\",\n \"eip155:80094\": \"berachain\",\n \"eip155:130\": \"unichain\",\n // Testnets\n \"eip155:11155111\": \"sepolia\",\n \"eip155:421614\": \"arbitrumSepolia\",\n \"eip155:84532\": \"baseSepolia\",\n};\n\n/**\n * Map from chain name to CAIP-2 network ID\n */\nexport const CHAIN_TO_NETWORK: Record<string, string> = Object.fromEntries(\n Object.entries(NETWORK_TO_CHAIN).map(([k, v]) => [v, k]),\n);\n\n/**\n * USDT0 OFT Adapter contract addresses by chain\n * These are the contracts that handle cross-chain transfers\n */\nexport const USDT0_OFT_ADDRESSES: Record<string, Address> = {\n // Ethereum is the OFT Adapter (locks/unlocks tokens)\n ethereum: \"0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee\",\n // Other chains have native USDT0 OFT contracts\n arbitrum: \"0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9\",\n ink: \"0x0200C29006150606B650577BBE7B6248F58470c1\",\n berachain: \"0x779Ded0c9e1022225f8E0630b35a9b54bE713736\",\n unichain: \"0x588ce4F028D8e7B53B687865d6A67b3A54C75518\",\n};\n\n/**\n * LayerZero V2 Endpoint contract addresses\n * Same address on all EVM chains\n */\nexport const LAYERZERO_ENDPOINT_V2: Address = \"0x1a44076050125825900e736c501f859c50fE728c\";\n\n/**\n * Default gas limit for cross-chain messages\n */\nexport const DEFAULT_GAS_LIMIT = 200000n;\n\n/**\n * Default extra options for LayerZero messages\n * Type 3 options with executor gas\n */\nexport const DEFAULT_EXTRA_OPTIONS = \"0x00030100110100000000000000000000000000030d40\" as `0x${string}`;\n\n/**\n * OFT Send ABI for cross-chain transfers\n */\nexport const OFT_SEND_ABI = [\n {\n inputs: [\n {\n components: [\n { name: \"dstEid\", type: \"uint32\" },\n { name: \"to\", type: \"bytes32\" },\n { name: \"amountLD\", type: \"uint256\" },\n { name: \"minAmountLD\", type: \"uint256\" },\n { name: \"extraOptions\", type: \"bytes\" },\n { name: \"composeMsg\", type: \"bytes\" },\n { name: \"oftCmd\", type: \"bytes\" },\n ],\n name: \"_sendParam\",\n type: \"tuple\",\n },\n {\n components: [\n { name: \"nativeFee\", type: \"uint256\" },\n { name: \"lzTokenFee\", type: \"uint256\" },\n ],\n name: \"_fee\",\n type: \"tuple\",\n },\n { name: \"_refundAddress\", type: \"address\" },\n ],\n name: \"send\",\n outputs: [\n {\n components: [\n { name: \"guid\", type: \"bytes32\" },\n { name: \"nonce\", type: \"uint64\" },\n {\n components: [\n { name: \"nativeFee\", type: \"uint256\" },\n { name: \"lzTokenFee\", type: \"uint256\" },\n ],\n name: \"fee\",\n type: \"tuple\",\n },\n ],\n name: \"msgReceipt\",\n type: \"tuple\",\n },\n {\n components: [\n { name: \"amountSentLD\", type: \"uint256\" },\n { name: \"amountReceivedLD\", type: \"uint256\" },\n ],\n name: \"oftReceipt\",\n type: \"tuple\",\n },\n ],\n stateMutability: \"payable\",\n type: \"function\",\n },\n {\n inputs: [\n {\n components: [\n { name: \"dstEid\", type: \"uint32\" },\n { name: \"to\", type: \"bytes32\" },\n { name: \"amountLD\", type: \"uint256\" },\n { name: \"minAmountLD\", type: \"uint256\" },\n { name: \"extraOptions\", type: \"bytes\" },\n { name: \"composeMsg\", type: \"bytes\" },\n { name: \"oftCmd\", type: \"bytes\" },\n ],\n name: \"_sendParam\",\n type: \"tuple\",\n },\n { name: \"_payInLzToken\", type: \"bool\" },\n ],\n name: \"quoteSend\",\n outputs: [\n {\n components: [\n { name: \"nativeFee\", type: \"uint256\" },\n { name: \"lzTokenFee\", type: \"uint256\" },\n ],\n name: \"msgFee\",\n type: \"tuple\",\n },\n ],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const;\n\n/**\n * ERC20 approval ABI for token allowance\n */\nexport const ERC20_APPROVE_ABI = [\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: \"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] as const;\n\n/**\n * Get LayerZero endpoint ID for a chain\n */\nexport function getEndpointId(chain: string): number | undefined {\n return LAYERZERO_ENDPOINT_IDS[chain];\n}\n\n/**\n * Get LayerZero endpoint ID from CAIP-2 network\n */\nexport function getEndpointIdFromNetwork(network: string): number | undefined {\n const chain = NETWORK_TO_CHAIN[network];\n return chain ? LAYERZERO_ENDPOINT_IDS[chain] : undefined;\n}\n\n/**\n * Get USDT0 OFT contract address for a chain\n */\nexport function getUsdt0OftAddress(chain: string): Address | undefined {\n return USDT0_OFT_ADDRESSES[chain];\n}\n\n/**\n * Check if a chain supports USDT0 bridging\n */\nexport function supportsBridging(chain: string): boolean {\n return chain in USDT0_OFT_ADDRESSES && chain in LAYERZERO_ENDPOINT_IDS;\n}\n\n/**\n * Get all chains that support USDT0 bridging\n */\nexport function getBridgeableChains(): string[] {\n return Object.keys(USDT0_OFT_ADDRESSES).filter(\n (chain) => chain in LAYERZERO_ENDPOINT_IDS,\n );\n}\n\n/**\n * Convert address to bytes32 format for LayerZero\n * Pads address with leading zeros to 32 bytes\n */\nexport function addressToBytes32(address: Address): `0x${string}` {\n // Remove 0x prefix, pad to 64 chars (32 bytes), add 0x prefix\n const cleanAddress = address.slice(2).toLowerCase();\n return `0x${cleanAddress.padStart(64, \"0\")}` as `0x${string}`;\n}\n\n/**\n * Convert bytes32 to address\n */\nexport function bytes32ToAddress(bytes32: `0x${string}`): Address {\n // Take last 40 characters (20 bytes)\n return `0x${bytes32.slice(-40)}` as Address;\n}\n","/**\n * ERC-4337 Account Abstraction Constants\n *\n * Provides constants for ERC-4337 v0.7 implementation including:\n * - EntryPoint contract addresses\n * - Default gas limits\n * - ABI definitions\n *\n * @see https://eips.ethereum.org/EIPS/eip-4337\n */\n\nimport type { Address } from \"viem\";\n\n/**\n * EntryPoint v0.7 contract address (canonical deployment)\n * Deployed on all major EVM chains at the same address\n */\nexport const ENTRYPOINT_V07_ADDRESS: Address =\n \"0x0000000071727De22E5E9d8BAf0edAc6f37da032\";\n\n/**\n * EntryPoint v0.6 contract address (legacy)\n */\nexport const ENTRYPOINT_V06_ADDRESS: Address =\n \"0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789\";\n\n/**\n * Default gas limits for UserOperations\n */\nexport const DEFAULT_GAS_LIMITS = {\n /** Gas for account validation */\n verificationGasLimit: 150000n,\n /** Gas for callData execution */\n callGasLimit: 100000n,\n /** Gas paid to bundler for overhead */\n preVerificationGas: 50000n,\n /** Gas for paymaster validation */\n paymasterVerificationGasLimit: 50000n,\n /** Gas for paymaster post-op */\n paymasterPostOpGasLimit: 50000n,\n} as const;\n\n/**\n * EntryPoint v0.7 ABI (essential functions)\n */\nexport const ENTRYPOINT_V07_ABI = [\n {\n inputs: [\n {\n components: [\n { name: \"sender\", type: \"address\" },\n { name: \"nonce\", type: \"uint256\" },\n { name: \"initCode\", type: \"bytes\" },\n { name: \"callData\", type: \"bytes\" },\n { name: \"accountGasLimits\", type: \"bytes32\" },\n { name: \"preVerificationGas\", type: \"uint256\" },\n { name: \"gasFees\", type: \"bytes32\" },\n { name: \"paymasterAndData\", type: \"bytes\" },\n { name: \"signature\", type: \"bytes\" },\n ],\n name: \"ops\",\n type: \"tuple[]\",\n },\n { name: \"beneficiary\", type: \"address\" },\n ],\n name: \"handleOps\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [{ name: \"sender\", type: \"address\" }],\n name: \"getNonce\",\n outputs: [{ name: \"nonce\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"sender\", type: \"address\" },\n { name: \"key\", type: \"uint192\" },\n ],\n name: \"getNonce\",\n outputs: [{ name: \"nonce\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n {\n components: [\n { name: \"sender\", type: \"address\" },\n { name: \"nonce\", type: \"uint256\" },\n { name: \"initCode\", type: \"bytes\" },\n { name: \"callData\", type: \"bytes\" },\n { name: \"accountGasLimits\", type: \"bytes32\" },\n { name: \"preVerificationGas\", type: \"uint256\" },\n { name: \"gasFees\", type: \"bytes32\" },\n { name: \"paymasterAndData\", type: \"bytes\" },\n { name: \"signature\", type: \"bytes\" },\n ],\n name: \"userOp\",\n type: \"tuple\",\n },\n ],\n name: \"getUserOpHash\",\n outputs: [{ name: \"\", type: \"bytes32\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const;\n\n/**\n * IAccount interface ABI (smart wallet validation)\n */\nexport const ACCOUNT_ABI = [\n {\n inputs: [\n {\n components: [\n { name: \"sender\", type: \"address\" },\n { name: \"nonce\", type: \"uint256\" },\n { name: \"initCode\", type: \"bytes\" },\n { name: \"callData\", type: \"bytes\" },\n { name: \"accountGasLimits\", type: \"bytes32\" },\n { name: \"preVerificationGas\", type: \"uint256\" },\n { name: \"gasFees\", type: \"bytes32\" },\n { name: \"paymasterAndData\", type: \"bytes\" },\n { name: \"signature\", type: \"bytes\" },\n ],\n name: \"userOp\",\n type: \"tuple\",\n },\n { name: \"userOpHash\", type: \"bytes32\" },\n { name: \"missingAccountFunds\", type: \"uint256\" },\n ],\n name: \"validateUserOp\",\n outputs: [{ name: \"validationData\", type: \"uint256\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"dest\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"func\", type: \"bytes\" },\n ],\n name: \"execute\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"dest\", type: \"address[]\" },\n { name: \"value\", type: \"uint256[]\" },\n { name: \"func\", type: \"bytes[]\" },\n ],\n name: \"executeBatch\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n\n/**\n * Bundler JSON-RPC method names\n */\nexport const BUNDLER_METHODS = {\n sendUserOperation: \"eth_sendUserOperation\",\n estimateUserOperationGas: \"eth_estimateUserOperationGas\",\n getUserOperationByHash: \"eth_getUserOperationByHash\",\n getUserOperationReceipt: \"eth_getUserOperationReceipt\",\n supportedEntryPoints: \"eth_supportedEntryPoints\",\n chainId: \"eth_chainId\",\n} as const;\n\n/**\n * Common paymaster types\n */\nexport enum PaymasterType {\n /** No paymaster - user pays gas */\n None = \"none\",\n /** Verifying paymaster with off-chain signature */\n Verifying = \"verifying\",\n /** Token paymaster - pay gas with ERC20 */\n Token = \"token\",\n /** Sponsoring paymaster - third party pays */\n Sponsoring = \"sponsoring\",\n}\n\n/**\n * Pack verification and call gas limits into bytes32\n */\nexport function packAccountGasLimits(\n verificationGasLimit: bigint,\n callGasLimit: bigint,\n): `0x${string}` {\n // First 16 bytes: verification gas limit\n // Last 16 bytes: call gas limit\n const verificationHex = verificationGasLimit.toString(16).padStart(32, \"0\");\n const callHex = callGasLimit.toString(16).padStart(32, \"0\");\n return `0x${verificationHex}${callHex}` as `0x${string}`;\n}\n\n/**\n * Unpack account gas limits from bytes32\n */\nexport function unpackAccountGasLimits(packed: `0x${string}`): {\n verificationGasLimit: bigint;\n callGasLimit: bigint;\n} {\n const hex = packed.slice(2);\n const verificationHex = hex.slice(0, 32);\n const callHex = hex.slice(32, 64);\n return {\n verificationGasLimit: BigInt(\"0x\" + verificationHex),\n callGasLimit: BigInt(\"0x\" + callHex),\n };\n}\n\n/**\n * Pack max priority fee and max fee per gas into bytes32\n */\nexport function packGasFees(\n maxPriorityFeePerGas: bigint,\n maxFeePerGas: bigint,\n): `0x${string}` {\n const priorityHex = maxPriorityFeePerGas.toString(16).padStart(32, \"0\");\n const maxHex = maxFeePerGas.toString(16).padStart(32, \"0\");\n return `0x${priorityHex}${maxHex}` as `0x${string}`;\n}\n\n/**\n * Unpack gas fees from bytes32\n */\nexport function unpackGasFees(packed: `0x${string}`): {\n maxPriorityFeePerGas: bigint;\n maxFeePerGas: bigint;\n} {\n const hex = packed.slice(2);\n const priorityHex = hex.slice(0, 32);\n const maxHex = hex.slice(32, 64);\n return {\n maxPriorityFeePerGas: BigInt(\"0x\" + priorityHex),\n maxFeePerGas: BigInt(\"0x\" + maxHex),\n };\n}\n","/**\n * ERC-4337 UserOperation Builder\n *\n * Builds UserOperations from transaction intents for ERC-4337 v0.7.\n * Handles gas estimation, nonce management, and operation packing.\n */\n\nimport type { Address, Hex, PublicClient } from \"viem\";\nimport { encodeFunctionData, concat, pad, toHex } from \"viem\";\nimport type {\n UserOperation,\n PackedUserOperation,\n SmartAccountSigner,\n TransactionIntent,\n GasEstimate,\n PaymasterData,\n} from \"./types.js\";\nimport {\n ENTRYPOINT_V07_ADDRESS,\n ENTRYPOINT_V07_ABI,\n DEFAULT_GAS_LIMITS,\n packAccountGasLimits,\n packGasFees,\n} from \"./constants.js\";\n\n/**\n * Builder configuration\n */\nexport interface UserOpBuilderOptions {\n /** EntryPoint address (defaults to v0.7) */\n entryPoint?: Address;\n /** Default gas multiplier for safety margin */\n gasMultiplier?: number;\n}\n\n/**\n * UserOperation Builder for creating and packing operations\n */\nexport class UserOpBuilder {\n private readonly entryPoint: Address;\n private readonly gasMultiplier: number;\n\n constructor(options: UserOpBuilderOptions = {}) {\n this.entryPoint = options.entryPoint ?? ENTRYPOINT_V07_ADDRESS;\n this.gasMultiplier = options.gasMultiplier ?? 1.2;\n }\n\n /**\n * Build a UserOperation from a transaction intent\n */\n async buildUserOp(\n signer: SmartAccountSigner,\n intent: TransactionIntent,\n client: PublicClient,\n gasEstimate?: GasEstimate,\n paymaster?: PaymasterData,\n ): Promise<UserOperation> {\n const sender = await signer.getAddress();\n const nonce = await this.getNonce(client, sender);\n const isDeployed = await signer.isDeployed();\n const initCode = isDeployed ? \"0x\" : await signer.getInitCode();\n\n // Encode the call data for the smart account's execute function\n const callData = signer.encodeExecute(\n intent.to,\n intent.value ?? 0n,\n intent.data ?? \"0x\",\n );\n\n // Get gas prices from the chain\n const { maxFeePerGas, maxPriorityFeePerGas } = await this.getGasPrices(client);\n\n // Use provided gas estimate or defaults\n const gas = gasEstimate ?? DEFAULT_GAS_LIMITS;\n\n // Apply safety multiplier to gas limits\n const verificationGasLimit = this.applyMultiplier(gas.verificationGasLimit);\n const callGasLimit = this.applyMultiplier(gas.callGasLimit);\n const preVerificationGas = this.applyMultiplier(gas.preVerificationGas);\n\n // Build paymaster data if provided\n const paymasterAndData = paymaster\n ? this.encodePaymasterData(paymaster)\n : (\"0x\" as Hex);\n\n return {\n sender,\n nonce,\n initCode: initCode as Hex,\n callData,\n verificationGasLimit,\n callGasLimit,\n preVerificationGas,\n maxPriorityFeePerGas,\n maxFeePerGas,\n paymasterAndData,\n signature: \"0x\" as Hex, // Will be filled after signing\n };\n }\n\n /**\n * Build a batch UserOperation from multiple transaction intents\n */\n async buildBatchUserOp(\n signer: SmartAccountSigner,\n intents: TransactionIntent[],\n client: PublicClient,\n gasEstimate?: GasEstimate,\n paymaster?: PaymasterData,\n ): Promise<UserOperation> {\n const sender = await signer.getAddress();\n const nonce = await this.getNonce(client, sender);\n const isDeployed = await signer.isDeployed();\n const initCode = isDeployed ? \"0x\" : await signer.getInitCode();\n\n // Encode batch call data\n const targets = intents.map((i) => i.to);\n const values = intents.map((i) => i.value ?? 0n);\n const datas = intents.map((i) => (i.data ?? \"0x\") as Hex);\n const callData = signer.encodeExecuteBatch(targets, values, datas);\n\n // Get gas prices\n const { maxFeePerGas, maxPriorityFeePerGas } = await this.getGasPrices(client);\n\n // Use provided gas estimate or defaults (with higher limits for batch)\n const gas = gasEstimate ?? {\n verificationGasLimit: DEFAULT_GAS_LIMITS.verificationGasLimit,\n callGasLimit: DEFAULT_GAS_LIMITS.callGasLimit * BigInt(intents.length),\n preVerificationGas: DEFAULT_GAS_LIMITS.preVerificationGas,\n };\n\n const verificationGasLimit = this.applyMultiplier(gas.verificationGasLimit);\n const callGasLimit = this.applyMultiplier(gas.callGasLimit);\n const preVerificationGas = this.applyMultiplier(gas.preVerificationGas);\n\n const paymasterAndData = paymaster\n ? this.encodePaymasterData(paymaster)\n : (\"0x\" as Hex);\n\n return {\n sender,\n nonce,\n initCode: initCode as Hex,\n callData,\n verificationGasLimit,\n callGasLimit,\n preVerificationGas,\n maxPriorityFeePerGas,\n maxFeePerGas,\n paymasterAndData,\n signature: \"0x\" as Hex,\n };\n }\n\n /**\n * Pack a UserOperation for on-chain submission (v0.7 format)\n */\n packUserOp(userOp: UserOperation): PackedUserOperation {\n return {\n sender: userOp.sender,\n nonce: userOp.nonce,\n initCode: userOp.initCode,\n callData: userOp.callData,\n accountGasLimits: packAccountGasLimits(\n userOp.verificationGasLimit,\n userOp.callGasLimit,\n ),\n preVerificationGas: userOp.preVerificationGas,\n gasFees: packGasFees(userOp.maxPriorityFeePerGas, userOp.maxFeePerGas),\n paymasterAndData: userOp.paymasterAndData,\n signature: userOp.signature,\n };\n }\n\n /**\n * Compute the UserOperation hash for signing\n */\n async getUserOpHash(\n userOp: UserOperation,\n client: PublicClient,\n chainId: number,\n ): Promise<Hex> {\n const packed = this.packUserOp(userOp);\n\n // Convert to the tuple format expected by the ABI\n const userOpTuple = {\n sender: packed.sender,\n nonce: packed.nonce,\n initCode: packed.initCode,\n callData: packed.callData,\n accountGasLimits: packed.accountGasLimits as `0x${string}`,\n preVerificationGas: packed.preVerificationGas,\n gasFees: packed.gasFees as `0x${string}`,\n paymasterAndData: packed.paymasterAndData,\n signature: packed.signature,\n } as const;\n\n // Call EntryPoint's getUserOpHash\n const hash = await client.readContract({\n address: this.entryPoint,\n abi: ENTRYPOINT_V07_ABI,\n functionName: \"getUserOpHash\",\n args: [userOpTuple],\n });\n\n return hash as Hex;\n }\n\n /**\n * Sign a UserOperation\n */\n async signUserOp(\n userOp: UserOperation,\n signer: SmartAccountSigner,\n client: PublicClient,\n chainId: number,\n ): Promise<UserOperation> {\n const userOpHash = await this.getUserOpHash(userOp, client, chainId);\n const signature = await signer.signUserOpHash(userOpHash);\n\n return {\n ...userOp,\n signature,\n };\n }\n\n /**\n * Get the nonce for an account from EntryPoint\n */\n private async getNonce(client: PublicClient, sender: Address): Promise<bigint> {\n try {\n const nonce = await client.readContract({\n address: this.entryPoint,\n abi: ENTRYPOINT_V07_ABI,\n functionName: \"getNonce\",\n args: [sender, 0n], // Use key 0 for default nonce space\n });\n return nonce as bigint;\n } catch {\n // Account may not exist yet, return 0\n return 0n;\n }\n }\n\n /**\n * Get current gas prices from the chain\n */\n private async getGasPrices(\n client: PublicClient,\n ): Promise<{ maxFeePerGas: bigint; maxPriorityFeePerGas: bigint }> {\n const block = await client.getBlock({ blockTag: \"latest\" });\n const baseFee = block.baseFeePerGas ?? 0n;\n\n // Use EIP-1559 pricing\n const maxPriorityFeePerGas = 1_500_000_000n; // 1.5 gwei default tip\n const maxFeePerGas = baseFee * 2n + maxPriorityFeePerGas;\n\n return { maxFeePerGas, maxPriorityFeePerGas };\n }\n\n /**\n * Apply gas multiplier for safety margin\n */\n private applyMultiplier(gas: bigint): bigint {\n return BigInt(Math.ceil(Number(gas) * this.gasMultiplier));\n }\n\n /**\n * Encode paymaster data for the UserOperation\n */\n private encodePaymasterData(paymaster: PaymasterData): Hex {\n // Pack: paymaster (20 bytes) + verification gas (16 bytes) + postOp gas (16 bytes) + data\n const paymasterAddress = paymaster.paymaster;\n const verificationGas = pad(toHex(paymaster.paymasterVerificationGasLimit), {\n size: 16,\n });\n const postOpGas = pad(toHex(paymaster.paymasterPostOpGasLimit), { size: 16 });\n\n return concat([\n paymasterAddress,\n verificationGas,\n postOpGas,\n paymaster.paymasterData,\n ]) as Hex;\n }\n}\n\n/**\n * Create a UserOpBuilder instance\n */\nexport function createUserOpBuilder(\n options?: UserOpBuilderOptions,\n): UserOpBuilder {\n return new UserOpBuilder(options);\n}\n","/**\n * ERC-4337 Bundler Client\n *\n * Client for interacting with ERC-4337 bundlers via JSON-RPC.\n * Handles UserOperation submission, gas estimation, and receipt polling.\n */\n\nimport type { Address, Hex } from \"viem\";\nimport type {\n UserOperation,\n PackedUserOperation,\n GasEstimate,\n UserOperationReceipt,\n UserOperationResult,\n BundlerConfig,\n} from \"./types.js\";\nimport {\n ENTRYPOINT_V07_ADDRESS,\n BUNDLER_METHODS,\n packAccountGasLimits,\n packGasFees,\n} from \"./constants.js\";\n\n/**\n * JSON-RPC request structure\n */\ninterface JsonRpcRequest {\n jsonrpc: \"2.0\";\n id: number;\n method: string;\n params: unknown[];\n}\n\n/**\n * JSON-RPC response structure\n */\ninterface JsonRpcResponse<T = unknown> {\n jsonrpc: \"2.0\";\n id: number;\n result?: T;\n error?: {\n code: number;\n message: string;\n data?: unknown;\n };\n}\n\n/**\n * Bundler error class\n */\nexport class BundlerError extends Error {\n constructor(\n message: string,\n public code?: number,\n public data?: unknown,\n ) {\n super(message);\n this.name = \"BundlerError\";\n }\n}\n\n/**\n * Bundler client for submitting UserOperations\n */\nexport class BundlerClient {\n private readonly bundlerUrl: string;\n private readonly entryPoint: Address;\n private readonly chainId: number;\n private requestId: number = 0;\n\n constructor(config: BundlerConfig) {\n this.bundlerUrl = config.bundlerUrl;\n this.entryPoint = config.entryPoint ?? ENTRYPOINT_V07_ADDRESS;\n this.chainId = config.chainId;\n }\n\n /**\n * Send a UserOperation to the bundler\n */\n async sendUserOperation(userOp: UserOperation): Promise<UserOperationResult> {\n const packed = this.packForRpc(userOp);\n\n const userOpHash = await this.rpcCall<Hex>(\n BUNDLER_METHODS.sendUserOperation,\n [packed, this.entryPoint],\n );\n\n return {\n userOpHash,\n wait: () => this.waitForReceipt(userOpHash),\n };\n }\n\n /**\n * Estimate gas for a UserOperation\n */\n async estimateUserOperationGas(\n userOp: Partial<UserOperation> & {\n sender: Address;\n callData: Hex;\n },\n ): Promise<GasEstimate> {\n // Fill in defaults for estimation\n const estimationOp = {\n sender: userOp.sender,\n nonce: userOp.nonce ?? 0n,\n initCode: userOp.initCode ?? \"0x\",\n callData: userOp.callData,\n verificationGasLimit: userOp.verificationGasLimit ?? 1000000n,\n callGasLimit: userOp.callGasLimit ?? 1000000n,\n preVerificationGas: userOp.preVerificationGas ?? 100000n,\n maxPriorityFeePerGas: userOp.maxPriorityFeePerGas ?? 1000000000n,\n maxFeePerGas: userOp.maxFeePerGas ?? 10000000000n,\n paymasterAndData: userOp.paymasterAndData ?? \"0x\",\n signature:\n userOp.signature ??\n // Dummy signature for estimation\n \"0xfffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c\",\n };\n\n const packed = this.packForRpc(estimationOp as UserOperation);\n\n const result = await this.rpcCall<{\n verificationGasLimit: Hex;\n callGasLimit: Hex;\n preVerificationGas: Hex;\n paymasterVerificationGasLimit?: Hex;\n paymasterPostOpGasLimit?: Hex;\n }>(BUNDLER_METHODS.estimateUserOperationGas, [packed, this.entryPoint]);\n\n return {\n verificationGasLimit: BigInt(result.verificationGasLimit),\n callGasLimit: BigInt(result.callGasLimit),\n preVerificationGas: BigInt(result.preVerificationGas),\n paymasterVerificationGasLimit: result.paymasterVerificationGasLimit\n ? BigInt(result.paymasterVerificationGasLimit)\n : undefined,\n paymasterPostOpGasLimit: result.paymasterPostOpGasLimit\n ? BigInt(result.paymasterPostOpGasLimit)\n : undefined,\n };\n }\n\n /**\n * Get UserOperation by hash\n */\n async getUserOperationByHash(\n userOpHash: Hex,\n ): Promise<{ userOperation: PackedUserOperation; entryPoint: Address } | null> {\n const result = await this.rpcCall<{\n userOperation: PackedUserOperation;\n entryPoint: Address;\n } | null>(BUNDLER_METHODS.getUserOperationByHash, [userOpHash]);\n\n return result;\n }\n\n /**\n * Get UserOperation receipt\n */\n async getUserOperationReceipt(\n userOpHash: Hex,\n ): Promise<UserOperationReceipt | null> {\n const result = await this.rpcCall<{\n userOpHash: Hex;\n sender: Address;\n nonce: Hex;\n paymaster?: Address;\n actualGasCost: Hex;\n actualGasUsed: Hex;\n success: boolean;\n reason?: string;\n receipt: {\n transactionHash: Hex;\n blockNumber: Hex;\n blockHash: Hex;\n };\n } | null>(BUNDLER_METHODS.getUserOperationReceipt, [userOpHash]);\n\n if (!result) return null;\n\n return {\n userOpHash: result.userOpHash,\n sender: result.sender,\n nonce: BigInt(result.nonce),\n paymaster: result.paymaster,\n actualGasCost: BigInt(result.actualGasCost),\n actualGasUsed: BigInt(result.actualGasUsed),\n success: result.success,\n reason: result.reason,\n receipt: {\n transactionHash: result.receipt.transactionHash,\n blockNumber: BigInt(result.receipt.blockNumber),\n blockHash: result.receipt.blockHash,\n },\n };\n }\n\n /**\n * Get supported EntryPoints\n */\n async getSupportedEntryPoints(): Promise<Address[]> {\n return this.rpcCall<Address[]>(BUNDLER_METHODS.supportedEntryPoints, []);\n }\n\n /**\n * Get chain ID from bundler\n */\n async getChainId(): Promise<number> {\n const result = await this.rpcCall<Hex>(BUNDLER_METHODS.chainId, []);\n return Number(result);\n }\n\n /**\n * Wait for UserOperation receipt with polling\n */\n async waitForReceipt(\n userOpHash: Hex,\n options: { timeout?: number; pollingInterval?: number } = {},\n ): Promise<UserOperationReceipt> {\n const timeout = options.timeout ?? 60000; // 60 seconds default\n const pollingInterval = options.pollingInterval ?? 2000; // 2 seconds default\n\n const startTime = Date.now();\n\n while (Date.now() - startTime < timeout) {\n const receipt = await this.getUserOperationReceipt(userOpHash);\n\n if (receipt) {\n return receipt;\n }\n\n await new Promise((resolve) => setTimeout(resolve, pollingInterval));\n }\n\n throw new BundlerError(\n `Timeout waiting for UserOperation receipt: ${userOpHash}`,\n );\n }\n\n /**\n * Pack UserOperation for RPC (convert bigints to hex strings)\n */\n private packForRpc(userOp: UserOperation): Record<string, unknown> {\n return {\n sender: userOp.sender,\n nonce: this.toHex(userOp.nonce),\n initCode: userOp.initCode,\n callData: userOp.callData,\n accountGasLimits: packAccountGasLimits(\n userOp.verificationGasLimit,\n userOp.callGasLimit,\n ),\n preVerificationGas: this.toHex(userOp.preVerificationGas),\n gasFees: packGasFees(userOp.maxPriorityFeePerGas, userOp.maxFeePerGas),\n paymasterAndData: userOp.paymasterAndData,\n signature: userOp.signature,\n };\n }\n\n /**\n * Convert bigint to hex string\n */\n private toHex(value: bigint): Hex {\n return `0x${value.toString(16)}` as Hex;\n }\n\n /**\n * Make a JSON-RPC call to the bundler\n */\n private async rpcCall<T>(method: string, params: unknown[]): Promise<T> {\n const request: JsonRpcRequest = {\n jsonrpc: \"2.0\",\n id: ++this.requestId,\n method,\n params,\n };\n\n const response = await fetch(this.bundlerUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n throw new BundlerError(\n `HTTP error: ${response.status} ${response.statusText}`,\n );\n }\n\n const json = (await response.json()) as JsonRpcResponse<T>;\n\n if (json.error) {\n throw new BundlerError(json.error.message, json.error.code, json.error.data);\n }\n\n return json.result as T;\n }\n}\n\n/**\n * Create a BundlerClient instance\n */\nexport function createBundlerClient(config: BundlerConfig): BundlerClient {\n return new BundlerClient(config);\n}\n","/**\n * ERC-4337 Paymaster Client\n *\n * Handles paymaster interactions for gas sponsorship.\n * Supports verifying paymasters (off-chain signature) and\n * sponsoring paymasters (third-party gas payment).\n */\n\nimport type { Address, Hex } from \"viem\";\nimport { concat, pad, toHex, keccak256, encodeAbiParameters } from \"viem\";\nimport type {\n UserOperation,\n PaymasterData,\n PaymasterConfig,\n GasEstimate,\n} from \"./types.js\";\nimport { DEFAULT_GAS_LIMITS } from \"./constants.js\";\n\n/**\n * Paymaster service response\n */\nexport interface PaymasterResponse {\n /** Paymaster address */\n paymaster: Address;\n /** Paymaster data to include in UserOp */\n paymasterData: Hex;\n /** Gas limits for paymaster operations */\n paymasterVerificationGasLimit: bigint;\n paymasterPostOpGasLimit: bigint;\n}\n\n/**\n * Paymaster sponsor request\n */\nexport interface SponsorRequest {\n /** UserOperation to sponsor (without paymaster data) */\n userOp: Partial<UserOperation>;\n /** Chain ID */\n chainId: number;\n /** EntryPoint address */\n entryPoint: Address;\n /** Optional context for the paymaster */\n context?: Record<string, unknown>;\n}\n\n/**\n * Paymaster client for gas sponsorship\n */\nexport class PaymasterClient {\n private readonly config: PaymasterConfig;\n\n constructor(config: PaymasterConfig) {\n this.config = config;\n }\n\n /**\n * Get paymaster data for a UserOperation\n */\n async getPaymasterData(\n userOp: Partial<UserOperation>,\n chainId: number,\n entryPoint: Address,\n context?: Record<string, unknown>,\n ): Promise<PaymasterData> {\n switch (this.config.type) {\n case \"verifying\":\n return this.getVerifyingPaymasterData(userOp, chainId, entryPoint);\n case \"sponsoring\":\n return this.getSponsoringPaymasterData(\n userOp,\n chainId,\n entryPoint,\n context,\n );\n case \"token\":\n return this.getTokenPaymasterData(userOp, chainId, entryPoint);\n default:\n throw new Error(`Unknown paymaster type: ${this.config.type}`);\n }\n }\n\n /**\n * Get gas estimates including paymaster gas\n */\n async estimatePaymasterGas(\n userOp: Partial<UserOperation>,\n _chainId: number,\n ): Promise<GasEstimate> {\n // For most paymasters, use default gas limits\n // This can be overridden by calling the paymaster service\n return {\n verificationGasLimit: DEFAULT_GAS_LIMITS.verificationGasLimit,\n callGasLimit: DEFAULT_GAS_LIMITS.callGasLimit,\n preVerificationGas: DEFAULT_GAS_LIMITS.preVerificationGas,\n paymasterVerificationGasLimit:\n DEFAULT_GAS_LIMITS.paymasterVerificationGasLimit,\n paymasterPostOpGasLimit: DEFAULT_GAS_LIMITS.paymasterPostOpGasLimit,\n };\n }\n\n /**\n * Check if the paymaster will sponsor this operation\n */\n async willSponsor(\n userOp: Partial<UserOperation>,\n chainId: number,\n entryPoint: Address,\n context?: Record<string, unknown>,\n ): Promise<boolean> {\n if (!this.config.url) {\n // Local paymaster - always sponsors\n return true;\n }\n\n try {\n const response = await fetch(`${this.config.url}/check`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n userOp: this.serializeUserOp(userOp),\n chainId,\n entryPoint,\n context,\n }),\n });\n\n if (!response.ok) return false;\n\n const result = (await response.json()) as { willSponsor: boolean };\n return result.willSponsor;\n } catch {\n return false;\n }\n }\n\n /**\n * Get verifying paymaster data (off-chain signature)\n */\n private async getVerifyingPaymasterData(\n userOp: Partial<UserOperation>,\n chainId: number,\n entryPoint: Address,\n ): Promise<PaymasterData> {\n if (this.config.url) {\n // Call paymaster service for signature\n return this.callPaymasterService(userOp, chainId, entryPoint);\n }\n\n // Local verifying paymaster - return basic data\n // The signature would need to be added by the paymaster owner\n return {\n paymaster: this.config.address,\n paymasterVerificationGasLimit:\n DEFAULT_GAS_LIMITS.paymasterVerificationGasLimit,\n paymasterPostOpGasLimit: DEFAULT_GAS_LIMITS.paymasterPostOpGasLimit,\n paymasterData: \"0x\" as Hex,\n };\n }\n\n /**\n * Get sponsoring paymaster data (third-party pays)\n */\n private async getSponsoringPaymasterData(\n userOp: Partial<UserOperation>,\n chainId: number,\n entryPoint: Address,\n context?: Record<string, unknown>,\n ): Promise<PaymasterData> {\n if (!this.config.url) {\n throw new Error(\"Sponsoring paymaster requires a service URL\");\n }\n\n // Call the sponsor API\n const response = await fetch(`${this.config.url}/sponsor`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n userOp: this.serializeUserOp(userOp),\n chainId,\n entryPoint,\n context,\n }),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Paymaster rejected sponsorship: ${error}`);\n }\n\n const result = (await response.json()) as PaymasterResponse;\n\n return {\n paymaster: result.paymaster,\n paymasterVerificationGasLimit: result.paymasterVerificationGasLimit,\n paymasterPostOpGasLimit: result.paymasterPostOpGasLimit,\n paymasterData: result.paymasterData,\n };\n }\n\n /**\n * Get token paymaster data (pay gas with ERC20)\n */\n private async getTokenPaymasterData(\n userOp: Partial<UserOperation>,\n chainId: number,\n entryPoint: Address,\n ): Promise<PaymasterData> {\n const tokenAddress = this.config.options?.tokenAddress as Address | undefined;\n if (!tokenAddress) {\n throw new Error(\"Token paymaster requires tokenAddress in options\");\n }\n\n if (this.config.url) {\n // Call paymaster service for token rate and data\n return this.callPaymasterService(userOp, chainId, entryPoint, {\n tokenAddress,\n });\n }\n\n // Return basic token paymaster data\n // The actual rate and validation would be done on-chain\n return {\n paymaster: this.config.address,\n paymasterVerificationGasLimit:\n DEFAULT_GAS_LIMITS.paymasterVerificationGasLimit,\n paymasterPostOpGasLimit: DEFAULT_GAS_LIMITS.paymasterPostOpGasLimit,\n paymasterData: tokenAddress as Hex, // Token address as data\n };\n }\n\n /**\n * Call paymaster service API\n */\n private async callPaymasterService(\n userOp: Partial<UserOperation>,\n chainId: number,\n entryPoint: Address,\n context?: Record<string, unknown>,\n ): Promise<PaymasterData> {\n if (!this.config.url) {\n throw new Error(\"Paymaster service URL not configured\");\n }\n\n const response = await fetch(`${this.config.url}/getPaymasterData`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n userOp: this.serializeUserOp(userOp),\n chainId,\n entryPoint,\n context,\n }),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Paymaster service error: ${error}`);\n }\n\n const result = (await response.json()) as PaymasterResponse;\n\n return {\n paymaster: result.paymaster,\n paymasterVerificationGasLimit: BigInt(result.paymasterVerificationGasLimit),\n paymasterPostOpGasLimit: BigInt(result.paymasterPostOpGasLimit),\n paymasterData: result.paymasterData,\n };\n }\n\n /**\n * Serialize UserOperation for API calls\n */\n private serializeUserOp(\n userOp: Partial<UserOperation>,\n ): Record<string, string> {\n const result: Record<string, string> = {};\n\n if (userOp.sender) result.sender = userOp.sender;\n if (userOp.nonce !== undefined)\n result.nonce = `0x${userOp.nonce.toString(16)}`;\n if (userOp.initCode) result.initCode = userOp.initCode;\n if (userOp.callData) result.callData = userOp.callData;\n if (userOp.verificationGasLimit !== undefined)\n result.verificationGasLimit = `0x${userOp.verificationGasLimit.toString(16)}`;\n if (userOp.callGasLimit !== undefined)\n result.callGasLimit = `0x${userOp.callGasLimit.toString(16)}`;\n if (userOp.preVerificationGas !== undefined)\n result.preVerificationGas = `0x${userOp.preVerificationGas.toString(16)}`;\n if (userOp.maxPriorityFeePerGas !== undefined)\n result.maxPriorityFeePerGas = `0x${userOp.maxPriorityFeePerGas.toString(16)}`;\n if (userOp.maxFeePerGas !== undefined)\n result.maxFeePerGas = `0x${userOp.maxFeePerGas.toString(16)}`;\n if (userOp.paymasterAndData) result.paymasterAndData = userOp.paymasterAndData;\n if (userOp.signature) result.signature = userOp.signature;\n\n return result;\n }\n}\n\n/**\n * Create a PaymasterClient instance\n */\nexport function createPaymasterClient(config: PaymasterConfig): PaymasterClient {\n return new PaymasterClient(config);\n}\n\n/**\n * Encode paymaster data for inclusion in UserOperation\n */\nexport function encodePaymasterAndData(data: PaymasterData): Hex {\n return concat([\n data.paymaster,\n pad(toHex(data.paymasterVerificationGasLimit), { size: 16 }),\n pad(toHex(data.paymasterPostOpGasLimit), { size: 16 }),\n data.paymasterData,\n ]) as Hex;\n}\n\n/**\n * Decode paymaster and data from UserOperation\n */\nexport function decodePaymasterAndData(paymasterAndData: Hex): PaymasterData | null {\n if (paymasterAndData === \"0x\" || paymasterAndData.length < 86) {\n return null;\n }\n\n // 20 bytes address + 16 bytes verification gas + 16 bytes postOp gas = 52 bytes = 104 hex chars + 0x\n const paymaster = `0x${paymasterAndData.slice(2, 42)}` as Address;\n const paymasterVerificationGasLimit = BigInt(\n `0x${paymasterAndData.slice(42, 74)}`,\n );\n const paymasterPostOpGasLimit = BigInt(`0x${paymasterAndData.slice(74, 106)}`);\n const paymasterData = `0x${paymasterAndData.slice(106)}` as Hex;\n\n return {\n paymaster,\n paymasterVerificationGasLimit,\n paymasterPostOpGasLimit,\n paymasterData,\n };\n}\n","/**\n * Pimlico Paymaster Client\n *\n * Paymaster integration with Pimlico's sponsorship service.\n * Supports:\n * - Verifying paymaster with off-chain signatures\n * - ERC-20 token payments\n * - Spending policies and limits\n *\n * @see https://docs.pimlico.io/paymaster\n */\n\nimport type { Address, Hex } from \"viem\";\nimport { concat, pad, toHex } from \"viem\";\nimport type {\n UserOperation,\n PaymasterData,\n GasEstimate,\n} from \"../types.js\";\nimport { ENTRYPOINT_V07_ADDRESS, DEFAULT_GAS_LIMITS, packAccountGasLimits, packGasFees } from \"../constants.js\";\n\n/**\n * Pimlico paymaster type\n */\nexport type PimlicoPaymasterType = \"verifying\" | \"erc20\";\n\n/**\n * Pimlico sponsorship policy\n */\nexport interface PimlicoPolicy {\n /** Maximum gas cost per operation (in wei) */\n maxGasCost?: bigint;\n /** Maximum operations per user per day */\n maxOpsPerUser?: number;\n /** Allowed sender addresses */\n allowedSenders?: Address[];\n /** Allowed target contracts */\n allowedTargets?: Address[];\n}\n\n/**\n * Pimlico paymaster configuration\n */\nexport interface PimlicoPaymasterConfig {\n /** Pimlico API key */\n apiKey: string;\n /** Chain ID */\n chainId: number;\n /** Paymaster type */\n type?: PimlicoPaymasterType;\n /** Token address for ERC-20 paymaster */\n tokenAddress?: Address;\n /** Sponsorship policy */\n policy?: PimlicoPolicy;\n /** Custom paymaster URL (optional) */\n paymasterUrl?: string;\n}\n\n/**\n * Pimlico sponsor result\n */\nexport interface PimlicoSponsorResult {\n /** Paymaster address */\n paymaster: Address;\n /** Packed paymaster data for UserOp */\n paymasterAndData: Hex;\n /** Gas estimates */\n callGasLimit: bigint;\n verificationGasLimit: bigint;\n preVerificationGas: bigint;\n paymasterVerificationGasLimit: bigint;\n paymasterPostOpGasLimit: bigint;\n}\n\n/**\n * Pimlico paymaster client\n */\nexport class PimlicoPaymaster {\n private readonly apiKey: string;\n private readonly chainId: number;\n private readonly paymasterUrl: string;\n private readonly type: PimlicoPaymasterType;\n private readonly tokenAddress?: Address;\n private readonly policy?: PimlicoPolicy;\n\n constructor(config: PimlicoPaymasterConfig) {\n this.apiKey = config.apiKey;\n this.chainId = config.chainId;\n this.type = config.type ?? \"verifying\";\n this.tokenAddress = config.tokenAddress;\n this.policy = config.policy;\n this.paymasterUrl = config.paymasterUrl ??\n `https://api.pimlico.io/v2/${config.chainId}/rpc?apikey=${config.apiKey}`;\n }\n\n /**\n * Sponsor a UserOperation\n * Returns paymaster data to include in the UserOp\n */\n async sponsorUserOperation(\n userOp: Partial<UserOperation> & {\n sender: Address;\n callData: Hex;\n },\n options?: {\n /** Override gas limits */\n gasOverrides?: Partial<GasEstimate>;\n },\n ): Promise<PimlicoSponsorResult> {\n const packed = this.packUserOpForSponsorship(userOp);\n\n const params: Record<string, unknown> = {\n entryPoint: ENTRYPOINT_V07_ADDRESS,\n userOperation: packed,\n };\n\n if (this.type === \"erc20\" && this.tokenAddress) {\n params.sponsorshipPolicyId = this.tokenAddress;\n }\n\n const result = await this.rpcCall<{\n paymasterAndData: Hex;\n callGasLimit: Hex;\n verificationGasLimit: Hex;\n preVerificationGas: Hex;\n }>(\"pm_sponsorUserOperation\", [params]);\n\n // Parse paymaster address and gas limits from paymasterAndData\n const paymaster = `0x${result.paymasterAndData.slice(2, 42)}` as Address;\n const paymasterVerificationGasLimit = BigInt(`0x${result.paymasterAndData.slice(42, 74)}`);\n const paymasterPostOpGasLimit = BigInt(`0x${result.paymasterAndData.slice(74, 106)}`);\n\n return {\n paymaster,\n paymasterAndData: result.paymasterAndData,\n callGasLimit: options?.gasOverrides?.callGasLimit ?? BigInt(result.callGasLimit),\n verificationGasLimit: options?.gasOverrides?.verificationGasLimit ?? BigInt(result.verificationGasLimit),\n preVerificationGas: options?.gasOverrides?.preVerificationGas ?? BigInt(result.preVerificationGas),\n paymasterVerificationGasLimit,\n paymasterPostOpGasLimit,\n };\n }\n\n /**\n * Get paymaster data without gas estimation\n * Useful when gas is already estimated\n */\n async getPaymasterData(\n userOp: UserOperation,\n ): Promise<PaymasterData> {\n const result = await this.sponsorUserOperation(userOp);\n\n return {\n paymaster: result.paymaster,\n paymasterVerificationGasLimit: result.paymasterVerificationGasLimit,\n paymasterPostOpGasLimit: result.paymasterPostOpGasLimit,\n paymasterData: `0x${result.paymasterAndData.slice(106)}` as Hex,\n };\n }\n\n /**\n * Check if an operation would be sponsored\n */\n async willSponsor(\n userOp: Partial<UserOperation> & {\n sender: Address;\n callData: Hex;\n },\n ): Promise<{ sponsored: boolean; reason?: string }> {\n try {\n await this.sponsorUserOperation(userOp);\n return { sponsored: true };\n } catch (error) {\n return {\n sponsored: false,\n reason: error instanceof Error ? error.message : \"Unknown error\",\n };\n }\n }\n\n /**\n * Get token quotes for ERC-20 paymaster\n */\n async getTokenQuotes(\n userOp: Partial<UserOperation> & {\n sender: Address;\n callData: Hex;\n },\n tokens: Address[],\n ): Promise<Array<{\n token: Address;\n maxCost: bigint;\n symbol: string;\n decimals: number;\n }>> {\n if (this.type !== \"erc20\") {\n throw new Error(\"Token quotes only available for ERC-20 paymaster\");\n }\n\n const packed = this.packUserOpForSponsorship(userOp);\n\n const result = await this.rpcCall<Array<{\n token: Address;\n maxCost: Hex;\n symbol: string;\n decimals: number;\n }>>(\"pm_getTokenQuotes\", [\n {\n entryPoint: ENTRYPOINT_V07_ADDRESS,\n userOperation: packed,\n tokens,\n },\n ]);\n\n return result.map((quote) => ({\n token: quote.token,\n maxCost: BigInt(quote.maxCost),\n symbol: quote.symbol,\n decimals: quote.decimals,\n }));\n }\n\n /**\n * Pack UserOp for sponsorship request\n */\n private packUserOpForSponsorship(\n userOp: Partial<UserOperation> & { sender: Address; callData: Hex },\n ): Record<string, unknown> {\n return {\n sender: userOp.sender,\n nonce: this.toHex(userOp.nonce ?? 0n),\n initCode: userOp.initCode ?? \"0x\",\n callData: userOp.callData,\n accountGasLimits: userOp.verificationGasLimit && userOp.callGasLimit\n ? packAccountGasLimits(userOp.verificationGasLimit, userOp.callGasLimit)\n : packAccountGasLimits(DEFAULT_GAS_LIMITS.verificationGasLimit, DEFAULT_GAS_LIMITS.callGasLimit),\n preVerificationGas: this.toHex(userOp.preVerificationGas ?? DEFAULT_GAS_LIMITS.preVerificationGas),\n gasFees: userOp.maxPriorityFeePerGas && userOp.maxFeePerGas\n ? packGasFees(userOp.maxPriorityFeePerGas, userOp.maxFeePerGas)\n : packGasFees(1000000000n, 10000000000n),\n paymasterAndData: \"0x\",\n signature: userOp.signature ?? getDummySignature(),\n };\n }\n\n /**\n * Convert bigint to hex\n */\n private toHex(value: bigint): Hex {\n return `0x${value.toString(16)}` as Hex;\n }\n\n /**\n * Make RPC call to Pimlico\n */\n private async rpcCall<T>(method: string, params: unknown[]): Promise<T> {\n const response = await fetch(this.paymasterUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: Date.now(),\n method,\n params,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error: ${response.status} ${response.statusText}`);\n }\n\n const json = await response.json() as {\n result?: T;\n error?: { code: number; message: string; data?: unknown };\n };\n\n if (json.error) {\n throw new Error(json.error.message);\n }\n\n return json.result as T;\n }\n}\n\n/**\n * Get dummy signature for sponsorship requests\n */\nfunction getDummySignature(): Hex {\n return \"0xfffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c\" as Hex;\n}\n\n/**\n * Encode paymaster and data for UserOperation\n */\nexport function encodePaymasterAndData(data: PaymasterData): Hex {\n return concat([\n data.paymaster,\n pad(toHex(data.paymasterVerificationGasLimit), { size: 16 }),\n pad(toHex(data.paymasterPostOpGasLimit), { size: 16 }),\n data.paymasterData,\n ]) as Hex;\n}\n\n/**\n * Create a Pimlico paymaster client\n */\nexport function createPimlicoPaymaster(config: PimlicoPaymasterConfig): PimlicoPaymaster {\n return new PimlicoPaymaster(config);\n}\n","/**\n * Safe Smart Account for ERC-4337\n *\n * Implements SmartAccountSigner using Safe's 4337 module.\n * Supports:\n * - Single-owner and multi-sig configurations\n * - Counterfactual address computation\n * - Safe 4337 module v0.3.0\n *\n * @see https://docs.safe.global/advanced/erc-4337\n */\n\nimport type { Address, Hex, PublicClient, WalletClient } from \"viem\";\nimport {\n encodeFunctionData,\n encodeAbiParameters,\n concat,\n pad,\n toHex,\n keccak256,\n getContractAddress,\n hexToBytes,\n} from \"viem\";\nimport type { SmartAccountSigner } from \"../types.js\";\n\n/**\n * Safe 4337 module addresses (v0.3.0)\n * Deployed on all major EVM chains at the same addresses\n */\nexport const SAFE_4337_ADDRESSES = {\n /** Safe 4337 Module */\n module: \"0xa581c4A4DB7175302464fF3C06380BC3270b4037\" as Address,\n /** Safe Module Setup */\n moduleSetup: \"0x2dd68b007B46fBe91B9A7c3EDa5A7a1063cB5b47\" as Address,\n /** Safe Singleton */\n singleton: \"0x29fcB43b46531BcA003ddC8FCB67FFE91900C762\" as Address,\n /** Safe Proxy Factory */\n proxyFactory: \"0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67\" as Address,\n /** Safe Fallback Handler */\n fallbackHandler: \"0xfd0732Dc9E303f09fCEf3a7388Ad10A83459Ec99\" as Address,\n /** Add Modules Lib */\n addModulesLib: \"0x8EcD4ec46D4D2a6B64fE960B3D64e8B94B2234eb\" as Address,\n} as const;\n\n/**\n * Safe Proxy Factory ABI (essential functions)\n */\nconst PROXY_FACTORY_ABI = [\n {\n inputs: [\n { name: \"singleton\", type: \"address\" },\n { name: \"initializer\", type: \"bytes\" },\n { name: \"saltNonce\", type: \"uint256\" },\n ],\n name: \"createProxyWithNonce\",\n outputs: [{ name: \"proxy\", type: \"address\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"singleton\", type: \"address\" },\n { name: \"initializer\", type: \"bytes\" },\n { name: \"saltNonce\", type: \"uint256\" },\n ],\n name: \"proxyCreationCode\",\n outputs: [{ name: \"\", type: \"bytes\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const;\n\n/**\n * Safe Singleton ABI (essential functions)\n */\nconst SAFE_ABI = [\n {\n inputs: [\n { name: \"owners\", type: \"address[]\" },\n { name: \"threshold\", type: \"uint256\" },\n { name: \"to\", type: \"address\" },\n { name: \"data\", type: \"bytes\" },\n { name: \"fallbackHandler\", type: \"address\" },\n { name: \"paymentToken\", type: \"address\" },\n { name: \"payment\", type: \"uint256\" },\n { name: \"paymentReceiver\", type: \"address\" },\n ],\n name: \"setup\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"data\", type: \"bytes\" },\n { name: \"operation\", type: \"uint8\" },\n ],\n name: \"execTransactionFromModule\",\n outputs: [{ name: \"success\", type: \"bool\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n\n/**\n * Add Modules Lib ABI\n */\nconst ADD_MODULES_LIB_ABI = [\n {\n inputs: [{ name: \"modules\", type: \"address[]\" }],\n name: \"enableModules\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n\n/**\n * Safe 4337 Module ABI\n */\nconst SAFE_4337_MODULE_ABI = [\n {\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"data\", type: \"bytes\" },\n { name: \"operation\", type: \"uint8\" },\n ],\n name: \"executeUserOp\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"tos\", type: \"address[]\" },\n { name: \"values\", type: \"uint256[]\" },\n { name: \"datas\", type: \"bytes[]\" },\n { name: \"operations\", type: \"uint8[]\" },\n ],\n name: \"executeUserOpBatch\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n\n/**\n * Safe smart account configuration\n */\nexport interface SafeSmartAccountConfig {\n /** Wallet client for signing */\n signer: WalletClient;\n /** Public client for reading chain state */\n publicClient: PublicClient;\n /** Chain ID */\n chainId: number;\n /** Owner addresses (for multi-sig, defaults to signer address) */\n owners?: Address[];\n /** Threshold for multi-sig (defaults to 1) */\n threshold?: number;\n /** Salt nonce for address generation */\n saltNonce?: bigint;\n /** Custom Safe addresses (optional) */\n addresses?: Partial<typeof SAFE_4337_ADDRESSES>;\n}\n\n/**\n * Safe smart account implementing SmartAccountSigner\n */\nexport class SafeSmartAccount implements SmartAccountSigner {\n private readonly signer: WalletClient;\n private readonly publicClient: PublicClient;\n private readonly chainId: number;\n private readonly owners: Address[];\n private readonly threshold: number;\n private readonly saltNonce: bigint;\n private readonly addresses: typeof SAFE_4337_ADDRESSES;\n\n private cachedAddress?: Address;\n private cachedInitCode?: Hex;\n private deploymentChecked = false;\n private isAccountDeployed = false;\n\n constructor(config: SafeSmartAccountConfig) {\n this.signer = config.signer;\n this.publicClient = config.publicClient;\n this.chainId = config.chainId;\n this.threshold = config.threshold ?? 1;\n this.saltNonce = config.saltNonce ?? 0n;\n this.addresses = {\n ...SAFE_4337_ADDRESSES,\n ...config.addresses,\n };\n\n // Default to signer address if no owners provided\n if (config.owners && config.owners.length > 0) {\n this.owners = config.owners;\n } else if (config.signer.account?.address) {\n this.owners = [config.signer.account.address];\n } else {\n throw new Error(\"Either owners or signer with account must be provided\");\n }\n\n if (this.threshold > this.owners.length) {\n throw new Error(\"Threshold cannot be greater than number of owners\");\n }\n }\n\n /**\n * Get the smart account address (counterfactual)\n */\n async getAddress(): Promise<Address> {\n if (this.cachedAddress) {\n return this.cachedAddress;\n }\n\n const initCode = await this.getInitCode();\n\n // Extract initializer from init code\n const initializerData = `0x${initCode.slice(2 + 40 * 2)}` as Hex;\n\n // Compute counterfactual address\n const salt = keccak256(\n encodeAbiParameters(\n [{ type: \"bytes32\" }, { type: \"uint256\" }],\n [keccak256(initializerData), this.saltNonce],\n ),\n );\n\n // Get proxy creation code\n const proxyCreationCode = await this.publicClient.readContract({\n address: this.addresses.proxyFactory,\n abi: PROXY_FACTORY_ABI,\n functionName: \"proxyCreationCode\",\n args: [this.addresses.singleton, initializerData, this.saltNonce],\n }) as Hex;\n\n // Compute CREATE2 address\n this.cachedAddress = getContractAddress({\n bytecode: proxyCreationCode,\n from: this.addresses.proxyFactory,\n opcode: \"CREATE2\",\n salt,\n });\n\n return this.cachedAddress;\n }\n\n /**\n * Sign a UserOperation hash\n */\n async signUserOpHash(userOpHash: Hex): Promise<Hex> {\n if (!this.signer.account) {\n throw new Error(\"Signer account not available\");\n }\n\n // Sign the hash with EIP-712 formatted signature for Safe\n const signature = await this.signer.signMessage({\n account: this.signer.account,\n message: { raw: hexToBytes(userOpHash) },\n });\n\n // Format signature for Safe (add signature type byte)\n // Type 0: EOA signature (most common)\n return concat([signature, \"0x00\"]) as Hex;\n }\n\n /**\n * Get the account's init code for deployment\n */\n async getInitCode(): Promise<Hex> {\n // Check if already deployed\n if (await this.isDeployed()) {\n return \"0x\" as Hex;\n }\n\n if (this.cachedInitCode) {\n return this.cachedInitCode;\n }\n\n // Build Safe setup data with 4337 module\n const setupModulesData = encodeFunctionData({\n abi: ADD_MODULES_LIB_ABI,\n functionName: \"enableModules\",\n args: [[this.addresses.module]],\n });\n\n const safeSetupData = encodeFunctionData({\n abi: SAFE_ABI,\n functionName: \"setup\",\n args: [\n this.owners,\n BigInt(this.threshold),\n this.addresses.addModulesLib, // to: AddModulesLib\n setupModulesData, // data: enableModules([module])\n this.addresses.fallbackHandler,\n \"0x0000000000000000000000000000000000000000\" as Address, // paymentToken\n 0n, // payment\n \"0x0000000000000000000000000000000000000000\" as Address, // paymentReceiver\n ],\n });\n\n // Build factory call data\n const createProxyData = encodeFunctionData({\n abi: PROXY_FACTORY_ABI,\n functionName: \"createProxyWithNonce\",\n args: [this.addresses.singleton, safeSetupData, this.saltNonce],\n });\n\n // Init code = factory address + factory call data\n this.cachedInitCode = concat([\n this.addresses.proxyFactory,\n createProxyData,\n ]) as Hex;\n\n return this.cachedInitCode;\n }\n\n /**\n * Check if the account is deployed\n */\n async isDeployed(): Promise<boolean> {\n if (this.deploymentChecked) {\n return this.isAccountDeployed;\n }\n\n const address = this.cachedAddress ?? await this.getAddress();\n const code = await this.publicClient.getCode({ address });\n\n this.deploymentChecked = true;\n this.isAccountDeployed = code !== undefined && code !== \"0x\";\n\n return this.isAccountDeployed;\n }\n\n /**\n * Encode a call to the account's execute function\n */\n encodeExecute(target: Address, value: bigint, data: Hex): Hex {\n return encodeFunctionData({\n abi: SAFE_4337_MODULE_ABI,\n functionName: \"executeUserOp\",\n args: [\n target,\n value,\n data,\n 0, // operation: CALL\n ],\n });\n }\n\n /**\n * Encode a batch call to the account's executeBatch function\n */\n encodeExecuteBatch(\n targets: Address[],\n values: bigint[],\n datas: Hex[],\n ): Hex {\n if (targets.length !== values.length || targets.length !== datas.length) {\n throw new Error(\"Array lengths must match\");\n }\n\n const operations = targets.map(() => 0); // All CALL operations\n\n return encodeFunctionData({\n abi: SAFE_4337_MODULE_ABI,\n functionName: \"executeUserOpBatch\",\n args: [targets, values, datas, operations],\n });\n }\n\n /**\n * Get the counterfactual address without caching\n */\n async getCounterfactualAddress(): Promise<Address> {\n return this.getAddress();\n }\n\n /**\n * Get the account's nonce from EntryPoint\n */\n async getNonce(entryPoint: Address, key = 0n): Promise<bigint> {\n const address = await this.getAddress();\n\n const nonce = await this.publicClient.readContract({\n address: entryPoint,\n abi: [\n {\n inputs: [\n { name: \"sender\", type: \"address\" },\n { name: \"key\", type: \"uint192\" },\n ],\n name: \"getNonce\",\n outputs: [{ name: \"nonce\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n ],\n functionName: \"getNonce\",\n args: [address, key],\n });\n\n return nonce as bigint;\n }\n\n /**\n * Get the Safe's owners\n */\n getOwners(): Address[] {\n return [...this.owners];\n }\n\n /**\n * Get the Safe's threshold\n */\n getThreshold(): number {\n return this.threshold;\n }\n\n /**\n * Clear cached values (useful after deployment)\n */\n clearCache(): void {\n this.cachedAddress = undefined;\n this.cachedInitCode = undefined;\n this.deploymentChecked = false;\n this.isAccountDeployed = false;\n }\n}\n\n/**\n * Create a Safe smart account\n */\nexport function createSafeSmartAccount(\n config: SafeSmartAccountConfig,\n): SafeSmartAccount {\n return new SafeSmartAccount(config);\n}\n","/**\n * ERC-4337 T402 Integration\n *\n * Integrates ERC-4337 Account Abstraction with T402 payment protocol.\n * Enables gasless payment execution via smart accounts and paymasters.\n */\n\nimport type { Address, Hex, PublicClient } from \"viem\";\nimport { encodeFunctionData } from \"viem\";\nimport type {\n UserOperation,\n SmartAccountSigner,\n TransactionIntent,\n PaymasterConfig,\n BundlerConfig,\n UserOperationResult,\n GasEstimate,\n} from \"./types.js\";\nimport { UserOpBuilder } from \"./builder.js\";\nimport { BundlerClient } from \"./bundler.js\";\nimport { PaymasterClient } from \"./paymaster.js\";\nimport { ENTRYPOINT_V07_ADDRESS } from \"./constants.js\";\n\n/**\n * T402 payment parameters for ERC-4337\n */\nexport interface GaslessPaymentParams {\n /** Token contract address */\n tokenAddress: Address;\n /** Recipient address (resource server/facilitator) */\n to: Address;\n /** Amount to transfer */\n amount: bigint;\n /** Optional: Pre-signed authorization (for EIP-3009 tokens) */\n authorization?: {\n validAfter: bigint;\n validBefore: bigint;\n nonce: Hex;\n signature: Hex;\n };\n}\n\n/**\n * Gasless T402 client configuration\n */\nexport interface GaslessClientConfig {\n /** Smart account signer */\n signer: SmartAccountSigner;\n /** Bundler configuration */\n bundler: BundlerConfig;\n /** Optional paymaster for gas sponsorship */\n paymaster?: PaymasterConfig;\n /** Chain ID */\n chainId: number;\n /** Public client for chain interactions */\n publicClient: PublicClient;\n}\n\n/**\n * ERC20 transfer ABI for building call data\n */\nconst ERC20_TRANSFER_ABI = [\n {\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n name: \"transfer\",\n outputs: [{ name: \"\", type: \"bool\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n\n/**\n * EIP-3009 transferWithAuthorization ABI\n */\nconst EIP3009_TRANSFER_ABI = [\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] as const;\n\n/**\n * Gasless T402 client for executing payments via ERC-4337\n */\nexport class GaslessT402Client {\n private readonly signer: SmartAccountSigner;\n private readonly builder: UserOpBuilder;\n private readonly bundler: BundlerClient;\n private readonly paymaster?: PaymasterClient;\n private readonly chainId: number;\n private readonly publicClient: PublicClient;\n\n constructor(config: GaslessClientConfig) {\n this.signer = config.signer;\n this.builder = new UserOpBuilder();\n this.bundler = new BundlerClient(config.bundler);\n this.paymaster = config.paymaster\n ? new PaymasterClient(config.paymaster)\n : undefined;\n this.chainId = config.chainId;\n this.publicClient = config.publicClient;\n }\n\n /**\n * Execute a T402 payment via ERC-4337\n *\n * This submits the payment as a UserOperation which can be:\n * - Sponsored by a paymaster (truly gasless)\n * - Paid from the smart account's balance\n */\n async executePayment(\n params: GaslessPaymentParams,\n ): Promise<UserOperationResult> {\n // Build the call data based on whether we have an authorization\n const callData = params.authorization\n ? this.buildAuthorizedTransferCallData(params)\n : this.buildTransferCallData(params);\n\n // Create the transaction intent\n const intent: TransactionIntent = {\n to: params.tokenAddress,\n value: 0n,\n data: callData,\n };\n\n // Estimate gas\n const gasEstimate = await this.estimateGas(intent);\n\n // Get paymaster data if configured\n const paymasterData = await this.getPaymasterData(gasEstimate);\n\n // Build the UserOperation\n const userOp = await this.builder.buildUserOp(\n this.signer,\n intent,\n this.publicClient,\n gasEstimate,\n paymasterData,\n );\n\n // Sign the UserOperation\n const signedUserOp = await this.builder.signUserOp(\n userOp,\n this.signer,\n this.publicClient,\n this.chainId,\n );\n\n // Submit to bundler\n return this.bundler.sendUserOperation(signedUserOp);\n }\n\n /**\n * Execute multiple T402 payments in a single UserOperation\n */\n async executeBatchPayments(\n payments: GaslessPaymentParams[],\n ): Promise<UserOperationResult> {\n // Build transaction intents for all payments\n const intents: TransactionIntent[] = payments.map((params) => ({\n to: params.tokenAddress,\n value: 0n,\n data: params.authorization\n ? this.buildAuthorizedTransferCallData(params)\n : this.buildTransferCallData(params),\n }));\n\n // Estimate gas for batch\n const gasEstimate = await this.estimateBatchGas(intents);\n\n // Get paymaster data\n const paymasterData = await this.getPaymasterData(gasEstimate);\n\n // Build batch UserOperation\n const userOp = await this.builder.buildBatchUserOp(\n this.signer,\n intents,\n this.publicClient,\n gasEstimate,\n paymasterData,\n );\n\n // Sign and submit\n const signedUserOp = await this.builder.signUserOp(\n userOp,\n this.signer,\n this.publicClient,\n this.chainId,\n );\n\n return this.bundler.sendUserOperation(signedUserOp);\n }\n\n /**\n * Check if a payment can be sponsored (gasless)\n */\n async canSponsor(params: GaslessPaymentParams): Promise<boolean> {\n if (!this.paymaster) return false;\n\n const intent: TransactionIntent = {\n to: params.tokenAddress,\n value: 0n,\n data: this.buildTransferCallData(params),\n };\n\n const sender = await this.signer.getAddress();\n\n return this.paymaster.willSponsor(\n { sender, callData: this.signer.encodeExecute(intent.to, 0n, intent.data!) },\n this.chainId,\n ENTRYPOINT_V07_ADDRESS,\n );\n }\n\n /**\n * Get the smart account address\n */\n async getAccountAddress(): Promise<Address> {\n return this.signer.getAddress();\n }\n\n /**\n * Check if the smart account is deployed\n */\n async isAccountDeployed(): Promise<boolean> {\n return this.signer.isDeployed();\n }\n\n /**\n * Build call data for a simple ERC20 transfer\n */\n private buildTransferCallData(params: GaslessPaymentParams): Hex {\n return encodeFunctionData({\n abi: ERC20_TRANSFER_ABI,\n functionName: \"transfer\",\n args: [params.to, params.amount],\n });\n }\n\n /**\n * Build call data for an authorized transfer (EIP-3009)\n */\n private buildAuthorizedTransferCallData(params: GaslessPaymentParams): Hex {\n if (!params.authorization) {\n throw new Error(\"Authorization required for authorized transfer\");\n }\n\n // Parse the signature\n const sig = params.authorization.signature;\n const r = `0x${sig.slice(2, 66)}` as Hex;\n const s = `0x${sig.slice(66, 130)}` as Hex;\n const v = parseInt(sig.slice(130, 132), 16);\n\n return encodeFunctionData({\n abi: EIP3009_TRANSFER_ABI,\n functionName: \"transferWithAuthorization\",\n args: [\n params.to, // from (will be overwritten by smart account)\n params.to,\n params.amount,\n params.authorization.validAfter,\n params.authorization.validBefore,\n params.authorization.nonce,\n v,\n r,\n s,\n ],\n });\n }\n\n /**\n * Estimate gas for a single transaction\n */\n private async estimateGas(intent: TransactionIntent): Promise<GasEstimate> {\n const sender = await this.signer.getAddress();\n const callData = this.signer.encodeExecute(\n intent.to,\n intent.value ?? 0n,\n intent.data ?? \"0x\",\n );\n\n try {\n return await this.bundler.estimateUserOperationGas({\n sender,\n callData,\n });\n } catch {\n // Return defaults if estimation fails\n return {\n verificationGasLimit: 150000n,\n callGasLimit: 100000n,\n preVerificationGas: 50000n,\n };\n }\n }\n\n /**\n * Estimate gas for a batch transaction\n */\n private async estimateBatchGas(\n intents: TransactionIntent[],\n ): Promise<GasEstimate> {\n const sender = await this.signer.getAddress();\n const callData = this.signer.encodeExecuteBatch(\n intents.map((i) => i.to),\n intents.map((i) => i.value ?? 0n),\n intents.map((i) => (i.data ?? \"0x\") as Hex),\n );\n\n try {\n return await this.bundler.estimateUserOperationGas({\n sender,\n callData,\n });\n } catch {\n // Return defaults with multiplier for batch size\n return {\n verificationGasLimit: 150000n,\n callGasLimit: 100000n * BigInt(intents.length),\n preVerificationGas: 50000n,\n };\n }\n }\n\n /**\n * Get paymaster data if configured\n */\n private async getPaymasterData(\n _gasEstimate: GasEstimate,\n ): Promise<\n | {\n paymaster: Address;\n paymasterVerificationGasLimit: bigint;\n paymasterPostOpGasLimit: bigint;\n paymasterData: Hex;\n }\n | undefined\n > {\n if (!this.paymaster) return undefined;\n\n const sender = await this.signer.getAddress();\n\n return this.paymaster.getPaymasterData(\n { sender },\n this.chainId,\n ENTRYPOINT_V07_ADDRESS,\n );\n }\n}\n\n/**\n * Create a GaslessT402Client instance\n */\nexport function createGaslessT402Client(\n config: GaslessClientConfig,\n): GaslessT402Client {\n return new GaslessT402Client(config);\n}\n"],"mappings":"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","names":["ExactLegacyEvmScheme","getAddress","ExactLegacyEvmScheme","getAddress","PaymasterType","concat","pad","toHex","concat","pad","toHex","concat","pad","toHex","encodeFunctionData","encodeAbiParameters","concat","keccak256","encodeFunctionData","encodeFunctionData"]}
1
+ {"version":3,"sources":["../../src/index.ts","../../src/exact-legacy/client/scheme.ts","../../src/exact-legacy/server/scheme.ts","../../src/exact-legacy/facilitator/scheme.ts","../../src/bridge/client.ts","../../src/bridge/constants.ts","../../src/bridge/scan.ts","../../src/bridge/router.ts","../../src/erc4337/constants.ts","../../src/erc4337/builder.ts","../../src/erc4337/bundler.ts","../../src/erc4337/paymaster.ts","../../src/erc4337/paymasters/pimlico.ts","../../src/erc4337/accounts/safe.ts","../../src/erc4337/t402.ts"],"sourcesContent":["/**\n * @module @t402/evm - t402 Payment Protocol EVM Implementation\n *\n * This module provides the EVM-specific implementation of the t402 payment protocol.\n * Supports USDT0, USDC, and other EIP-3009 compatible tokens.\n *\n * Schemes:\n * - exact: EIP-3009 transferWithAuthorization (gasless, recommended)\n * - exact-legacy: approve + transferFrom (legacy tokens like USDT)\n * - upto: EIP-2612 permit for usage-based billing\n *\n * For types-only usage without viem, use @t402/evm-core instead.\n */\n\n// Re-export everything from @t402/evm-core\n// This allows users to get all types from @t402/evm while @t402/evm-core\n// provides the same types without bundling viem\nexport * from \"@t402/evm-core\";\n\n// Export EVM implementation modules (viem-dependent)\nexport { ExactEvmScheme } from \"./exact/index.js\";\nexport type { ExactEvmSchemeConfig } from \"./exact/server/scheme.js\";\n\n// Export exact-legacy scheme for legacy tokens\nexport {\n ExactLegacyEvmClientScheme,\n ExactLegacyEvmServerScheme,\n ExactLegacyEvmFacilitatorScheme,\n} from \"./exact-legacy/index.js\";\nexport type {\n ExactLegacyEvmServerSchemeConfig,\n ExactLegacyEvmFacilitatorSchemeConfig,\n} from \"./exact-legacy/index.js\";\n\n// Export Up-To scheme\nexport {\n // Client\n UptoEvmScheme,\n createUptoEvmScheme,\n // Server\n UptoEvmServerScheme,\n createUptoEvmServerScheme,\n // Facilitator\n UptoEvmFacilitatorScheme,\n createUptoEvmFacilitatorScheme,\n} from \"./upto/index.js\";\nexport type { UptoEvmServerSchemeConfig, UptoEvmFacilitatorSchemeConfig } from \"./upto/index.js\";\n\n// Export USDT0 bridge module\nexport {\n // Bridge client\n Usdt0Bridge,\n createUsdt0Bridge,\n // LayerZero Scan client\n LayerZeroScanClient,\n createLayerZeroScanClient,\n LAYERZERO_SCAN_BASE_URL,\n // Cross-chain payment router\n CrossChainPaymentRouter,\n createCrossChainPaymentRouter,\n // Bridge constants\n LAYERZERO_ENDPOINT_IDS,\n USDT0_OFT_ADDRESSES,\n LAYERZERO_ENDPOINT_V2,\n getEndpointId,\n getUsdt0OftAddress,\n supportsBridging,\n getBridgeableChains,\n addressToBytes32,\n bytes32ToAddress,\n} from \"./bridge/index.js\";\n\n// Export bridge types\nexport type {\n BridgeQuoteParams,\n BridgeQuote,\n BridgeExecuteParams,\n BridgeResult,\n BridgeStatus,\n BridgeTransaction,\n BridgeSigner,\n TransactionReceipt,\n TransactionLog,\n // LayerZero Scan types\n LayerZeroMessage,\n LayerZeroMessageStatus,\n WaitForDeliveryOptions,\n // Cross-chain payment types\n CrossChainPaymentParams,\n CrossChainPaymentResult,\n} from \"./bridge/index.js\";\n\n// Export ERC-4337 Account Abstraction module\nexport {\n // Builder\n UserOpBuilder,\n createUserOpBuilder,\n // Bundler\n BundlerClient,\n BundlerError,\n createBundlerClient,\n // Paymaster\n PaymasterClient,\n createPaymasterClient,\n encodePaymasterAndData,\n decodePaymasterAndData,\n // T402 Integration\n GaslessT402Client,\n createGaslessT402Client,\n // Constants\n ENTRYPOINT_V07_ADDRESS,\n ENTRYPOINT_V06_ADDRESS,\n DEFAULT_GAS_LIMITS,\n ENTRYPOINT_V07_ABI,\n ACCOUNT_ABI,\n BUNDLER_METHODS,\n PaymasterType,\n packAccountGasLimits,\n unpackAccountGasLimits,\n packGasFees,\n unpackGasFees,\n} from \"./erc4337/index.js\";\n\n// Export ERC-4337 types\nexport type {\n UserOperation,\n PackedUserOperation,\n PaymasterData,\n GasEstimate,\n UserOperationReceipt,\n UserOperationResult,\n BundlerConfig,\n PaymasterConfig,\n SmartAccountSigner,\n UserOpBuilderConfig,\n TransactionIntent,\n UserOpBuilderOptions,\n PaymasterResponse,\n SponsorRequest,\n GaslessPaymentParams,\n GaslessClientConfig,\n} from \"./erc4337/index.js\";\n","import { PaymentPayload, PaymentRequirements, SchemeNetworkClient } from \"@t402/core/types\";\nimport { getAddress } from \"viem\";\nimport { legacyAuthorizationTypes } from \"../../constants.js\";\nimport { ClientEvmSigner } from \"../../signer.js\";\nimport { ExactLegacyPayload } from \"../../types.js\";\nimport { createNonce } from \"../../utils.js\";\n\n/**\n * EVM client implementation for the exact-legacy payment scheme.\n * Used for legacy tokens (like USDT) that don't support EIP-3009.\n *\n * This scheme uses the approve + transferFrom pattern:\n * 1. Client must first approve the facilitator to spend tokens\n * 2. Client signs an authorization message\n * 3. Facilitator verifies the signature and calls transferFrom\n *\n * Note: The client must have already approved the facilitator (spender)\n * for at least the payment amount before creating a payment payload.\n */\nexport class ExactLegacyEvmScheme implements SchemeNetworkClient {\n readonly scheme = \"exact-legacy\";\n\n /**\n * Creates a new ExactLegacyEvmScheme 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-legacy scheme.\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<Pick<PaymentPayload, \"t402Version\" | \"payload\">> {\n // Validate that we have the spender (facilitator) address\n if (!paymentRequirements.extra?.spender) {\n throw new Error(\n \"exact-legacy scheme requires 'spender' (facilitator address) in payment requirements extra field\",\n );\n }\n\n const spender = getAddress(paymentRequirements.extra.spender as string);\n const nonce = createNonce();\n const now = Math.floor(Date.now() / 1000);\n\n const authorization: ExactLegacyPayload[\"authorization\"] = {\n from: this.signer.address,\n to: getAddress(paymentRequirements.payTo),\n value: paymentRequirements.amount,\n validAfter: (now - 600).toString(), // 10 minutes before\n validBefore: (now + paymentRequirements.maxTimeoutSeconds).toString(),\n nonce,\n spender,\n };\n\n // Sign the authorization\n const signature = await this.signAuthorization(authorization, paymentRequirements);\n\n const payload: ExactLegacyPayload = {\n authorization,\n signature,\n };\n\n return {\n t402Version,\n payload,\n };\n }\n\n /**\n * Sign the legacy transfer 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: ExactLegacyPayload[\"authorization\"],\n requirements: PaymentRequirements,\n ): Promise<`0x${string}`> {\n const chainId = parseInt(requirements.network.split(\":\")[1]);\n\n // For legacy tokens, we use a simple domain with the token address\n // The name and version can be provided in extra, or we use defaults\n const name = (requirements.extra?.name as string) || \"T402LegacyTransfer\";\n const version = (requirements.extra?.version as string) || \"1\";\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 spender: getAddress(authorization.spender),\n };\n\n return await this.signer.signTypedData({\n domain,\n types: legacyAuthorizationTypes,\n primaryType: \"LegacyTransferAuthorization\",\n message,\n });\n }\n}\n","import {\n AssetAmount,\n Network,\n PaymentRequirements,\n Price,\n SchemeNetworkServer,\n MoneyParser,\n} from \"@t402/core/types\";\nimport {\n getTokenConfig,\n TokenConfig,\n TOKEN_REGISTRY,\n USDT_LEGACY_ADDRESSES,\n} from \"../../tokens.js\";\n\n/**\n * Configuration options for ExactLegacyEvmScheme\n */\nexport interface ExactLegacyEvmSchemeConfig {\n /** Preferred token symbol. Defaults to \"USDT\" (legacy USDT) */\n preferredToken?: string;\n}\n\n/**\n * EVM server implementation for the exact-legacy payment scheme.\n * Supports legacy tokens that use approve + transferFrom pattern.\n */\nexport class ExactLegacyEvmScheme implements SchemeNetworkServer {\n readonly scheme = \"exact-legacy\";\n private moneyParsers: MoneyParser[] = [];\n private config: ExactLegacyEvmSchemeConfig;\n\n /**\n * Creates a new ExactLegacyEvmScheme instance.\n *\n * @param config - Optional configuration options for the scheme\n */\n constructor(config: ExactLegacyEvmSchemeConfig = {}) {\n this.config = config;\n }\n\n /**\n * Get all supported networks that have legacy tokens\n *\n * @returns Array of network identifiers with legacy token support\n */\n static getSupportedNetworks(): string[] {\n return Object.keys(USDT_LEGACY_ADDRESSES);\n }\n\n /**\n * Check if a network has legacy token support\n *\n * @param network - The network identifier to check\n * @returns True if the network has legacy token support\n */\n static isNetworkSupported(network: string): boolean {\n return network in USDT_LEGACY_ADDRESSES;\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 scheme instance for method chaining\n */\n registerMoneyParser(parser: MoneyParser): ExactLegacyEvmScheme {\n this.moneyParsers.push(parser);\n return this;\n }\n\n /**\n * Parses a price into an asset amount for legacy tokens.\n *\n * @param price - The price to parse (Money or AssetAmount)\n * @param network - The network identifier in CAIP-2 format\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 throw new Error(`Asset address must be specified for AssetAmount on network ${network}`);\n }\n return {\n amount: price.amount,\n asset: price.asset,\n extra: {\n ...price.extra,\n tokenType: \"legacy\",\n },\n };\n }\n\n // Parse Money to decimal number\n const amount = this.parseMoneyToDecimal(price);\n\n // Try each custom money parser in order\n for (const parser of this.moneyParsers) {\n const result = await parser(amount, network);\n if (result !== null) {\n return result;\n }\n }\n\n // All custom parsers returned null, use default conversion\n return this.defaultMoneyConversion(amount, network);\n }\n\n /**\n * Build payment requirements for this scheme/network combination.\n * Adds the spender (facilitator) address to the extra field.\n *\n * @param paymentRequirements - The base payment requirements to enhance\n * @param supportedKind - The supported kind from facilitator\n * @param supportedKind.t402Version - The t402 protocol version\n * @param supportedKind.scheme - The logical payment scheme identifier\n * @param supportedKind.network - The network identifier in CAIP-2 format\n * @param supportedKind.extra - Optional extra metadata with spender address\n * @param extensionKeys - Extension keys supported by the facilitator (unused)\n * @returns Promise resolving to enhanced payment requirements\n */\n enhancePaymentRequirements(\n paymentRequirements: PaymentRequirements,\n supportedKind: {\n t402Version: number;\n scheme: string;\n network: Network;\n extra?: Record<string, unknown>;\n },\n extensionKeys: string[],\n ): Promise<PaymentRequirements> {\n void extensionKeys;\n\n // Add spender (facilitator) address from supportedKind.extra\n // The facilitator should provide its address in the extra field\n const spender = supportedKind.extra?.spender as string | undefined;\n\n return Promise.resolve({\n ...paymentRequirements,\n extra: {\n ...paymentRequirements.extra,\n tokenType: \"legacy\",\n ...(spender && { spender }),\n },\n });\n }\n\n /**\n * Parse Money (string | number) to a decimal number.\n *\n * @param money - The money value to parse (e.g., \"$1.50\" or 1.50)\n * @returns The decimal number representation\n */\n private parseMoneyToDecimal(money: string | number): number {\n if (typeof money === \"number\") {\n return money;\n }\n\n const cleanMoney = money.replace(/^\\$/, \"\").trim();\n const amount = parseFloat(cleanMoney);\n\n if (isNaN(amount)) {\n throw new Error(`Invalid money format: ${money}`);\n }\n\n return amount;\n }\n\n /**\n * Default money conversion implementation for legacy tokens.\n *\n * @param amount - The decimal amount to convert (e.g., 1.50)\n * @param network - The network identifier in CAIP-2 format\n * @returns The asset amount in token units\n */\n private defaultMoneyConversion(amount: number, network: Network): AssetAmount {\n const token = this.getDefaultAsset(network);\n\n const tokenAmount = this.convertToTokenAmount(amount.toString(), token.decimals);\n\n return {\n amount: tokenAmount,\n asset: token.address,\n extra: {\n name: token.name,\n version: token.version,\n symbol: token.symbol,\n tokenType: \"legacy\",\n },\n };\n }\n\n /**\n * Convert decimal amount to token units\n *\n * @param decimalAmount - The decimal amount as a string (e.g., \"1.50\")\n * @param decimals - The number of decimal places for the token\n * @returns The token amount as a string in smallest units\n */\n private convertToTokenAmount(decimalAmount: string, decimals: number): string {\n const amount = parseFloat(decimalAmount);\n if (isNaN(amount)) {\n throw new Error(`Invalid amount: ${decimalAmount}`);\n }\n const tokenAmount = Math.floor(amount * Math.pow(10, decimals));\n return tokenAmount.toString();\n }\n\n /**\n * Get the default legacy token for a network.\n *\n * @param network - The network identifier in CAIP-2 format\n * @returns The token configuration for the default legacy token\n */\n private getDefaultAsset(network: Network): TokenConfig {\n // If a preferred token is configured, try to use it\n if (this.config.preferredToken) {\n const preferred = getTokenConfig(network, this.config.preferredToken);\n if (preferred && preferred.tokenType === \"legacy\") {\n return preferred;\n }\n }\n\n // Look for legacy USDT on this network\n const usdt = getTokenConfig(network, \"USDT\");\n if (usdt && usdt.tokenType === \"legacy\") {\n return usdt;\n }\n\n // Fallback: find any legacy token on this network\n const tokens = TOKEN_REGISTRY[network];\n if (tokens) {\n const legacyToken = Object.values(tokens).find(t => t.tokenType === \"legacy\");\n if (legacyToken) return legacyToken;\n }\n\n throw new Error(`No legacy tokens configured for network ${network}`);\n }\n}\n","import {\n PaymentPayload,\n PaymentRequirements,\n SchemeNetworkFacilitator,\n SettleResponse,\n VerifyResponse,\n} from \"@t402/core/types\";\nimport { getAddress, isAddressEqual } from \"viem\";\nimport { legacyAuthorizationTypes, erc20LegacyABI } from \"../../constants.js\";\nimport { FacilitatorEvmSigner } from \"../../signer.js\";\nimport { ExactLegacyPayload } from \"../../types.js\";\n\nexport interface ExactLegacyEvmSchemeConfig {\n /**\n * Minimum allowance ratio required (0.0 to 1.0)\n * If the allowance is less than this ratio of the payment amount,\n * verification will fail.\n *\n * @default 1.0 (exact allowance required)\n */\n minAllowanceRatio?: number;\n}\n\n/**\n * EVM facilitator implementation for the exact-legacy payment scheme.\n * Uses the approve + transferFrom pattern for legacy tokens.\n */\nexport class ExactLegacyEvmScheme implements SchemeNetworkFacilitator {\n readonly scheme = \"exact-legacy\";\n readonly caipFamily = \"eip155:*\";\n private readonly config: Required<ExactLegacyEvmSchemeConfig>;\n\n /**\n * Creates a new ExactLegacyEvmScheme 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?: ExactLegacyEvmSchemeConfig,\n ) {\n this.config = {\n minAllowanceRatio: config?.minAllowanceRatio ?? 1.0,\n };\n }\n\n /**\n * Get mechanism-specific extra data for the supported kinds endpoint.\n * For exact-legacy, returns the spender (facilitator) addresses.\n *\n * @param network - The network identifier\n * @returns Extra data including spender addresses\n */\n getExtra(network: string): Record<string, unknown> | undefined {\n void network;\n // Return the first facilitator address as the spender\n const addresses = this.signer.getAddresses();\n if (addresses.length > 0) {\n return {\n spender: addresses[0],\n tokenType: \"legacy\",\n };\n }\n return { tokenType: \"legacy\" };\n }\n\n /**\n * Get signer addresses used by this facilitator.\n *\n * @param network - The network identifier (unused, returns same addresses for all networks)\n * @returns Array of signer addresses\n */\n getSigners(network: string): string[] {\n void network;\n return [...this.signer.getAddresses()];\n }\n\n /**\n * Verifies a payment payload.\n *\n * @param payload - The payment payload to verify\n * @param requirements - The payment requirements to verify against\n * @returns Promise resolving to verification response with validity status\n */\n async verify(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<VerifyResponse> {\n const legacyPayload = payload.payload as ExactLegacyPayload;\n\n // Verify scheme matches\n if (payload.accepted.scheme !== \"exact-legacy\" || requirements.scheme !== \"exact-legacy\") {\n return {\n isValid: false,\n invalidReason: \"unsupported_scheme\",\n payer: legacyPayload.authorization.from,\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: legacyPayload.authorization.from,\n };\n }\n\n const erc20Address = getAddress(requirements.asset);\n\n // Verify the spender is one of our addresses\n const spender = getAddress(legacyPayload.authorization.spender);\n const facilitatorAddresses = this.signer.getAddresses();\n const isValidSpender = facilitatorAddresses.some(addr => isAddressEqual(addr, spender));\n\n if (!isValidSpender) {\n return {\n isValid: false,\n invalidReason: \"invalid_spender\",\n payer: legacyPayload.authorization.from,\n };\n }\n\n // Build domain for signature verification\n const name = (requirements.extra?.name as string) || \"T402LegacyTransfer\";\n const version = (requirements.extra?.version as string) || \"1\";\n const chainId = parseInt(requirements.network.split(\":\")[1]);\n\n const domain = {\n name,\n version,\n chainId,\n verifyingContract: erc20Address,\n };\n\n const message = {\n from: legacyPayload.authorization.from,\n to: legacyPayload.authorization.to,\n value: BigInt(legacyPayload.authorization.value),\n validAfter: BigInt(legacyPayload.authorization.validAfter),\n validBefore: BigInt(legacyPayload.authorization.validBefore),\n nonce: legacyPayload.authorization.nonce,\n spender: legacyPayload.authorization.spender,\n };\n\n // Verify signature\n try {\n const isValid = await this.signer.verifyTypedData({\n address: legacyPayload.authorization.from,\n domain,\n types: legacyAuthorizationTypes,\n primaryType: \"LegacyTransferAuthorization\",\n message,\n signature: legacyPayload.signature!,\n });\n\n if (!isValid) {\n return {\n isValid: false,\n invalidReason: \"invalid_signature\",\n payer: legacyPayload.authorization.from,\n };\n }\n } catch {\n return {\n isValid: false,\n invalidReason: \"signature_verification_failed\",\n payer: legacyPayload.authorization.from,\n };\n }\n\n // Verify payment recipient matches\n if (getAddress(legacyPayload.authorization.to) !== getAddress(requirements.payTo)) {\n return {\n isValid: false,\n invalidReason: \"recipient_mismatch\",\n payer: legacyPayload.authorization.from,\n };\n }\n\n // Verify validBefore is in the future\n const now = Math.floor(Date.now() / 1000);\n if (BigInt(legacyPayload.authorization.validBefore) < BigInt(now + 6)) {\n return {\n isValid: false,\n invalidReason: \"authorization_expired\",\n payer: legacyPayload.authorization.from,\n };\n }\n\n // Verify validAfter is not in the future\n if (BigInt(legacyPayload.authorization.validAfter) > BigInt(now)) {\n return {\n isValid: false,\n invalidReason: \"authorization_not_yet_valid\",\n payer: legacyPayload.authorization.from,\n };\n }\n\n // Check balance\n try {\n const balance = (await this.signer.readContract({\n address: erc20Address,\n abi: erc20LegacyABI,\n functionName: \"balanceOf\",\n args: [legacyPayload.authorization.from],\n })) as bigint;\n\n if (BigInt(balance) < BigInt(requirements.amount)) {\n return {\n isValid: false,\n invalidReason: \"insufficient_balance\",\n payer: legacyPayload.authorization.from,\n };\n }\n } catch {\n // If we can't check balance, continue with other validations\n }\n\n // Check allowance\n try {\n const allowance = (await this.signer.readContract({\n address: erc20Address,\n abi: erc20LegacyABI,\n functionName: \"allowance\",\n args: [legacyPayload.authorization.from, spender],\n })) as bigint;\n\n const requiredAllowance = BigInt(\n Math.floor(Number(requirements.amount) * this.config.minAllowanceRatio),\n );\n\n if (allowance < requiredAllowance) {\n return {\n isValid: false,\n invalidReason: \"insufficient_allowance\",\n payer: legacyPayload.authorization.from,\n };\n }\n } catch {\n return {\n isValid: false,\n invalidReason: \"allowance_check_failed\",\n payer: legacyPayload.authorization.from,\n };\n }\n\n // Verify amount is sufficient\n if (BigInt(legacyPayload.authorization.value) < BigInt(requirements.amount)) {\n return {\n isValid: false,\n invalidReason: \"insufficient_amount\",\n payer: legacyPayload.authorization.from,\n };\n }\n\n return {\n isValid: true,\n invalidReason: undefined,\n payer: legacyPayload.authorization.from,\n };\n }\n\n /**\n * Settles a payment by executing transferFrom.\n *\n * @param payload - The payment payload containing transfer authorization\n * @param requirements - The payment requirements specifying amount and recipient\n * @returns Promise resolving to settlement response with transaction hash\n */\n async settle(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<SettleResponse> {\n const legacyPayload = payload.payload as ExactLegacyPayload;\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: payload.accepted.network,\n transaction: \"\",\n errorReason: valid.invalidReason ?? \"invalid_payment\",\n payer: legacyPayload.authorization.from,\n };\n }\n\n try {\n // Execute transferFrom\n const tx = await this.signer.writeContract({\n address: getAddress(requirements.asset),\n abi: erc20LegacyABI,\n functionName: \"transferFrom\",\n args: [\n getAddress(legacyPayload.authorization.from),\n getAddress(legacyPayload.authorization.to),\n BigInt(legacyPayload.authorization.value),\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: \"transaction_failed\",\n transaction: tx,\n network: payload.accepted.network,\n payer: legacyPayload.authorization.from,\n };\n }\n\n return {\n success: true,\n transaction: tx,\n network: payload.accepted.network,\n payer: legacyPayload.authorization.from,\n };\n } catch (error) {\n console.error(\"Failed to settle legacy transaction:\", error);\n return {\n success: false,\n errorReason: \"settlement_failed\",\n transaction: \"\",\n network: payload.accepted.network,\n payer: legacyPayload.authorization.from,\n };\n }\n }\n}\n","/**\n * USDT0 Bridge Client\n *\n * Provides cross-chain USDT0 transfers using LayerZero OFT standard.\n *\n * @example\n * ```typescript\n * import { Usdt0Bridge } from '@t402/evm';\n * import { createWalletClient, http } from 'viem';\n * import { arbitrum } from 'viem/chains';\n *\n * const walletClient = createWalletClient({\n * chain: arbitrum,\n * transport: http(),\n * account: privateKeyToAccount(privateKey),\n * });\n *\n * const bridge = new Usdt0Bridge(walletClient, 'arbitrum');\n *\n * // Get quote\n * const quote = await bridge.quote({\n * fromChain: 'arbitrum',\n * toChain: 'ethereum',\n * amount: 100_000000n, // 100 USDT0\n * recipient: '0x...',\n * });\n *\n * // Execute bridge\n * const result = await bridge.send({\n * fromChain: 'arbitrum',\n * toChain: 'ethereum',\n * amount: 100_000000n,\n * recipient: '0x...',\n * });\n * ```\n */\n\nimport type { Address } from \"viem\";\nimport { keccak256, toBytes } from \"viem\";\nimport {\n getEndpointId,\n getUsdt0OftAddress,\n supportsBridging,\n addressToBytes32,\n OFT_SEND_ABI,\n ERC20_APPROVE_ABI,\n DEFAULT_EXTRA_OPTIONS,\n getBridgeableChains,\n} from \"./constants.js\";\nimport type {\n BridgeQuoteParams,\n BridgeQuote,\n BridgeExecuteParams,\n BridgeResult,\n BridgeSigner,\n SendParam,\n MessagingFee,\n TransactionReceipt,\n} from \"./types.js\";\n\n/**\n * OFTSent event signature for GUID extraction\n * Event: OFTSent(bytes32 indexed guid, uint32 dstEid, address indexed from, uint256 amountSentLD, uint256 amountReceivedLD)\n */\nconst OFT_SENT_EVENT_TOPIC = keccak256(toBytes(\"OFTSent(bytes32,uint32,address,uint256,uint256)\"));\n\n/**\n * Default slippage tolerance (0.5%)\n */\nconst DEFAULT_SLIPPAGE = 0.5;\n\n/**\n * Estimated bridge completion time in seconds\n */\nconst ESTIMATED_BRIDGE_TIME = 300; // ~5 minutes\n\n/**\n * USDT0 Bridge Client for LayerZero OFT transfers\n */\nexport class Usdt0Bridge {\n private readonly signer: BridgeSigner;\n private readonly chain: string;\n\n /**\n * Create a new bridge client\n *\n * @param signer - Wallet signer with read/write capabilities\n * @param chain - Source chain name (e.g., \"arbitrum\", \"ethereum\")\n */\n constructor(signer: BridgeSigner, chain: string) {\n if (!supportsBridging(chain)) {\n throw new Error(\n `Chain \"${chain}\" does not support USDT0 bridging. Supported chains: ${getBridgeableChains().join(\", \")}`,\n );\n }\n\n this.signer = signer;\n this.chain = chain;\n }\n\n /**\n * Get a quote for bridging USDT0\n *\n * @param params - Bridge parameters\n * @returns Quote with fee and amount information\n */\n async quote(params: BridgeQuoteParams): Promise<BridgeQuote> {\n this.validateBridgeParams(params);\n\n const sendParam = this.buildSendParam(params);\n const oftAddress = getUsdt0OftAddress(params.fromChain)!;\n\n // Get quote from contract\n const fee = (await this.signer.readContract({\n address: oftAddress,\n abi: OFT_SEND_ABI,\n functionName: \"quoteSend\",\n args: [sendParam, false],\n })) as MessagingFee;\n\n return {\n nativeFee: fee.nativeFee,\n amountToSend: params.amount,\n minAmountToReceive: sendParam.minAmountLD,\n estimatedTime: ESTIMATED_BRIDGE_TIME,\n fromChain: params.fromChain,\n toChain: params.toChain,\n };\n }\n\n /**\n * Execute a bridge transaction\n *\n * @param params - Bridge execution parameters\n * @returns Bridge result with transaction hash\n */\n async send(params: BridgeExecuteParams): Promise<BridgeResult> {\n this.validateBridgeParams(params);\n\n const oftAddress = getUsdt0OftAddress(params.fromChain)!;\n const sendParam = this.buildSendParam(params);\n const refundAddress = params.refundAddress ?? this.signer.address;\n\n // Get fee quote\n const fee = (await this.signer.readContract({\n address: oftAddress,\n abi: OFT_SEND_ABI,\n functionName: \"quoteSend\",\n args: [sendParam, false],\n })) as MessagingFee;\n\n // Check and approve allowance if needed\n await this.ensureAllowance(oftAddress, params.amount);\n\n // Execute bridge transaction\n const txHash = await this.signer.writeContract({\n address: oftAddress,\n abi: OFT_SEND_ABI,\n functionName: \"send\",\n args: [sendParam, fee, refundAddress],\n value: fee.nativeFee,\n });\n\n // Wait for transaction confirmation\n const receipt = await this.signer.waitForTransactionReceipt({ hash: txHash });\n\n if (receipt.status !== \"success\") {\n throw new Error(`Bridge transaction failed: ${txHash}`);\n }\n\n // Extract message GUID from OFTSent event logs\n const messageGuid = this.extractMessageGuid(receipt);\n\n return {\n txHash,\n messageGuid,\n amountSent: params.amount,\n amountToReceive: sendParam.minAmountLD,\n fromChain: params.fromChain,\n toChain: params.toChain,\n estimatedTime: ESTIMATED_BRIDGE_TIME,\n };\n }\n\n /**\n * Get all supported destination chains from current chain\n *\n * @returns Array of supported destination chain names\n */\n getSupportedDestinations(): string[] {\n return getBridgeableChains().filter(chain => chain !== this.chain);\n }\n\n /**\n * Check if a destination chain is supported\n *\n * @param toChain - The destination chain to check\n * @returns True if the destination chain is supported\n */\n supportsDestination(toChain: string): boolean {\n return toChain !== this.chain && supportsBridging(toChain);\n }\n\n /**\n * Extract LayerZero message GUID from OFTSent event logs\n *\n * @param receipt - Transaction receipt with logs\n * @returns Message GUID as hex string\n */\n private extractMessageGuid(receipt: TransactionReceipt): `0x${string}` {\n for (const log of receipt.logs) {\n // Check if this is an OFTSent event\n if (log.topics[0] === OFT_SENT_EVENT_TOPIC && log.topics[1]) {\n // GUID is the first indexed parameter (topics[1])\n return log.topics[1];\n }\n }\n\n throw new Error(\n \"Failed to extract message GUID from transaction logs. \" +\n \"The OFTSent event was not found in the transaction receipt.\",\n );\n }\n\n /**\n * Ensure sufficient token allowance for the OFT contract\n *\n * @param oftAddress - The OFT contract address\n * @param amount - The amount to approve\n */\n private async ensureAllowance(oftAddress: Address, amount: bigint): Promise<void> {\n // Check current allowance\n const allowance = (await this.signer.readContract({\n address: oftAddress,\n abi: ERC20_APPROVE_ABI,\n functionName: \"allowance\",\n args: [this.signer.address, oftAddress],\n })) as bigint;\n\n // Approve if needed\n if (allowance < amount) {\n const approveTx = await this.signer.writeContract({\n address: oftAddress,\n abi: ERC20_APPROVE_ABI,\n functionName: \"approve\",\n args: [oftAddress, amount],\n });\n\n await this.signer.waitForTransactionReceipt({ hash: approveTx });\n }\n }\n\n /**\n * Build SendParam struct for LayerZero\n *\n * @param params - Bridge parameters\n * @returns SendParam struct for the OFT contract\n */\n private buildSendParam(params: BridgeQuoteParams | BridgeExecuteParams): SendParam {\n const dstEid = getEndpointId(params.toChain);\n if (!dstEid) {\n throw new Error(`Unknown destination chain: ${params.toChain}`);\n }\n\n const slippage =\n \"slippageTolerance\" in params\n ? ((params as BridgeExecuteParams).slippageTolerance ?? DEFAULT_SLIPPAGE)\n : DEFAULT_SLIPPAGE;\n\n // Calculate minimum amount with slippage\n const minAmount = params.amount - (params.amount * BigInt(Math.floor(slippage * 100))) / 10000n;\n\n return {\n dstEid,\n to: addressToBytes32(params.recipient),\n amountLD: params.amount,\n minAmountLD: minAmount,\n extraOptions: DEFAULT_EXTRA_OPTIONS,\n composeMsg: \"0x\" as `0x${string}`,\n oftCmd: \"0x\" as `0x${string}`,\n };\n }\n\n /**\n * Validate bridge parameters\n *\n * @param params - Bridge parameters to validate\n */\n private validateBridgeParams(params: BridgeQuoteParams): void {\n if (params.fromChain !== this.chain) {\n throw new Error(\n `Source chain mismatch: bridge initialized for \"${this.chain}\" but got \"${params.fromChain}\"`,\n );\n }\n\n if (!supportsBridging(params.fromChain)) {\n throw new Error(`Source chain \"${params.fromChain}\" does not support USDT0 bridging`);\n }\n\n if (!supportsBridging(params.toChain)) {\n throw new Error(`Destination chain \"${params.toChain}\" does not support USDT0 bridging`);\n }\n\n if (params.fromChain === params.toChain) {\n throw new Error(\"Source and destination chains must be different\");\n }\n\n if (params.amount <= 0n) {\n throw new Error(\"Amount must be greater than 0\");\n }\n }\n}\n\n/**\n * Create a bridge client for a specific chain\n *\n * @param signer - Wallet signer with read/write capabilities\n * @param chain - Source chain name\n * @returns New Usdt0Bridge instance\n */\nexport function createUsdt0Bridge(signer: BridgeSigner, chain: string): Usdt0Bridge {\n return new Usdt0Bridge(signer, chain);\n}\n","/**\n * LayerZero OFT Bridge Constants for USDT0\n *\n * USDT0 uses LayerZero's OFT (Omnichain Fungible Token) standard\n * for cross-chain transfers.\n *\n * @see https://docs.layerzero.network/v2/developers/evm/oft/quickstart\n */\n\nimport type { Address } from \"viem\";\n\n/**\n * LayerZero V2 Endpoint IDs (EIDs) for supported chains\n * These are unique identifiers used by LayerZero to route messages\n *\n * @see https://docs.layerzero.network/v2/deployments/deployed-contracts\n */\nexport const LAYERZERO_ENDPOINT_IDS: Record<string, number> = {\n // Mainnets\n ethereum: 30101,\n arbitrum: 30110,\n base: 30184,\n optimism: 30111,\n polygon: 30109,\n avalanche: 30106,\n bsc: 30102,\n // USDT0 specific chains\n ink: 30291, // Ink mainnet\n berachain: 30362, // Berachain mainnet\n unichain: 30320, // Unichain mainnet\n // Testnets\n sepolia: 40161,\n arbitrumSepolia: 40231,\n baseSepolia: 40245,\n};\n\n/**\n * Map from CAIP-2 network ID to chain name\n */\nexport const NETWORK_TO_CHAIN: Record<string, string> = {\n \"eip155:1\": \"ethereum\",\n \"eip155:42161\": \"arbitrum\",\n \"eip155:8453\": \"base\",\n \"eip155:10\": \"optimism\",\n \"eip155:137\": \"polygon\",\n \"eip155:43114\": \"avalanche\",\n \"eip155:56\": \"bsc\",\n \"eip155:57073\": \"ink\",\n \"eip155:80094\": \"berachain\",\n \"eip155:130\": \"unichain\",\n // Testnets\n \"eip155:11155111\": \"sepolia\",\n \"eip155:421614\": \"arbitrumSepolia\",\n \"eip155:84532\": \"baseSepolia\",\n};\n\n/**\n * Map from chain name to CAIP-2 network ID\n */\nexport const CHAIN_TO_NETWORK: Record<string, string> = Object.fromEntries(\n Object.entries(NETWORK_TO_CHAIN).map(([k, v]) => [v, k]),\n);\n\n/**\n * USDT0 OFT Adapter contract addresses by chain\n * These are the contracts that handle cross-chain transfers\n */\nexport const USDT0_OFT_ADDRESSES: Record<string, Address> = {\n // Ethereum is the OFT Adapter (locks/unlocks tokens)\n ethereum: \"0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee\",\n // Other chains have native USDT0 OFT contracts\n arbitrum: \"0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9\",\n ink: \"0x0200C29006150606B650577BBE7B6248F58470c1\",\n berachain: \"0x779Ded0c9e1022225f8E0630b35a9b54bE713736\",\n unichain: \"0x588ce4F028D8e7B53B687865d6A67b3A54C75518\",\n};\n\n/**\n * LayerZero V2 Endpoint contract addresses\n * Same address on all EVM chains\n */\nexport const LAYERZERO_ENDPOINT_V2: Address = \"0x1a44076050125825900e736c501f859c50fE728c\";\n\n/**\n * Default gas limit for cross-chain messages\n */\nexport const DEFAULT_GAS_LIMIT = 200000n;\n\n/**\n * Default extra options for LayerZero messages\n * Type 3 options with executor gas\n */\nexport const DEFAULT_EXTRA_OPTIONS =\n \"0x00030100110100000000000000000000000000030d40\" as `0x${string}`;\n\n/**\n * OFT Send ABI for cross-chain transfers\n */\nexport const OFT_SEND_ABI = [\n {\n inputs: [\n {\n components: [\n { name: \"dstEid\", type: \"uint32\" },\n { name: \"to\", type: \"bytes32\" },\n { name: \"amountLD\", type: \"uint256\" },\n { name: \"minAmountLD\", type: \"uint256\" },\n { name: \"extraOptions\", type: \"bytes\" },\n { name: \"composeMsg\", type: \"bytes\" },\n { name: \"oftCmd\", type: \"bytes\" },\n ],\n name: \"_sendParam\",\n type: \"tuple\",\n },\n {\n components: [\n { name: \"nativeFee\", type: \"uint256\" },\n { name: \"lzTokenFee\", type: \"uint256\" },\n ],\n name: \"_fee\",\n type: \"tuple\",\n },\n { name: \"_refundAddress\", type: \"address\" },\n ],\n name: \"send\",\n outputs: [\n {\n components: [\n { name: \"guid\", type: \"bytes32\" },\n { name: \"nonce\", type: \"uint64\" },\n {\n components: [\n { name: \"nativeFee\", type: \"uint256\" },\n { name: \"lzTokenFee\", type: \"uint256\" },\n ],\n name: \"fee\",\n type: \"tuple\",\n },\n ],\n name: \"msgReceipt\",\n type: \"tuple\",\n },\n {\n components: [\n { name: \"amountSentLD\", type: \"uint256\" },\n { name: \"amountReceivedLD\", type: \"uint256\" },\n ],\n name: \"oftReceipt\",\n type: \"tuple\",\n },\n ],\n stateMutability: \"payable\",\n type: \"function\",\n },\n {\n inputs: [\n {\n components: [\n { name: \"dstEid\", type: \"uint32\" },\n { name: \"to\", type: \"bytes32\" },\n { name: \"amountLD\", type: \"uint256\" },\n { name: \"minAmountLD\", type: \"uint256\" },\n { name: \"extraOptions\", type: \"bytes\" },\n { name: \"composeMsg\", type: \"bytes\" },\n { name: \"oftCmd\", type: \"bytes\" },\n ],\n name: \"_sendParam\",\n type: \"tuple\",\n },\n { name: \"_payInLzToken\", type: \"bool\" },\n ],\n name: \"quoteSend\",\n outputs: [\n {\n components: [\n { name: \"nativeFee\", type: \"uint256\" },\n { name: \"lzTokenFee\", type: \"uint256\" },\n ],\n name: \"msgFee\",\n type: \"tuple\",\n },\n ],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const;\n\n/**\n * ERC20 approval ABI for token allowance\n */\nexport const ERC20_APPROVE_ABI = [\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: \"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] as const;\n\n/**\n * Get LayerZero endpoint ID for a chain\n *\n * @param chain - The chain name (e.g., 'ethereum', 'arbitrum')\n * @returns The LayerZero endpoint ID, or undefined if chain not supported\n */\nexport function getEndpointId(chain: string): number | undefined {\n return LAYERZERO_ENDPOINT_IDS[chain];\n}\n\n/**\n * Get LayerZero endpoint ID from CAIP-2 network\n *\n * @param network - The CAIP-2 network identifier (e.g., 'eip155:1' for Ethereum)\n * @returns The LayerZero endpoint ID, or undefined if network not supported\n */\nexport function getEndpointIdFromNetwork(network: string): number | undefined {\n const chain = NETWORK_TO_CHAIN[network];\n return chain ? LAYERZERO_ENDPOINT_IDS[chain] : undefined;\n}\n\n/**\n * Get USDT0 OFT contract address for a chain\n *\n * @param chain - The chain name (e.g., 'ethereum', 'arbitrum')\n * @returns The USDT0 OFT contract address, or undefined if chain not supported\n */\nexport function getUsdt0OftAddress(chain: string): Address | undefined {\n return USDT0_OFT_ADDRESSES[chain];\n}\n\n/**\n * Check if a chain supports USDT0 bridging\n *\n * @param chain - The chain name to check (e.g., 'ethereum', 'arbitrum')\n * @returns True if the chain supports USDT0 bridging, false otherwise\n */\nexport function supportsBridging(chain: string): boolean {\n return chain in USDT0_OFT_ADDRESSES && chain in LAYERZERO_ENDPOINT_IDS;\n}\n\n/**\n * Get all chains that support USDT0 bridging\n *\n * @returns Array of chain names that support USDT0 bridging\n */\nexport function getBridgeableChains(): string[] {\n return Object.keys(USDT0_OFT_ADDRESSES).filter(chain => chain in LAYERZERO_ENDPOINT_IDS);\n}\n\n/**\n * Convert address to bytes32 format for LayerZero\n * Pads address with leading zeros to 32 bytes\n *\n * @param address - The EVM address to convert\n * @returns The address as a bytes32 hex string with leading zeros\n */\nexport function addressToBytes32(address: Address): `0x${string}` {\n // Remove 0x prefix, pad to 64 chars (32 bytes), add 0x prefix\n const cleanAddress = address.slice(2).toLowerCase();\n return `0x${cleanAddress.padStart(64, \"0\")}` as `0x${string}`;\n}\n\n/**\n * Convert bytes32 to address\n *\n * @param bytes32 - The bytes32 hex string to convert\n * @returns The extracted EVM address from the last 20 bytes\n */\nexport function bytes32ToAddress(bytes32: `0x${string}`): Address {\n // Take last 40 characters (20 bytes)\n return `0x${bytes32.slice(-40)}` as Address;\n}\n","/**\n * LayerZero Scan API Client\n *\n * Provides tracking for cross-chain messages via LayerZero Scan.\n *\n * @see https://docs.layerzero.network/v2/tools/api/scan/mainnet\n *\n * @example\n * ```typescript\n * import { LayerZeroScanClient } from '@t402/evm';\n *\n * const scanClient = new LayerZeroScanClient();\n *\n * // Get message status\n * const message = await scanClient.getMessage(messageGuid);\n * console.log(`Status: ${message.status}`);\n *\n * // Wait for delivery\n * const delivered = await scanClient.waitForDelivery(messageGuid, {\n * onStatusChange: (status) => console.log(`Status changed: ${status}`),\n * });\n * console.log(`Delivered! Destination TX: ${delivered.dstTxHash}`);\n * ```\n */\n\nimport type { LayerZeroMessage, LayerZeroMessageStatus, WaitForDeliveryOptions } from \"./types.js\";\n\n/**\n * LayerZero Scan API base URL\n */\nexport const LAYERZERO_SCAN_BASE_URL = \"https://scan.layerzero-api.com/v1\";\n\n/**\n * Default timeout for waiting (10 minutes)\n */\nconst DEFAULT_TIMEOUT = 600_000;\n\n/**\n * Default poll interval (10 seconds)\n */\nconst DEFAULT_POLL_INTERVAL = 10_000;\n\n/**\n * LayerZero Scan API Client\n *\n * Use this client to track the status of cross-chain messages sent via LayerZero.\n */\nexport class LayerZeroScanClient {\n private readonly baseUrl: string;\n\n /**\n * Create a new LayerZero Scan client\n *\n * @param baseUrl - API base URL (default: production endpoint)\n */\n constructor(baseUrl: string = LAYERZERO_SCAN_BASE_URL) {\n this.baseUrl = baseUrl;\n }\n\n /**\n * Get message by GUID\n *\n * @param guid - LayerZero message GUID\n * @returns Message details including status\n * @throws Error if message not found or API error\n */\n async getMessage(guid: string): Promise<LayerZeroMessage> {\n const url = `${this.baseUrl}/messages/guid/${guid}`;\n\n const response = await fetch(url, {\n method: \"GET\",\n headers: {\n Accept: \"application/json\",\n },\n });\n\n if (!response.ok) {\n if (response.status === 404) {\n throw new Error(`Message not found: ${guid}`);\n }\n throw new Error(`LayerZero Scan API error: ${response.status} ${response.statusText}`);\n }\n\n const data = await response.json();\n return this.mapApiResponse(data);\n }\n\n /**\n * Get messages by wallet address\n *\n * @param address - Wallet address that initiated messages\n * @param limit - Maximum number of messages to return (default: 20)\n * @returns Array of messages\n */\n async getMessagesByWallet(address: string, limit: number = 20): Promise<LayerZeroMessage[]> {\n const url = `${this.baseUrl}/messages/wallet/${address}?limit=${limit}`;\n\n const response = await fetch(url, {\n method: \"GET\",\n headers: {\n Accept: \"application/json\",\n },\n });\n\n if (!response.ok) {\n throw new Error(`LayerZero Scan API error: ${response.status} ${response.statusText}`);\n }\n\n const data = (await response.json()) as Record<string, unknown>;\n const messages = (data.messages ?? data.data ?? []) as unknown[];\n return messages.map((msg: unknown) => this.mapApiResponse(msg));\n }\n\n /**\n * Poll message status until delivered or failed\n *\n * @param guid - LayerZero message GUID\n * @param options - Wait configuration options\n * @returns Final message state (DELIVERED)\n * @throws Error if message fails, is blocked, or times out\n */\n async waitForDelivery(\n guid: string,\n options: WaitForDeliveryOptions = {},\n ): Promise<LayerZeroMessage> {\n const {\n timeout = DEFAULT_TIMEOUT,\n pollInterval = DEFAULT_POLL_INTERVAL,\n onStatusChange,\n } = options;\n\n const startTime = Date.now();\n let lastStatus: LayerZeroMessageStatus | null = null;\n\n while (Date.now() - startTime < timeout) {\n try {\n const message = await this.getMessage(guid);\n\n // Notify on status change\n if (lastStatus !== message.status) {\n lastStatus = message.status;\n onStatusChange?.(message.status);\n }\n\n // Check terminal states\n if (message.status === \"DELIVERED\") {\n return message;\n }\n\n if (message.status === \"FAILED\") {\n throw new Error(`Bridge message failed: ${guid}`);\n }\n\n if (message.status === \"BLOCKED\") {\n throw new Error(`Bridge message blocked by DVN: ${guid}`);\n }\n\n // Continue polling for INFLIGHT/CONFIRMING\n await this.sleep(pollInterval);\n } catch (error) {\n // Message not yet indexed, retry\n if ((error as Error).message.includes(\"not found\")) {\n await this.sleep(pollInterval);\n continue;\n }\n throw error;\n }\n }\n\n throw new Error(`Timeout waiting for message delivery: ${guid}`);\n }\n\n /**\n * Check if a message has been delivered\n *\n * @param guid - LayerZero message GUID\n * @returns True if delivered, false otherwise\n */\n async isDelivered(guid: string): Promise<boolean> {\n try {\n const message = await this.getMessage(guid);\n return message.status === \"DELIVERED\";\n } catch {\n return false;\n }\n }\n\n /**\n * Map API response to our interface\n *\n * @param data - The raw API response data\n * @returns The mapped LayerZeroMessage object\n */\n private mapApiResponse(data: unknown): LayerZeroMessage {\n const msg = data as Record<string, unknown>;\n return {\n guid: (msg.guid ?? msg.messageGuid ?? \"\") as string,\n srcEid: (msg.srcEid ?? msg.srcChainId ?? 0) as number,\n dstEid: (msg.dstEid ?? msg.dstChainId ?? 0) as number,\n srcUaAddress: (msg.srcUaAddress ?? msg.srcAddress ?? \"\") as string,\n dstUaAddress: (msg.dstUaAddress ?? msg.dstAddress ?? \"\") as string,\n srcTxHash: (msg.srcTxHash ?? \"\") as string,\n dstTxHash: (msg.dstTxHash ?? undefined) as string | undefined,\n status: (msg.status ?? \"INFLIGHT\") as LayerZeroMessageStatus,\n srcBlockNumber: (msg.srcBlockNumber ?? 0) as number,\n dstBlockNumber: (msg.dstBlockNumber ?? undefined) as number | undefined,\n created: (msg.created ?? msg.createdAt ?? \"\") as string,\n updated: (msg.updated ?? msg.updatedAt ?? \"\") as string,\n };\n }\n\n /**\n * Sleep helper\n *\n * @param ms - The number of milliseconds to sleep\n * @returns A promise that resolves after the specified delay\n */\n private sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n}\n\n/**\n * Create a LayerZero Scan client\n *\n * @param baseUrl - Optional custom API base URL\n * @returns A new LayerZeroScanClient instance\n */\nexport function createLayerZeroScanClient(baseUrl?: string): LayerZeroScanClient {\n return new LayerZeroScanClient(baseUrl);\n}\n","/**\n * Cross-Chain Payment Router\n *\n * Enables payments on a destination chain using funds from a source chain.\n * Uses USDT0 bridge via LayerZero for cross-chain transfers.\n *\n * @example\n * ```typescript\n * import { CrossChainPaymentRouter } from '@t402/evm';\n *\n * const router = new CrossChainPaymentRouter(signer, 'arbitrum');\n *\n * // Route payment from Arbitrum to Ethereum\n * const result = await router.routePayment({\n * sourceChain: 'arbitrum',\n * destinationChain: 'ethereum',\n * amount: 100_000000n, // 100 USDT0\n * payTo: recipientAddress,\n * payer: userAddress,\n * });\n *\n * // Track delivery\n * const message = await router.trackMessage(result.messageGuid);\n * ```\n */\n\nimport { Usdt0Bridge } from \"./client.js\";\nimport { LayerZeroScanClient } from \"./scan.js\";\nimport { getBridgeableChains, supportsBridging } from \"./constants.js\";\nimport type {\n BridgeSigner,\n CrossChainPaymentParams,\n CrossChainPaymentResult,\n LayerZeroMessage,\n WaitForDeliveryOptions,\n} from \"./types.js\";\n\n/**\n * Cross-Chain Payment Router\n *\n * Routes payments across chains using USDT0 bridge.\n * Handles fee estimation, bridge execution, and delivery tracking.\n */\nexport class CrossChainPaymentRouter {\n private readonly bridge: Usdt0Bridge;\n private readonly scanClient: LayerZeroScanClient;\n private readonly sourceChain: string;\n\n /**\n * Create a cross-chain payment router\n *\n * @param signer - Wallet signer for bridge operations\n * @param sourceChain - Chain where user's funds are located\n */\n constructor(signer: BridgeSigner, sourceChain: string) {\n this.bridge = new Usdt0Bridge(signer, sourceChain);\n this.scanClient = new LayerZeroScanClient();\n this.sourceChain = sourceChain;\n }\n\n /**\n * Get all bridgeable chains\n *\n * @returns Array of all chain names that support USDT0 bridging\n */\n static getBridgeableChains(): string[] {\n return getBridgeableChains();\n }\n\n /**\n * Route payment across chains\n *\n * This method:\n * 1. Bridges USDT0 from source chain to destination chain\n * 2. Sends funds to the payer's address on destination chain\n * 3. Returns tracking info for monitoring delivery\n *\n * After delivery, the payer can use the bridged funds to pay on the destination chain.\n *\n * @param params - Payment routing parameters\n * @returns Result with transaction hash and tracking info\n */\n async routePayment(params: CrossChainPaymentParams): Promise<CrossChainPaymentResult> {\n // Validate parameters\n this.validateParams(params);\n\n // Execute bridge transaction\n const result = await this.bridge.send({\n fromChain: params.sourceChain,\n toChain: params.destinationChain,\n amount: params.amount,\n recipient: params.payer,\n slippageTolerance: params.slippageTolerance,\n });\n\n return {\n bridgeTxHash: result.txHash,\n messageGuid: result.messageGuid,\n amountBridged: result.amountSent,\n estimatedReceiveAmount: result.amountToReceive,\n sourceChain: params.sourceChain,\n destinationChain: params.destinationChain,\n estimatedDeliveryTime: result.estimatedTime,\n };\n }\n\n /**\n * Get estimated fees for routing a payment\n *\n * @param params - Payment parameters\n * @returns Quote with native fee and estimated receive amount\n */\n async estimateFees(params: CrossChainPaymentParams): Promise<{\n nativeFee: bigint;\n estimatedReceiveAmount: bigint;\n estimatedTime: number;\n }> {\n const quote = await this.bridge.quote({\n fromChain: params.sourceChain,\n toChain: params.destinationChain,\n amount: params.amount,\n recipient: params.payer,\n });\n\n return {\n nativeFee: quote.nativeFee,\n estimatedReceiveAmount: quote.minAmountToReceive,\n estimatedTime: quote.estimatedTime,\n };\n }\n\n /**\n * Track message delivery status\n *\n * @param messageGuid - LayerZero message GUID from routePayment result\n * @returns Current message status\n */\n async trackMessage(messageGuid: string): Promise<LayerZeroMessage> {\n return this.scanClient.getMessage(messageGuid);\n }\n\n /**\n * Wait for payment to be delivered on destination chain\n *\n * @param messageGuid - LayerZero message GUID from routePayment result\n * @param options - Wait options (timeout, poll interval, callbacks)\n * @returns Final message state when delivered\n */\n async waitForDelivery(\n messageGuid: string,\n options?: WaitForDeliveryOptions,\n ): Promise<LayerZeroMessage> {\n return this.scanClient.waitForDelivery(messageGuid, options);\n }\n\n /**\n * Check if routing between two chains is supported\n *\n * @param sourceChain - Source chain name\n * @param destinationChain - Destination chain name\n * @returns True if routing is supported\n */\n canRoute(sourceChain: string, destinationChain: string): boolean {\n return (\n sourceChain !== destinationChain &&\n supportsBridging(sourceChain) &&\n supportsBridging(destinationChain)\n );\n }\n\n /**\n * Get all supported destination chains from source chain\n *\n * @returns Array of chain names that can receive bridged funds\n */\n getSupportedDestinations(): string[] {\n return this.bridge.getSupportedDestinations();\n }\n\n /**\n * Validate routing parameters\n *\n * @param params - The cross-chain payment parameters to validate\n * @throws Error if parameters are invalid or routing is not supported\n */\n private validateParams(params: CrossChainPaymentParams): void {\n if (params.sourceChain !== this.sourceChain) {\n throw new Error(\n `Source chain mismatch: router initialized for \"${this.sourceChain}\" but got \"${params.sourceChain}\"`,\n );\n }\n\n if (!this.canRoute(params.sourceChain, params.destinationChain)) {\n throw new Error(\n `Cannot route payment from \"${params.sourceChain}\" to \"${params.destinationChain}\". ` +\n `Supported chains: ${getBridgeableChains().join(\", \")}`,\n );\n }\n\n if (params.amount <= 0n) {\n throw new Error(\"Amount must be greater than 0\");\n }\n }\n}\n\n/**\n * Create a cross-chain payment router\n *\n * @param signer - Wallet signer for bridge operations\n * @param sourceChain - Chain where funds are located\n * @returns A new CrossChainPaymentRouter instance\n */\nexport function createCrossChainPaymentRouter(\n signer: BridgeSigner,\n sourceChain: string,\n): CrossChainPaymentRouter {\n return new CrossChainPaymentRouter(signer, sourceChain);\n}\n","/**\n * ERC-4337 Account Abstraction Constants\n *\n * Provides constants for ERC-4337 v0.7 implementation including:\n * - EntryPoint contract addresses\n * - Default gas limits\n * - ABI definitions\n *\n * @see https://eips.ethereum.org/EIPS/eip-4337\n */\n\nimport type { Address } from \"viem\";\n\n/**\n * EntryPoint v0.7 contract address (canonical deployment)\n * Deployed on all major EVM chains at the same address\n */\nexport const ENTRYPOINT_V07_ADDRESS: Address = \"0x0000000071727De22E5E9d8BAf0edAc6f37da032\";\n\n/**\n * EntryPoint v0.6 contract address (legacy)\n */\nexport const ENTRYPOINT_V06_ADDRESS: Address = \"0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789\";\n\n/**\n * Default gas limits for UserOperations\n */\nexport const DEFAULT_GAS_LIMITS = {\n /** Gas for account validation */\n verificationGasLimit: 150000n,\n /** Gas for callData execution */\n callGasLimit: 100000n,\n /** Gas paid to bundler for overhead */\n preVerificationGas: 50000n,\n /** Gas for paymaster validation */\n paymasterVerificationGasLimit: 50000n,\n /** Gas for paymaster post-op */\n paymasterPostOpGasLimit: 50000n,\n} as const;\n\n/**\n * EntryPoint v0.7 ABI (essential functions)\n */\nexport const ENTRYPOINT_V07_ABI = [\n {\n inputs: [\n {\n components: [\n { name: \"sender\", type: \"address\" },\n { name: \"nonce\", type: \"uint256\" },\n { name: \"initCode\", type: \"bytes\" },\n { name: \"callData\", type: \"bytes\" },\n { name: \"accountGasLimits\", type: \"bytes32\" },\n { name: \"preVerificationGas\", type: \"uint256\" },\n { name: \"gasFees\", type: \"bytes32\" },\n { name: \"paymasterAndData\", type: \"bytes\" },\n { name: \"signature\", type: \"bytes\" },\n ],\n name: \"ops\",\n type: \"tuple[]\",\n },\n { name: \"beneficiary\", type: \"address\" },\n ],\n name: \"handleOps\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [{ name: \"sender\", type: \"address\" }],\n name: \"getNonce\",\n outputs: [{ name: \"nonce\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"sender\", type: \"address\" },\n { name: \"key\", type: \"uint192\" },\n ],\n name: \"getNonce\",\n outputs: [{ name: \"nonce\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n {\n components: [\n { name: \"sender\", type: \"address\" },\n { name: \"nonce\", type: \"uint256\" },\n { name: \"initCode\", type: \"bytes\" },\n { name: \"callData\", type: \"bytes\" },\n { name: \"accountGasLimits\", type: \"bytes32\" },\n { name: \"preVerificationGas\", type: \"uint256\" },\n { name: \"gasFees\", type: \"bytes32\" },\n { name: \"paymasterAndData\", type: \"bytes\" },\n { name: \"signature\", type: \"bytes\" },\n ],\n name: \"userOp\",\n type: \"tuple\",\n },\n ],\n name: \"getUserOpHash\",\n outputs: [{ name: \"\", type: \"bytes32\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const;\n\n/**\n * IAccount interface ABI (smart wallet validation)\n */\nexport const ACCOUNT_ABI = [\n {\n inputs: [\n {\n components: [\n { name: \"sender\", type: \"address\" },\n { name: \"nonce\", type: \"uint256\" },\n { name: \"initCode\", type: \"bytes\" },\n { name: \"callData\", type: \"bytes\" },\n { name: \"accountGasLimits\", type: \"bytes32\" },\n { name: \"preVerificationGas\", type: \"uint256\" },\n { name: \"gasFees\", type: \"bytes32\" },\n { name: \"paymasterAndData\", type: \"bytes\" },\n { name: \"signature\", type: \"bytes\" },\n ],\n name: \"userOp\",\n type: \"tuple\",\n },\n { name: \"userOpHash\", type: \"bytes32\" },\n { name: \"missingAccountFunds\", type: \"uint256\" },\n ],\n name: \"validateUserOp\",\n outputs: [{ name: \"validationData\", type: \"uint256\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"dest\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"func\", type: \"bytes\" },\n ],\n name: \"execute\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"dest\", type: \"address[]\" },\n { name: \"value\", type: \"uint256[]\" },\n { name: \"func\", type: \"bytes[]\" },\n ],\n name: \"executeBatch\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n\n/**\n * Bundler JSON-RPC method names\n */\nexport const BUNDLER_METHODS = {\n sendUserOperation: \"eth_sendUserOperation\",\n estimateUserOperationGas: \"eth_estimateUserOperationGas\",\n getUserOperationByHash: \"eth_getUserOperationByHash\",\n getUserOperationReceipt: \"eth_getUserOperationReceipt\",\n supportedEntryPoints: \"eth_supportedEntryPoints\",\n chainId: \"eth_chainId\",\n} as const;\n\n/**\n * Common paymaster types\n */\nexport enum PaymasterType {\n /** No paymaster - user pays gas */\n None = \"none\",\n /** Verifying paymaster with off-chain signature */\n Verifying = \"verifying\",\n /** Token paymaster - pay gas with ERC20 */\n Token = \"token\",\n /** Sponsoring paymaster - third party pays */\n Sponsoring = \"sponsoring\",\n}\n\n/**\n * Pack verification and call gas limits into bytes32\n *\n * @param verificationGasLimit - The verification gas limit\n * @param callGasLimit - The call gas limit\n * @returns Packed bytes32 with gas limits\n */\nexport function packAccountGasLimits(\n verificationGasLimit: bigint,\n callGasLimit: bigint,\n): `0x${string}` {\n // First 16 bytes: verification gas limit\n // Last 16 bytes: call gas limit\n const verificationHex = verificationGasLimit.toString(16).padStart(32, \"0\");\n const callHex = callGasLimit.toString(16).padStart(32, \"0\");\n return `0x${verificationHex}${callHex}` as `0x${string}`;\n}\n\n/**\n * Unpack account gas limits from bytes32\n *\n * @param packed - The packed bytes32 containing gas limits\n * @returns Object containing verificationGasLimit and callGasLimit\n */\nexport function unpackAccountGasLimits(packed: `0x${string}`): {\n verificationGasLimit: bigint;\n callGasLimit: bigint;\n} {\n const hex = packed.slice(2);\n const verificationHex = hex.slice(0, 32);\n const callHex = hex.slice(32, 64);\n return {\n verificationGasLimit: BigInt(\"0x\" + verificationHex),\n callGasLimit: BigInt(\"0x\" + callHex),\n };\n}\n\n/**\n * Pack max priority fee and max fee per gas into bytes32\n *\n * @param maxPriorityFeePerGas - The max priority fee per gas (tip)\n * @param maxFeePerGas - The max fee per gas\n * @returns Packed bytes32 with gas fees\n */\nexport function packGasFees(maxPriorityFeePerGas: bigint, maxFeePerGas: bigint): `0x${string}` {\n const priorityHex = maxPriorityFeePerGas.toString(16).padStart(32, \"0\");\n const maxHex = maxFeePerGas.toString(16).padStart(32, \"0\");\n return `0x${priorityHex}${maxHex}` as `0x${string}`;\n}\n\n/**\n * Unpack gas fees from bytes32\n *\n * @param packed - The packed bytes32 containing gas fees\n * @returns Object containing maxPriorityFeePerGas and maxFeePerGas\n */\nexport function unpackGasFees(packed: `0x${string}`): {\n maxPriorityFeePerGas: bigint;\n maxFeePerGas: bigint;\n} {\n const hex = packed.slice(2);\n const priorityHex = hex.slice(0, 32);\n const maxHex = hex.slice(32, 64);\n return {\n maxPriorityFeePerGas: BigInt(\"0x\" + priorityHex),\n maxFeePerGas: BigInt(\"0x\" + maxHex),\n };\n}\n","/**\n * ERC-4337 UserOperation Builder\n *\n * Builds UserOperations from transaction intents for ERC-4337 v0.7.\n * Handles gas estimation, nonce management, and operation packing.\n */\n\nimport type { Address, Hex, PublicClient } from \"viem\";\nimport { concat, pad, toHex } from \"viem\";\nimport type {\n UserOperation,\n PackedUserOperation,\n SmartAccountSigner,\n TransactionIntent,\n GasEstimate,\n PaymasterData,\n} from \"./types.js\";\nimport {\n ENTRYPOINT_V07_ADDRESS,\n ENTRYPOINT_V07_ABI,\n DEFAULT_GAS_LIMITS,\n packAccountGasLimits,\n packGasFees,\n} from \"./constants.js\";\n\n/**\n * Builder configuration\n */\nexport interface UserOpBuilderOptions {\n /** EntryPoint address (defaults to v0.7) */\n entryPoint?: Address;\n /** Default gas multiplier for safety margin */\n gasMultiplier?: number;\n}\n\n/**\n * UserOperation Builder for creating and packing operations\n */\nexport class UserOpBuilder {\n private readonly entryPoint: Address;\n private readonly gasMultiplier: number;\n\n /**\n * Create a new UserOpBuilder instance\n *\n * @param options - Optional configuration for the builder\n */\n constructor(options: UserOpBuilderOptions = {}) {\n this.entryPoint = options.entryPoint ?? ENTRYPOINT_V07_ADDRESS;\n this.gasMultiplier = options.gasMultiplier ?? 1.2;\n }\n\n /**\n * Build a UserOperation from a transaction intent\n *\n * @param signer - The smart account signer\n * @param intent - The transaction intent to execute\n * @param client - The public client for chain interaction\n * @param gasEstimate - Optional gas estimates (uses defaults if not provided)\n * @param paymaster - Optional paymaster data for sponsored transactions\n * @returns A UserOperation ready for signing\n */\n async buildUserOp(\n signer: SmartAccountSigner,\n intent: TransactionIntent,\n client: PublicClient,\n gasEstimate?: GasEstimate,\n paymaster?: PaymasterData,\n ): Promise<UserOperation> {\n const sender = await signer.getAddress();\n const nonce = await this.getNonce(client, sender);\n const isDeployed = await signer.isDeployed();\n const initCode = isDeployed ? \"0x\" : await signer.getInitCode();\n\n // Encode the call data for the smart account's execute function\n const callData = signer.encodeExecute(intent.to, intent.value ?? 0n, intent.data ?? \"0x\");\n\n // Get gas prices from the chain\n const { maxFeePerGas, maxPriorityFeePerGas } = await this.getGasPrices(client);\n\n // Use provided gas estimate or defaults\n const gas = gasEstimate ?? DEFAULT_GAS_LIMITS;\n\n // Apply safety multiplier to gas limits\n const verificationGasLimit = this.applyMultiplier(gas.verificationGasLimit);\n const callGasLimit = this.applyMultiplier(gas.callGasLimit);\n const preVerificationGas = this.applyMultiplier(gas.preVerificationGas);\n\n // Build paymaster data if provided\n const paymasterAndData = paymaster ? this.encodePaymasterData(paymaster) : (\"0x\" as Hex);\n\n return {\n sender,\n nonce,\n initCode: initCode as Hex,\n callData,\n verificationGasLimit,\n callGasLimit,\n preVerificationGas,\n maxPriorityFeePerGas,\n maxFeePerGas,\n paymasterAndData,\n signature: \"0x\" as Hex, // Will be filled after signing\n };\n }\n\n /**\n * Build a batch UserOperation from multiple transaction intents\n *\n * @param signer - The smart account signer\n * @param intents - Array of transaction intents to execute\n * @param client - The public client for chain interaction\n * @param gasEstimate - Optional gas estimates (uses defaults if not provided)\n * @param paymaster - Optional paymaster data for sponsored transactions\n * @returns A UserOperation ready for signing\n */\n async buildBatchUserOp(\n signer: SmartAccountSigner,\n intents: TransactionIntent[],\n client: PublicClient,\n gasEstimate?: GasEstimate,\n paymaster?: PaymasterData,\n ): Promise<UserOperation> {\n const sender = await signer.getAddress();\n const nonce = await this.getNonce(client, sender);\n const isDeployed = await signer.isDeployed();\n const initCode = isDeployed ? \"0x\" : await signer.getInitCode();\n\n // Encode batch call data\n const targets = intents.map(i => i.to);\n const values = intents.map(i => i.value ?? 0n);\n const datas = intents.map(i => (i.data ?? \"0x\") as Hex);\n const callData = signer.encodeExecuteBatch(targets, values, datas);\n\n // Get gas prices\n const { maxFeePerGas, maxPriorityFeePerGas } = await this.getGasPrices(client);\n\n // Use provided gas estimate or defaults (with higher limits for batch)\n const gas = gasEstimate ?? {\n verificationGasLimit: DEFAULT_GAS_LIMITS.verificationGasLimit,\n callGasLimit: DEFAULT_GAS_LIMITS.callGasLimit * BigInt(intents.length),\n preVerificationGas: DEFAULT_GAS_LIMITS.preVerificationGas,\n };\n\n const verificationGasLimit = this.applyMultiplier(gas.verificationGasLimit);\n const callGasLimit = this.applyMultiplier(gas.callGasLimit);\n const preVerificationGas = this.applyMultiplier(gas.preVerificationGas);\n\n const paymasterAndData = paymaster ? this.encodePaymasterData(paymaster) : (\"0x\" as Hex);\n\n return {\n sender,\n nonce,\n initCode: initCode as Hex,\n callData,\n verificationGasLimit,\n callGasLimit,\n preVerificationGas,\n maxPriorityFeePerGas,\n maxFeePerGas,\n paymasterAndData,\n signature: \"0x\" as Hex,\n };\n }\n\n /**\n * Pack a UserOperation for on-chain submission (v0.7 format)\n *\n * @param userOp - The UserOperation to pack\n * @returns The packed UserOperation for on-chain submission\n */\n packUserOp(userOp: UserOperation): PackedUserOperation {\n return {\n sender: userOp.sender,\n nonce: userOp.nonce,\n initCode: userOp.initCode,\n callData: userOp.callData,\n accountGasLimits: packAccountGasLimits(userOp.verificationGasLimit, userOp.callGasLimit),\n preVerificationGas: userOp.preVerificationGas,\n gasFees: packGasFees(userOp.maxPriorityFeePerGas, userOp.maxFeePerGas),\n paymasterAndData: userOp.paymasterAndData,\n signature: userOp.signature,\n };\n }\n\n /**\n * Compute the UserOperation hash for signing\n *\n * @param userOp - The UserOperation to hash\n * @param client - The public client for chain interaction\n * @param _ - The chain ID (reserved for future use)\n * @returns The UserOperation hash\n */\n async getUserOpHash(userOp: UserOperation, client: PublicClient, _: number): Promise<Hex> {\n const packed = this.packUserOp(userOp);\n\n // Convert to the tuple format expected by the ABI\n const userOpTuple = {\n sender: packed.sender,\n nonce: packed.nonce,\n initCode: packed.initCode,\n callData: packed.callData,\n accountGasLimits: packed.accountGasLimits as `0x${string}`,\n preVerificationGas: packed.preVerificationGas,\n gasFees: packed.gasFees as `0x${string}`,\n paymasterAndData: packed.paymasterAndData,\n signature: packed.signature,\n } as const;\n\n // Call EntryPoint's getUserOpHash\n const hash = await client.readContract({\n address: this.entryPoint,\n abi: ENTRYPOINT_V07_ABI,\n functionName: \"getUserOpHash\",\n args: [userOpTuple],\n });\n\n return hash as Hex;\n }\n\n /**\n * Sign a UserOperation\n *\n * @param userOp - The UserOperation to sign\n * @param signer - The smart account signer\n * @param client - The public client for chain interaction\n * @param chainId - The chain ID for the signature\n * @returns The UserOperation with signature attached\n */\n async signUserOp(\n userOp: UserOperation,\n signer: SmartAccountSigner,\n client: PublicClient,\n chainId: number,\n ): Promise<UserOperation> {\n const userOpHash = await this.getUserOpHash(userOp, client, chainId);\n const signature = await signer.signUserOpHash(userOpHash);\n\n return {\n ...userOp,\n signature,\n };\n }\n\n /**\n * Get the nonce for an account from EntryPoint\n *\n * @param client - The public client for chain interaction\n * @param sender - The smart account address\n * @returns The current nonce for the account\n */\n private async getNonce(client: PublicClient, sender: Address): Promise<bigint> {\n try {\n const nonce = await client.readContract({\n address: this.entryPoint,\n abi: ENTRYPOINT_V07_ABI,\n functionName: \"getNonce\",\n args: [sender, 0n], // Use key 0 for default nonce space\n });\n return nonce as bigint;\n } catch {\n // Account may not exist yet, return 0\n return 0n;\n }\n }\n\n /**\n * Get current gas prices from the chain\n *\n * @param client - The public client for chain interaction\n * @returns The current gas prices for EIP-1559 transactions\n */\n private async getGasPrices(\n client: PublicClient,\n ): Promise<{ maxFeePerGas: bigint; maxPriorityFeePerGas: bigint }> {\n const block = await client.getBlock({ blockTag: \"latest\" });\n const baseFee = block.baseFeePerGas ?? 0n;\n\n // Use EIP-1559 pricing\n const maxPriorityFeePerGas = 1_500_000_000n; // 1.5 gwei default tip\n const maxFeePerGas = baseFee * 2n + maxPriorityFeePerGas;\n\n return { maxFeePerGas, maxPriorityFeePerGas };\n }\n\n /**\n * Apply gas multiplier for safety margin\n *\n * @param gas - The gas amount to multiply\n * @returns The gas amount with safety margin applied\n */\n private applyMultiplier(gas: bigint): bigint {\n return BigInt(Math.ceil(Number(gas) * this.gasMultiplier));\n }\n\n /**\n * Encode paymaster data for the UserOperation\n *\n * @param paymaster - The paymaster configuration\n * @returns The encoded paymaster data\n */\n private encodePaymasterData(paymaster: PaymasterData): Hex {\n // Pack: paymaster (20 bytes) + verification gas (16 bytes) + postOp gas (16 bytes) + data\n const paymasterAddress = paymaster.paymaster;\n const verificationGas = pad(toHex(paymaster.paymasterVerificationGasLimit), {\n size: 16,\n });\n const postOpGas = pad(toHex(paymaster.paymasterPostOpGasLimit), { size: 16 });\n\n return concat([paymasterAddress, verificationGas, postOpGas, paymaster.paymasterData]) as Hex;\n }\n}\n\n/**\n * Create a UserOpBuilder instance\n *\n * @param options - Optional configuration for the builder\n * @returns A new UserOpBuilder instance\n */\nexport function createUserOpBuilder(options?: UserOpBuilderOptions): UserOpBuilder {\n return new UserOpBuilder(options);\n}\n","/**\n * ERC-4337 Bundler Client\n *\n * Client for interacting with ERC-4337 bundlers via JSON-RPC.\n * Handles UserOperation submission, gas estimation, and receipt polling.\n */\n\nimport type { Address, Hex } from \"viem\";\nimport type {\n UserOperation,\n PackedUserOperation,\n GasEstimate,\n UserOperationReceipt,\n UserOperationResult,\n BundlerConfig,\n} from \"./types.js\";\nimport {\n ENTRYPOINT_V07_ADDRESS,\n BUNDLER_METHODS,\n packAccountGasLimits,\n packGasFees,\n} from \"./constants.js\";\n\n/**\n * JSON-RPC request structure\n */\ninterface JsonRpcRequest {\n jsonrpc: \"2.0\";\n id: number;\n method: string;\n params: unknown[];\n}\n\n/**\n * JSON-RPC response structure\n */\ninterface JsonRpcResponse<T = unknown> {\n jsonrpc: \"2.0\";\n id: number;\n result?: T;\n error?: {\n code: number;\n message: string;\n data?: unknown;\n };\n}\n\n/**\n * Bundler error class\n */\nexport class BundlerError extends Error {\n /**\n * Create a new BundlerError\n *\n * @param message - The error message\n * @param code - Optional JSON-RPC error code\n * @param data - Optional additional error data\n */\n constructor(\n message: string,\n public code?: number,\n public data?: unknown,\n ) {\n super(message);\n this.name = \"BundlerError\";\n }\n}\n\n/**\n * Bundler client for submitting UserOperations\n */\nexport class BundlerClient {\n private readonly bundlerUrl: string;\n private readonly entryPoint: Address;\n private requestId: number = 0;\n\n /**\n * Create a new BundlerClient instance\n *\n * @param config - Configuration for the bundler client\n */\n constructor(config: BundlerConfig) {\n this.bundlerUrl = config.bundlerUrl;\n this.entryPoint = config.entryPoint ?? ENTRYPOINT_V07_ADDRESS;\n // Note: chainId from config is available for future use but not currently needed\n void config.chainId;\n }\n\n /**\n * Send a UserOperation to the bundler\n *\n * @param userOp - The UserOperation to send\n * @returns The result containing the userOpHash and a wait function\n */\n async sendUserOperation(userOp: UserOperation): Promise<UserOperationResult> {\n const packed = this.packForRpc(userOp);\n\n const userOpHash = await this.rpcCall<Hex>(BUNDLER_METHODS.sendUserOperation, [\n packed,\n this.entryPoint,\n ]);\n\n return {\n userOpHash,\n wait: () => this.waitForReceipt(userOpHash),\n };\n }\n\n /**\n * Estimate gas for a UserOperation\n *\n * @param userOp - Partial UserOperation with required sender and callData\n * @returns Gas estimates for the UserOperation\n */\n async estimateUserOperationGas(\n userOp: Partial<UserOperation> & {\n sender: Address;\n callData: Hex;\n },\n ): Promise<GasEstimate> {\n // Fill in defaults for estimation\n const estimationOp = {\n sender: userOp.sender,\n nonce: userOp.nonce ?? 0n,\n initCode: userOp.initCode ?? \"0x\",\n callData: userOp.callData,\n verificationGasLimit: userOp.verificationGasLimit ?? 1000000n,\n callGasLimit: userOp.callGasLimit ?? 1000000n,\n preVerificationGas: userOp.preVerificationGas ?? 100000n,\n maxPriorityFeePerGas: userOp.maxPriorityFeePerGas ?? 1000000000n,\n maxFeePerGas: userOp.maxFeePerGas ?? 10000000000n,\n paymasterAndData: userOp.paymasterAndData ?? \"0x\",\n signature:\n userOp.signature ??\n // Dummy signature for estimation\n \"0xfffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c\",\n };\n\n const packed = this.packForRpc(estimationOp as UserOperation);\n\n const result = await this.rpcCall<{\n verificationGasLimit: Hex;\n callGasLimit: Hex;\n preVerificationGas: Hex;\n paymasterVerificationGasLimit?: Hex;\n paymasterPostOpGasLimit?: Hex;\n }>(BUNDLER_METHODS.estimateUserOperationGas, [packed, this.entryPoint]);\n\n return {\n verificationGasLimit: BigInt(result.verificationGasLimit),\n callGasLimit: BigInt(result.callGasLimit),\n preVerificationGas: BigInt(result.preVerificationGas),\n paymasterVerificationGasLimit: result.paymasterVerificationGasLimit\n ? BigInt(result.paymasterVerificationGasLimit)\n : undefined,\n paymasterPostOpGasLimit: result.paymasterPostOpGasLimit\n ? BigInt(result.paymasterPostOpGasLimit)\n : undefined,\n };\n }\n\n /**\n * Get UserOperation by hash\n *\n * @param userOpHash - The hash of the UserOperation to retrieve\n * @returns The UserOperation and EntryPoint, or null if not found\n */\n async getUserOperationByHash(\n userOpHash: Hex,\n ): Promise<{ userOperation: PackedUserOperation; entryPoint: Address } | null> {\n const result = await this.rpcCall<{\n userOperation: PackedUserOperation;\n entryPoint: Address;\n } | null>(BUNDLER_METHODS.getUserOperationByHash, [userOpHash]);\n\n return result;\n }\n\n /**\n * Get UserOperation receipt\n *\n * @param userOpHash - The hash of the UserOperation\n * @returns The receipt, or null if not yet included\n */\n async getUserOperationReceipt(userOpHash: Hex): Promise<UserOperationReceipt | null> {\n const result = await this.rpcCall<{\n userOpHash: Hex;\n sender: Address;\n nonce: Hex;\n paymaster?: Address;\n actualGasCost: Hex;\n actualGasUsed: Hex;\n success: boolean;\n reason?: string;\n receipt: {\n transactionHash: Hex;\n blockNumber: Hex;\n blockHash: Hex;\n };\n } | null>(BUNDLER_METHODS.getUserOperationReceipt, [userOpHash]);\n\n if (!result) return null;\n\n return {\n userOpHash: result.userOpHash,\n sender: result.sender,\n nonce: BigInt(result.nonce),\n paymaster: result.paymaster,\n actualGasCost: BigInt(result.actualGasCost),\n actualGasUsed: BigInt(result.actualGasUsed),\n success: result.success,\n reason: result.reason,\n receipt: {\n transactionHash: result.receipt.transactionHash,\n blockNumber: BigInt(result.receipt.blockNumber),\n blockHash: result.receipt.blockHash,\n },\n };\n }\n\n /**\n * Get supported EntryPoints\n *\n * @returns Array of supported EntryPoint addresses\n */\n async getSupportedEntryPoints(): Promise<Address[]> {\n return this.rpcCall<Address[]>(BUNDLER_METHODS.supportedEntryPoints, []);\n }\n\n /**\n * Get chain ID from bundler\n *\n * @returns The chain ID\n */\n async getChainId(): Promise<number> {\n const result = await this.rpcCall<Hex>(BUNDLER_METHODS.chainId, []);\n return Number(result);\n }\n\n /**\n * Wait for UserOperation receipt with polling\n *\n * @param userOpHash - The hash of the UserOperation to wait for\n * @param options - Polling options\n * @param options.timeout - Maximum time to wait in milliseconds (default: 60000)\n * @param options.pollingInterval - Interval between polls in milliseconds (default: 2000)\n * @returns The UserOperation receipt\n */\n async waitForReceipt(\n userOpHash: Hex,\n options: { timeout?: number; pollingInterval?: number } = {},\n ): Promise<UserOperationReceipt> {\n const timeout = options.timeout ?? 60000; // 60 seconds default\n const pollingInterval = options.pollingInterval ?? 2000; // 2 seconds default\n\n const startTime = Date.now();\n\n while (Date.now() - startTime < timeout) {\n const receipt = await this.getUserOperationReceipt(userOpHash);\n\n if (receipt) {\n return receipt;\n }\n\n await new Promise(resolve => setTimeout(resolve, pollingInterval));\n }\n\n throw new BundlerError(`Timeout waiting for UserOperation receipt: ${userOpHash}`);\n }\n\n /**\n * Pack UserOperation for RPC (convert bigints to hex strings)\n *\n * @param userOp - The UserOperation to pack\n * @returns The packed UserOperation for RPC transmission\n */\n private packForRpc(userOp: UserOperation): Record<string, unknown> {\n return {\n sender: userOp.sender,\n nonce: this.toHex(userOp.nonce),\n initCode: userOp.initCode,\n callData: userOp.callData,\n accountGasLimits: packAccountGasLimits(userOp.verificationGasLimit, userOp.callGasLimit),\n preVerificationGas: this.toHex(userOp.preVerificationGas),\n gasFees: packGasFees(userOp.maxPriorityFeePerGas, userOp.maxFeePerGas),\n paymasterAndData: userOp.paymasterAndData,\n signature: userOp.signature,\n };\n }\n\n /**\n * Convert bigint to hex string\n *\n * @param value - The bigint value to convert\n * @returns The hex string representation\n */\n private toHex(value: bigint): Hex {\n return `0x${value.toString(16)}` as Hex;\n }\n\n /**\n * Make a JSON-RPC call to the bundler\n *\n * @param method - The JSON-RPC method name\n * @param params - The method parameters\n * @returns The result from the bundler\n */\n private async rpcCall<T>(method: string, params: unknown[]): Promise<T> {\n const request: JsonRpcRequest = {\n jsonrpc: \"2.0\",\n id: ++this.requestId,\n method,\n params,\n };\n\n const response = await fetch(this.bundlerUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n throw new BundlerError(`HTTP error: ${response.status} ${response.statusText}`);\n }\n\n const json = (await response.json()) as JsonRpcResponse<T>;\n\n if (json.error) {\n throw new BundlerError(json.error.message, json.error.code, json.error.data);\n }\n\n return json.result as T;\n }\n}\n\n/**\n * Create a BundlerClient instance\n *\n * @param config - Configuration for the bundler client\n * @returns A new BundlerClient instance\n */\nexport function createBundlerClient(config: BundlerConfig): BundlerClient {\n return new BundlerClient(config);\n}\n","/**\n * ERC-4337 Paymaster Client\n *\n * Handles paymaster interactions for gas sponsorship.\n * Supports verifying paymasters (off-chain signature) and\n * sponsoring paymasters (third-party gas payment).\n */\n\nimport type { Address, Hex } from \"viem\";\nimport { concat, pad, toHex } from \"viem\";\nimport type { UserOperation, PaymasterData, PaymasterConfig, GasEstimate } from \"./types.js\";\nimport { DEFAULT_GAS_LIMITS } from \"./constants.js\";\n\n/**\n * Paymaster service response\n */\nexport interface PaymasterResponse {\n /** Paymaster address */\n paymaster: Address;\n /** Paymaster data to include in UserOp */\n paymasterData: Hex;\n /** Gas limits for paymaster operations */\n paymasterVerificationGasLimit: bigint;\n paymasterPostOpGasLimit: bigint;\n}\n\n/**\n * Paymaster sponsor request\n */\nexport interface SponsorRequest {\n /** UserOperation to sponsor (without paymaster data) */\n userOp: Partial<UserOperation>;\n /** Chain ID */\n chainId: number;\n /** EntryPoint address */\n entryPoint: Address;\n /** Optional context for the paymaster */\n context?: Record<string, unknown>;\n}\n\n/**\n * Paymaster client for gas sponsorship\n */\nexport class PaymasterClient {\n private readonly config: PaymasterConfig;\n\n /**\n * Creates a new PaymasterClient instance\n *\n * @param config - Paymaster configuration including type, address, and optional URL\n */\n constructor(config: PaymasterConfig) {\n this.config = config;\n }\n\n /**\n * Get paymaster data for a UserOperation\n *\n * @param userOp - Partial UserOperation to get paymaster data for\n * @param chainId - The chain ID for the operation\n * @param entryPoint - The EntryPoint contract address\n * @param context - Optional context data for the paymaster\n * @returns Paymaster data including address and gas limits\n */\n async getPaymasterData(\n userOp: Partial<UserOperation>,\n chainId: number,\n entryPoint: Address,\n context?: Record<string, unknown>,\n ): Promise<PaymasterData> {\n switch (this.config.type) {\n case \"verifying\":\n return this.getVerifyingPaymasterData(userOp, chainId, entryPoint);\n case \"sponsoring\":\n return this.getSponsoringPaymasterData(userOp, chainId, entryPoint, context);\n case \"token\":\n return this.getTokenPaymasterData(userOp, chainId, entryPoint);\n default:\n throw new Error(`Unknown paymaster type: ${this.config.type}`);\n }\n }\n\n /**\n * Get gas estimates including paymaster gas\n *\n * @param _userOp - Partial UserOperation to estimate gas for (reserved for future use)\n * @param _chainId - The chain ID for the operation (reserved for future use)\n * @returns Gas estimates including paymaster verification and postOp gas\n */\n async estimatePaymasterGas(\n _userOp: Partial<UserOperation>, // eslint-disable-line @typescript-eslint/no-unused-vars\n _chainId: number, // eslint-disable-line @typescript-eslint/no-unused-vars\n ): Promise<GasEstimate> {\n // For most paymasters, use default gas limits\n // This can be overridden by calling the paymaster service\n return {\n verificationGasLimit: DEFAULT_GAS_LIMITS.verificationGasLimit,\n callGasLimit: DEFAULT_GAS_LIMITS.callGasLimit,\n preVerificationGas: DEFAULT_GAS_LIMITS.preVerificationGas,\n paymasterVerificationGasLimit: DEFAULT_GAS_LIMITS.paymasterVerificationGasLimit,\n paymasterPostOpGasLimit: DEFAULT_GAS_LIMITS.paymasterPostOpGasLimit,\n };\n }\n\n /**\n * Check if the paymaster will sponsor this operation\n *\n * @param userOp - Partial UserOperation to check sponsorship for\n * @param chainId - The chain ID for the operation\n * @param entryPoint - The EntryPoint contract address\n * @param context - Optional context data for policy validation\n * @returns True if the paymaster will sponsor the operation\n */\n async willSponsor(\n userOp: Partial<UserOperation>,\n chainId: number,\n entryPoint: Address,\n context?: Record<string, unknown>,\n ): Promise<boolean> {\n if (!this.config.url) {\n // Local paymaster - always sponsors\n return true;\n }\n\n try {\n const response = await fetch(`${this.config.url}/check`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n userOp: this.serializeUserOp(userOp),\n chainId,\n entryPoint,\n context,\n }),\n });\n\n if (!response.ok) return false;\n\n const result = (await response.json()) as { willSponsor: boolean };\n return result.willSponsor;\n } catch {\n return false;\n }\n }\n\n /**\n * Get verifying paymaster data (off-chain signature)\n *\n * @param userOp - Partial UserOperation to get paymaster data for\n * @param chainId - The chain ID for the operation\n * @param entryPoint - The EntryPoint contract address\n * @returns Paymaster data with verification signature\n */\n private async getVerifyingPaymasterData(\n userOp: Partial<UserOperation>,\n chainId: number,\n entryPoint: Address,\n ): Promise<PaymasterData> {\n if (this.config.url) {\n // Call paymaster service for signature\n return this.callPaymasterService(userOp, chainId, entryPoint);\n }\n\n // Local verifying paymaster - return basic data\n // The signature would need to be added by the paymaster owner\n return {\n paymaster: this.config.address,\n paymasterVerificationGasLimit: DEFAULT_GAS_LIMITS.paymasterVerificationGasLimit,\n paymasterPostOpGasLimit: DEFAULT_GAS_LIMITS.paymasterPostOpGasLimit,\n paymasterData: \"0x\" as Hex,\n };\n }\n\n /**\n * Get sponsoring paymaster data (third-party pays)\n *\n * @param userOp - Partial UserOperation to get sponsorship for\n * @param chainId - The chain ID for the operation\n * @param entryPoint - The EntryPoint contract address\n * @param context - Optional context data for sponsorship validation\n * @returns Paymaster data for sponsored operation\n */\n private async getSponsoringPaymasterData(\n userOp: Partial<UserOperation>,\n chainId: number,\n entryPoint: Address,\n context?: Record<string, unknown>,\n ): Promise<PaymasterData> {\n if (!this.config.url) {\n throw new Error(\"Sponsoring paymaster requires a service URL\");\n }\n\n // Call the sponsor API\n const response = await fetch(`${this.config.url}/sponsor`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n userOp: this.serializeUserOp(userOp),\n chainId,\n entryPoint,\n context,\n }),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Paymaster rejected sponsorship: ${error}`);\n }\n\n const result = (await response.json()) as PaymasterResponse;\n\n return {\n paymaster: result.paymaster,\n paymasterVerificationGasLimit: result.paymasterVerificationGasLimit,\n paymasterPostOpGasLimit: result.paymasterPostOpGasLimit,\n paymasterData: result.paymasterData,\n };\n }\n\n /**\n * Get token paymaster data (pay gas with ERC20)\n *\n * @param userOp - Partial UserOperation to get token paymaster data for\n * @param chainId - The chain ID for the operation\n * @param entryPoint - The EntryPoint contract address\n * @returns Paymaster data for ERC20 token payment\n */\n private async getTokenPaymasterData(\n userOp: Partial<UserOperation>,\n chainId: number,\n entryPoint: Address,\n ): Promise<PaymasterData> {\n const tokenAddress = this.config.options?.tokenAddress as Address | undefined;\n if (!tokenAddress) {\n throw new Error(\"Token paymaster requires tokenAddress in options\");\n }\n\n if (this.config.url) {\n // Call paymaster service for token rate and data\n return this.callPaymasterService(userOp, chainId, entryPoint, {\n tokenAddress,\n });\n }\n\n // Return basic token paymaster data\n // The actual rate and validation would be done on-chain\n return {\n paymaster: this.config.address,\n paymasterVerificationGasLimit: DEFAULT_GAS_LIMITS.paymasterVerificationGasLimit,\n paymasterPostOpGasLimit: DEFAULT_GAS_LIMITS.paymasterPostOpGasLimit,\n paymasterData: tokenAddress as Hex, // Token address as data\n };\n }\n\n /**\n * Call paymaster service API\n *\n * @param userOp - Partial UserOperation to send to the service\n * @param chainId - The chain ID for the operation\n * @param entryPoint - The EntryPoint contract address\n * @param context - Optional context data for the service\n * @returns Paymaster data from the service response\n */\n private async callPaymasterService(\n userOp: Partial<UserOperation>,\n chainId: number,\n entryPoint: Address,\n context?: Record<string, unknown>,\n ): Promise<PaymasterData> {\n if (!this.config.url) {\n throw new Error(\"Paymaster service URL not configured\");\n }\n\n const response = await fetch(`${this.config.url}/getPaymasterData`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n userOp: this.serializeUserOp(userOp),\n chainId,\n entryPoint,\n context,\n }),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Paymaster service error: ${error}`);\n }\n\n const result = (await response.json()) as PaymasterResponse;\n\n return {\n paymaster: result.paymaster,\n paymasterVerificationGasLimit: BigInt(result.paymasterVerificationGasLimit),\n paymasterPostOpGasLimit: BigInt(result.paymasterPostOpGasLimit),\n paymasterData: result.paymasterData,\n };\n }\n\n /**\n * Serialize UserOperation for API calls\n *\n * @param userOp - Partial UserOperation to serialize\n * @returns Serialized UserOperation with hex-encoded values\n */\n private serializeUserOp(userOp: Partial<UserOperation>): Record<string, string> {\n const result: Record<string, string> = {};\n\n if (userOp.sender) result.sender = userOp.sender;\n if (userOp.nonce !== undefined) result.nonce = `0x${userOp.nonce.toString(16)}`;\n if (userOp.initCode) result.initCode = userOp.initCode;\n if (userOp.callData) result.callData = userOp.callData;\n if (userOp.verificationGasLimit !== undefined)\n result.verificationGasLimit = `0x${userOp.verificationGasLimit.toString(16)}`;\n if (userOp.callGasLimit !== undefined)\n result.callGasLimit = `0x${userOp.callGasLimit.toString(16)}`;\n if (userOp.preVerificationGas !== undefined)\n result.preVerificationGas = `0x${userOp.preVerificationGas.toString(16)}`;\n if (userOp.maxPriorityFeePerGas !== undefined)\n result.maxPriorityFeePerGas = `0x${userOp.maxPriorityFeePerGas.toString(16)}`;\n if (userOp.maxFeePerGas !== undefined)\n result.maxFeePerGas = `0x${userOp.maxFeePerGas.toString(16)}`;\n if (userOp.paymasterAndData) result.paymasterAndData = userOp.paymasterAndData;\n if (userOp.signature) result.signature = userOp.signature;\n\n return result;\n }\n}\n\n/**\n * Create a PaymasterClient instance\n *\n * @param config - Paymaster configuration including type, address, and optional URL\n * @returns A new PaymasterClient instance\n */\nexport function createPaymasterClient(config: PaymasterConfig): PaymasterClient {\n return new PaymasterClient(config);\n}\n\n/**\n * Encode paymaster data for inclusion in UserOperation\n *\n * @param data - Paymaster data to encode\n * @returns Encoded paymasterAndData hex string\n */\nexport function encodePaymasterAndData(data: PaymasterData): Hex {\n return concat([\n data.paymaster,\n pad(toHex(data.paymasterVerificationGasLimit), { size: 16 }),\n pad(toHex(data.paymasterPostOpGasLimit), { size: 16 }),\n data.paymasterData,\n ]) as Hex;\n}\n\n/**\n * Decode paymaster and data from UserOperation\n *\n * @param paymasterAndData - Encoded paymasterAndData hex string\n * @returns Decoded PaymasterData or null if invalid/empty\n */\nexport function decodePaymasterAndData(paymasterAndData: Hex): PaymasterData | null {\n if (paymasterAndData === \"0x\" || paymasterAndData.length < 86) {\n return null;\n }\n\n // 20 bytes address + 16 bytes verification gas + 16 bytes postOp gas = 52 bytes = 104 hex chars + 0x\n const paymaster = `0x${paymasterAndData.slice(2, 42)}` as Address;\n const paymasterVerificationGasLimit = BigInt(`0x${paymasterAndData.slice(42, 74)}`);\n const paymasterPostOpGasLimit = BigInt(`0x${paymasterAndData.slice(74, 106)}`);\n const paymasterData = `0x${paymasterAndData.slice(106)}` as Hex;\n\n return {\n paymaster,\n paymasterVerificationGasLimit,\n paymasterPostOpGasLimit,\n paymasterData,\n };\n}\n","/**\n * Pimlico Paymaster Client\n *\n * Paymaster integration with Pimlico's sponsorship service.\n * Supports:\n * - Verifying paymaster with off-chain signatures\n * - ERC-20 token payments\n * - Spending policies and limits\n *\n * @see https://docs.pimlico.io/paymaster\n */\n\nimport type { Address, Hex } from \"viem\";\nimport { concat, pad, toHex } from \"viem\";\nimport type { UserOperation, PaymasterData, GasEstimate } from \"../types.js\";\nimport {\n ENTRYPOINT_V07_ADDRESS,\n DEFAULT_GAS_LIMITS,\n packAccountGasLimits,\n packGasFees,\n} from \"../constants.js\";\n\n/**\n * Pimlico paymaster type\n */\nexport type PimlicoPaymasterType = \"verifying\" | \"erc20\";\n\n/**\n * Pimlico sponsorship policy\n */\nexport interface PimlicoPolicy {\n /** Maximum gas cost per operation (in wei) */\n maxGasCost?: bigint;\n /** Maximum operations per user per day */\n maxOpsPerUser?: number;\n /** Allowed sender addresses */\n allowedSenders?: Address[];\n /** Allowed target contracts */\n allowedTargets?: Address[];\n}\n\n/**\n * Pimlico paymaster configuration\n */\nexport interface PimlicoPaymasterConfig {\n /** Pimlico API key */\n apiKey: string;\n /** Chain ID */\n chainId: number;\n /** Paymaster type */\n type?: PimlicoPaymasterType;\n /** Token address for ERC-20 paymaster */\n tokenAddress?: Address;\n /** Sponsorship policy */\n policy?: PimlicoPolicy;\n /** Custom paymaster URL (optional) */\n paymasterUrl?: string;\n}\n\n/**\n * Pimlico sponsor result\n */\nexport interface PimlicoSponsorResult {\n /** Paymaster address */\n paymaster: Address;\n /** Packed paymaster data for UserOp */\n paymasterAndData: Hex;\n /** Gas estimates */\n callGasLimit: bigint;\n verificationGasLimit: bigint;\n preVerificationGas: bigint;\n paymasterVerificationGasLimit: bigint;\n paymasterPostOpGasLimit: bigint;\n}\n\n/**\n * Pimlico paymaster client\n */\nexport class PimlicoPaymaster {\n private readonly paymasterUrl: string;\n private readonly type: PimlicoPaymasterType;\n private readonly tokenAddress?: Address;\n\n /**\n * Creates a new Pimlico paymaster client\n *\n * @param config - Pimlico paymaster configuration including API key and type\n */\n constructor(config: PimlicoPaymasterConfig) {\n this.type = config.type ?? \"verifying\";\n this.tokenAddress = config.tokenAddress;\n this.paymasterUrl =\n config.paymasterUrl ??\n `https://api.pimlico.io/v2/${config.chainId}/rpc?apikey=${config.apiKey}`;\n }\n\n /**\n * Sponsor a UserOperation\n * Returns paymaster data to include in the UserOp\n *\n * @param userOp - Partial UserOperation with sender and callData required\n * @param options - Optional sponsorship options\n * @param options.gasOverrides - Override gas limit estimates\n * @returns Sponsorship result with paymaster data and gas estimates\n */\n async sponsorUserOperation(\n userOp: Partial<UserOperation> & {\n sender: Address;\n callData: Hex;\n },\n options?: {\n /** Override gas limits */\n gasOverrides?: Partial<GasEstimate>;\n },\n ): Promise<PimlicoSponsorResult> {\n const packed = this.packUserOpForSponsorship(userOp);\n\n const params: Record<string, unknown> = {\n entryPoint: ENTRYPOINT_V07_ADDRESS,\n userOperation: packed,\n };\n\n if (this.type === \"erc20\" && this.tokenAddress) {\n params.sponsorshipPolicyId = this.tokenAddress;\n }\n\n const result = await this.rpcCall<{\n paymasterAndData: Hex;\n callGasLimit: Hex;\n verificationGasLimit: Hex;\n preVerificationGas: Hex;\n }>(\"pm_sponsorUserOperation\", [params]);\n\n // Parse paymaster address and gas limits from paymasterAndData\n const paymaster = `0x${result.paymasterAndData.slice(2, 42)}` as Address;\n const paymasterVerificationGasLimit = BigInt(`0x${result.paymasterAndData.slice(42, 74)}`);\n const paymasterPostOpGasLimit = BigInt(`0x${result.paymasterAndData.slice(74, 106)}`);\n\n return {\n paymaster,\n paymasterAndData: result.paymasterAndData,\n callGasLimit: options?.gasOverrides?.callGasLimit ?? BigInt(result.callGasLimit),\n verificationGasLimit:\n options?.gasOverrides?.verificationGasLimit ?? BigInt(result.verificationGasLimit),\n preVerificationGas:\n options?.gasOverrides?.preVerificationGas ?? BigInt(result.preVerificationGas),\n paymasterVerificationGasLimit,\n paymasterPostOpGasLimit,\n };\n }\n\n /**\n * Get paymaster data without gas estimation\n * Useful when gas is already estimated\n *\n * @param userOp - The complete UserOperation to get paymaster data for\n * @returns Paymaster data including address and gas limits\n */\n async getPaymasterData(userOp: UserOperation): Promise<PaymasterData> {\n const result = await this.sponsorUserOperation(userOp);\n\n return {\n paymaster: result.paymaster,\n paymasterVerificationGasLimit: result.paymasterVerificationGasLimit,\n paymasterPostOpGasLimit: result.paymasterPostOpGasLimit,\n paymasterData: `0x${result.paymasterAndData.slice(106)}` as Hex,\n };\n }\n\n /**\n * Check if an operation would be sponsored\n *\n * @param userOp - Partial UserOperation with sender and callData required\n * @returns Object indicating whether sponsorship is available and optional reason\n */\n async willSponsor(\n userOp: Partial<UserOperation> & {\n sender: Address;\n callData: Hex;\n },\n ): Promise<{ sponsored: boolean; reason?: string }> {\n try {\n await this.sponsorUserOperation(userOp);\n return { sponsored: true };\n } catch (error) {\n return {\n sponsored: false,\n reason: error instanceof Error ? error.message : \"Unknown error\",\n };\n }\n }\n\n /**\n * Get token quotes for ERC-20 paymaster\n *\n * @param userOp - Partial UserOperation with sender and callData required\n * @param tokens - Array of token addresses to get quotes for\n * @returns Array of token quotes with max cost and token details\n */\n async getTokenQuotes(\n userOp: Partial<UserOperation> & {\n sender: Address;\n callData: Hex;\n },\n tokens: Address[],\n ): Promise<\n Array<{\n token: Address;\n maxCost: bigint;\n symbol: string;\n decimals: number;\n }>\n > {\n if (this.type !== \"erc20\") {\n throw new Error(\"Token quotes only available for ERC-20 paymaster\");\n }\n\n const packed = this.packUserOpForSponsorship(userOp);\n\n const result = await this.rpcCall<\n Array<{\n token: Address;\n maxCost: Hex;\n symbol: string;\n decimals: number;\n }>\n >(\"pm_getTokenQuotes\", [\n {\n entryPoint: ENTRYPOINT_V07_ADDRESS,\n userOperation: packed,\n tokens,\n },\n ]);\n\n return result.map(quote => ({\n token: quote.token,\n maxCost: BigInt(quote.maxCost),\n symbol: quote.symbol,\n decimals: quote.decimals,\n }));\n }\n\n /**\n * Pack UserOp for sponsorship request\n *\n * @param userOp - Partial UserOperation with sender and callData required\n * @returns Packed UserOperation object for RPC calls\n */\n private packUserOpForSponsorship(\n userOp: Partial<UserOperation> & { sender: Address; callData: Hex },\n ): Record<string, unknown> {\n return {\n sender: userOp.sender,\n nonce: this.toHex(userOp.nonce ?? 0n),\n initCode: userOp.initCode ?? \"0x\",\n callData: userOp.callData,\n accountGasLimits:\n userOp.verificationGasLimit && userOp.callGasLimit\n ? packAccountGasLimits(userOp.verificationGasLimit, userOp.callGasLimit)\n : packAccountGasLimits(\n DEFAULT_GAS_LIMITS.verificationGasLimit,\n DEFAULT_GAS_LIMITS.callGasLimit,\n ),\n preVerificationGas: this.toHex(\n userOp.preVerificationGas ?? DEFAULT_GAS_LIMITS.preVerificationGas,\n ),\n gasFees:\n userOp.maxPriorityFeePerGas && userOp.maxFeePerGas\n ? packGasFees(userOp.maxPriorityFeePerGas, userOp.maxFeePerGas)\n : packGasFees(1000000000n, 10000000000n),\n paymasterAndData: \"0x\",\n signature: userOp.signature ?? getDummySignature(),\n };\n }\n\n /**\n * Convert bigint to hex\n *\n * @param value - The bigint value to convert\n * @returns Hexadecimal string representation\n */\n private toHex(value: bigint): Hex {\n return `0x${value.toString(16)}` as Hex;\n }\n\n /**\n * Make RPC call to Pimlico\n *\n * @param method - The RPC method name to call\n * @param params - Array of parameters for the RPC call\n * @returns The typed result from the RPC call\n */\n private async rpcCall<T>(method: string, params: unknown[]): Promise<T> {\n const response = await fetch(this.paymasterUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: Date.now(),\n method,\n params,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error: ${response.status} ${response.statusText}`);\n }\n\n const json = (await response.json()) as {\n result?: T;\n error?: { code: number; message: string; data?: unknown };\n };\n\n if (json.error) {\n throw new Error(json.error.message);\n }\n\n return json.result as T;\n }\n}\n\n/**\n * Get dummy signature for sponsorship requests\n *\n * @returns A dummy signature hex string for gas estimation\n */\nfunction getDummySignature(): Hex {\n return \"0xfffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c\" as Hex;\n}\n\n/**\n * Encode paymaster and data for UserOperation\n *\n * @param data - Paymaster data to encode\n * @returns Encoded paymasterAndData hex string\n */\nexport function encodePaymasterAndData(data: PaymasterData): Hex {\n return concat([\n data.paymaster,\n pad(toHex(data.paymasterVerificationGasLimit), { size: 16 }),\n pad(toHex(data.paymasterPostOpGasLimit), { size: 16 }),\n data.paymasterData,\n ]) as Hex;\n}\n\n/**\n * Create a Pimlico paymaster client\n *\n * @param config - Pimlico paymaster configuration including API key and type\n * @returns A new PimlicoPaymaster instance\n */\nexport function createPimlicoPaymaster(config: PimlicoPaymasterConfig): PimlicoPaymaster {\n return new PimlicoPaymaster(config);\n}\n","/**\n * Safe Smart Account for ERC-4337\n *\n * Implements SmartAccountSigner using Safe's 4337 module.\n * Supports:\n * - Single-owner and multi-sig configurations\n * - Counterfactual address computation\n * - Safe 4337 module v0.3.0\n *\n * @see https://docs.safe.global/advanced/erc-4337\n */\n\nimport type { Address, Hex, PublicClient, WalletClient } from \"viem\";\nimport {\n encodeFunctionData,\n encodeAbiParameters,\n concat,\n keccak256,\n getContractAddress,\n hexToBytes,\n} from \"viem\";\nimport type { SmartAccountSigner } from \"../types.js\";\n\n/**\n * Safe 4337 module addresses (v0.3.0)\n * Deployed on all major EVM chains at the same addresses\n */\nexport const SAFE_4337_ADDRESSES = {\n /** Safe 4337 Module */\n module: \"0xa581c4A4DB7175302464fF3C06380BC3270b4037\" as Address,\n /** Safe Module Setup */\n moduleSetup: \"0x2dd68b007B46fBe91B9A7c3EDa5A7a1063cB5b47\" as Address,\n /** Safe Singleton */\n singleton: \"0x29fcB43b46531BcA003ddC8FCB67FFE91900C762\" as Address,\n /** Safe Proxy Factory */\n proxyFactory: \"0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67\" as Address,\n /** Safe Fallback Handler */\n fallbackHandler: \"0xfd0732Dc9E303f09fCEf3a7388Ad10A83459Ec99\" as Address,\n /** Add Modules Lib */\n addModulesLib: \"0x8EcD4ec46D4D2a6B64fE960B3D64e8B94B2234eb\" as Address,\n} as const;\n\n/**\n * Safe Proxy Factory ABI (essential functions)\n */\nconst PROXY_FACTORY_ABI = [\n {\n inputs: [\n { name: \"singleton\", type: \"address\" },\n { name: \"initializer\", type: \"bytes\" },\n { name: \"saltNonce\", type: \"uint256\" },\n ],\n name: \"createProxyWithNonce\",\n outputs: [{ name: \"proxy\", type: \"address\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"singleton\", type: \"address\" },\n { name: \"initializer\", type: \"bytes\" },\n { name: \"saltNonce\", type: \"uint256\" },\n ],\n name: \"proxyCreationCode\",\n outputs: [{ name: \"\", type: \"bytes\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const;\n\n/**\n * Safe Singleton ABI (essential functions)\n */\nconst SAFE_ABI = [\n {\n inputs: [\n { name: \"owners\", type: \"address[]\" },\n { name: \"threshold\", type: \"uint256\" },\n { name: \"to\", type: \"address\" },\n { name: \"data\", type: \"bytes\" },\n { name: \"fallbackHandler\", type: \"address\" },\n { name: \"paymentToken\", type: \"address\" },\n { name: \"payment\", type: \"uint256\" },\n { name: \"paymentReceiver\", type: \"address\" },\n ],\n name: \"setup\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"data\", type: \"bytes\" },\n { name: \"operation\", type: \"uint8\" },\n ],\n name: \"execTransactionFromModule\",\n outputs: [{ name: \"success\", type: \"bool\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n\n/**\n * Add Modules Lib ABI\n */\nconst ADD_MODULES_LIB_ABI = [\n {\n inputs: [{ name: \"modules\", type: \"address[]\" }],\n name: \"enableModules\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n\n/**\n * Safe 4337 Module ABI\n */\nconst SAFE_4337_MODULE_ABI = [\n {\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"data\", type: \"bytes\" },\n { name: \"operation\", type: \"uint8\" },\n ],\n name: \"executeUserOp\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"tos\", type: \"address[]\" },\n { name: \"values\", type: \"uint256[]\" },\n { name: \"datas\", type: \"bytes[]\" },\n { name: \"operations\", type: \"uint8[]\" },\n ],\n name: \"executeUserOpBatch\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n\n/**\n * Safe smart account configuration\n */\nexport interface SafeSmartAccountConfig {\n /** Wallet client for signing */\n signer: WalletClient;\n /** Public client for reading chain state */\n publicClient: PublicClient;\n /** Chain ID */\n chainId: number;\n /** Owner addresses (for multi-sig, defaults to signer address) */\n owners?: Address[];\n /** Threshold for multi-sig (defaults to 1) */\n threshold?: number;\n /** Salt nonce for address generation */\n saltNonce?: bigint;\n /** Custom Safe addresses (optional) */\n addresses?: Partial<typeof SAFE_4337_ADDRESSES>;\n}\n\n/**\n * Safe smart account implementing SmartAccountSigner\n */\nexport class SafeSmartAccount implements SmartAccountSigner {\n private readonly signer: WalletClient;\n private readonly publicClient: PublicClient;\n private readonly owners: Address[];\n private readonly threshold: number;\n private readonly saltNonce: bigint;\n private readonly addresses: typeof SAFE_4337_ADDRESSES;\n\n private cachedAddress?: Address;\n private cachedInitCode?: Hex;\n private deploymentChecked = false;\n private isAccountDeployed = false;\n\n /**\n * Create a new SafeSmartAccount instance\n *\n * @param config - Configuration options for the Safe smart account\n */\n constructor(config: SafeSmartAccountConfig) {\n this.signer = config.signer;\n this.publicClient = config.publicClient;\n // Note: chainId from config is available for future use\n void config.chainId;\n this.threshold = config.threshold ?? 1;\n this.saltNonce = config.saltNonce ?? 0n;\n this.addresses = {\n ...SAFE_4337_ADDRESSES,\n ...config.addresses,\n };\n\n // Default to signer address if no owners provided\n if (config.owners && config.owners.length > 0) {\n this.owners = config.owners;\n } else if (config.signer.account?.address) {\n this.owners = [config.signer.account.address];\n } else {\n throw new Error(\"Either owners or signer with account must be provided\");\n }\n\n if (this.threshold > this.owners.length) {\n throw new Error(\"Threshold cannot be greater than number of owners\");\n }\n }\n\n /**\n * Get the smart account address (counterfactual)\n *\n * @returns The counterfactual address of the smart account\n */\n async getAddress(): Promise<Address> {\n if (this.cachedAddress) {\n return this.cachedAddress;\n }\n\n const initCode = await this.getInitCode();\n\n // Extract initializer from init code\n const initializerData = `0x${initCode.slice(2 + 40 * 2)}` as Hex;\n\n // Compute counterfactual address\n const salt = keccak256(\n encodeAbiParameters(\n [{ type: \"bytes32\" }, { type: \"uint256\" }],\n [keccak256(initializerData), this.saltNonce],\n ),\n );\n\n // Get proxy creation code\n const proxyCreationCode = (await this.publicClient.readContract({\n address: this.addresses.proxyFactory,\n abi: PROXY_FACTORY_ABI,\n functionName: \"proxyCreationCode\",\n args: [this.addresses.singleton, initializerData, this.saltNonce],\n })) as Hex;\n\n // Compute CREATE2 address\n this.cachedAddress = getContractAddress({\n bytecode: proxyCreationCode,\n from: this.addresses.proxyFactory,\n opcode: \"CREATE2\",\n salt,\n });\n\n return this.cachedAddress;\n }\n\n /**\n * Sign a UserOperation hash\n *\n * @param userOpHash - The hash of the UserOperation to sign\n * @returns The signature formatted for Safe validation\n */\n async signUserOpHash(userOpHash: Hex): Promise<Hex> {\n if (!this.signer.account) {\n throw new Error(\"Signer account not available\");\n }\n\n // Sign the hash with EIP-712 formatted signature for Safe\n const signature = await this.signer.signMessage({\n account: this.signer.account,\n message: { raw: hexToBytes(userOpHash) },\n });\n\n // Format signature for Safe (add signature type byte)\n // Type 0: EOA signature (most common)\n return concat([signature, \"0x00\"]) as Hex;\n }\n\n /**\n * Get the account's init code for deployment\n *\n * @returns The init code for deploying the Safe, or \"0x\" if already deployed\n */\n async getInitCode(): Promise<Hex> {\n // Check if already deployed\n if (await this.isDeployed()) {\n return \"0x\" as Hex;\n }\n\n if (this.cachedInitCode) {\n return this.cachedInitCode;\n }\n\n // Build Safe setup data with 4337 module\n const setupModulesData = encodeFunctionData({\n abi: ADD_MODULES_LIB_ABI,\n functionName: \"enableModules\",\n args: [[this.addresses.module]],\n });\n\n const safeSetupData = encodeFunctionData({\n abi: SAFE_ABI,\n functionName: \"setup\",\n args: [\n this.owners,\n BigInt(this.threshold),\n this.addresses.addModulesLib, // to: AddModulesLib\n setupModulesData, // data: enableModules([module])\n this.addresses.fallbackHandler,\n \"0x0000000000000000000000000000000000000000\" as Address, // paymentToken\n 0n, // payment\n \"0x0000000000000000000000000000000000000000\" as Address, // paymentReceiver\n ],\n });\n\n // Build factory call data\n const createProxyData = encodeFunctionData({\n abi: PROXY_FACTORY_ABI,\n functionName: \"createProxyWithNonce\",\n args: [this.addresses.singleton, safeSetupData, this.saltNonce],\n });\n\n // Init code = factory address + factory call data\n this.cachedInitCode = concat([this.addresses.proxyFactory, createProxyData]) as Hex;\n\n return this.cachedInitCode;\n }\n\n /**\n * Check if the account is deployed\n *\n * @returns True if the account is deployed on-chain, false otherwise\n */\n async isDeployed(): Promise<boolean> {\n if (this.deploymentChecked) {\n return this.isAccountDeployed;\n }\n\n const address = this.cachedAddress ?? (await this.getAddress());\n const code = await this.publicClient.getCode({ address });\n\n this.deploymentChecked = true;\n this.isAccountDeployed = code !== undefined && code !== \"0x\";\n\n return this.isAccountDeployed;\n }\n\n /**\n * Encode a call to the account's execute function\n *\n * @param target - The target address for the call\n * @param value - The ETH value to send with the call\n * @param data - The calldata to execute\n * @returns The encoded function data for executeUserOp\n */\n encodeExecute(target: Address, value: bigint, data: Hex): Hex {\n return encodeFunctionData({\n abi: SAFE_4337_MODULE_ABI,\n functionName: \"executeUserOp\",\n args: [\n target,\n value,\n data,\n 0, // operation: CALL\n ],\n });\n }\n\n /**\n * Encode a batch call to the account's executeBatch function\n *\n * @param targets - Array of target addresses for each call\n * @param values - Array of ETH values to send with each call\n * @param datas - Array of calldata for each call\n * @returns The encoded function data for executeUserOpBatch\n */\n encodeExecuteBatch(targets: Address[], values: bigint[], datas: Hex[]): Hex {\n if (targets.length !== values.length || targets.length !== datas.length) {\n throw new Error(\"Array lengths must match\");\n }\n\n const operations = targets.map(() => 0); // All CALL operations\n\n return encodeFunctionData({\n abi: SAFE_4337_MODULE_ABI,\n functionName: \"executeUserOpBatch\",\n args: [targets, values, datas, operations],\n });\n }\n\n /**\n * Get the counterfactual address without caching\n *\n * @returns The counterfactual address of the smart account\n */\n async getCounterfactualAddress(): Promise<Address> {\n return this.getAddress();\n }\n\n /**\n * Get the account's nonce from EntryPoint\n *\n * @param entryPoint - The EntryPoint contract address\n * @param key - The nonce key for parallel nonce spaces (defaults to 0n)\n * @returns The current nonce for the account\n */\n async getNonce(entryPoint: Address, key = 0n): Promise<bigint> {\n const address = await this.getAddress();\n\n const nonce = await this.publicClient.readContract({\n address: entryPoint,\n abi: [\n {\n inputs: [\n { name: \"sender\", type: \"address\" },\n { name: \"key\", type: \"uint192\" },\n ],\n name: \"getNonce\",\n outputs: [{ name: \"nonce\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n ],\n functionName: \"getNonce\",\n args: [address, key],\n });\n\n return nonce as bigint;\n }\n\n /**\n * Get the Safe's owners\n *\n * @returns A copy of the owners array\n */\n getOwners(): Address[] {\n return [...this.owners];\n }\n\n /**\n * Get the Safe's threshold\n *\n * @returns The number of required signatures for transactions\n */\n getThreshold(): number {\n return this.threshold;\n }\n\n /**\n * Clear cached values (useful after deployment)\n */\n clearCache(): void {\n this.cachedAddress = undefined;\n this.cachedInitCode = undefined;\n this.deploymentChecked = false;\n this.isAccountDeployed = false;\n }\n}\n\n/**\n * Create a Safe smart account\n *\n * @param config - Configuration options for the Safe smart account\n * @returns A new SafeSmartAccount instance\n */\nexport function createSafeSmartAccount(config: SafeSmartAccountConfig): SafeSmartAccount {\n return new SafeSmartAccount(config);\n}\n","/**\n * ERC-4337 T402 Integration\n *\n * Integrates ERC-4337 Account Abstraction with T402 payment protocol.\n * Enables gasless payment execution via smart accounts and paymasters.\n */\n\nimport type { Address, Hex, PublicClient } from \"viem\";\nimport { encodeFunctionData } from \"viem\";\nimport type {\n SmartAccountSigner,\n TransactionIntent,\n PaymasterConfig,\n BundlerConfig,\n UserOperationResult,\n GasEstimate,\n} from \"./types.js\";\nimport { UserOpBuilder } from \"./builder.js\";\nimport { BundlerClient } from \"./bundler.js\";\nimport { PaymasterClient } from \"./paymaster.js\";\nimport { ENTRYPOINT_V07_ADDRESS } from \"./constants.js\";\n\n/**\n * T402 payment parameters for ERC-4337\n */\nexport interface GaslessPaymentParams {\n /** Token contract address */\n tokenAddress: Address;\n /** Recipient address (resource server/facilitator) */\n to: Address;\n /** Amount to transfer */\n amount: bigint;\n /** Optional: Pre-signed authorization (for EIP-3009 tokens) */\n authorization?: {\n validAfter: bigint;\n validBefore: bigint;\n nonce: Hex;\n signature: Hex;\n };\n}\n\n/**\n * Gasless T402 client configuration\n */\nexport interface GaslessClientConfig {\n /** Smart account signer */\n signer: SmartAccountSigner;\n /** Bundler configuration */\n bundler: BundlerConfig;\n /** Optional paymaster for gas sponsorship */\n paymaster?: PaymasterConfig;\n /** Chain ID */\n chainId: number;\n /** Public client for chain interactions */\n publicClient: PublicClient;\n}\n\n/**\n * ERC20 transfer ABI for building call data\n */\nconst ERC20_TRANSFER_ABI = [\n {\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n name: \"transfer\",\n outputs: [{ name: \"\", type: \"bool\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n\n/**\n * EIP-3009 transferWithAuthorization ABI\n */\nconst EIP3009_TRANSFER_ABI = [\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] as const;\n\n/**\n * Gasless T402 client for executing payments via ERC-4337\n */\nexport class GaslessT402Client {\n private readonly signer: SmartAccountSigner;\n private readonly builder: UserOpBuilder;\n private readonly bundler: BundlerClient;\n private readonly paymaster?: PaymasterClient;\n private readonly chainId: number;\n private readonly publicClient: PublicClient;\n\n /**\n * Creates a new GaslessT402Client instance\n *\n * @param config - Configuration including signer, bundler, paymaster, and chain settings\n */\n constructor(config: GaslessClientConfig) {\n this.signer = config.signer;\n this.builder = new UserOpBuilder();\n this.bundler = new BundlerClient(config.bundler);\n this.paymaster = config.paymaster ? new PaymasterClient(config.paymaster) : undefined;\n this.chainId = config.chainId;\n this.publicClient = config.publicClient;\n }\n\n /**\n * Execute a T402 payment via ERC-4337\n *\n * This submits the payment as a UserOperation which can be:\n * - Sponsored by a paymaster (truly gasless)\n * - Paid from the smart account's balance\n *\n * @param params - Payment parameters including token, recipient, and amount\n * @returns Result containing the user operation hash and wait function\n */\n async executePayment(params: GaslessPaymentParams): Promise<UserOperationResult> {\n // Build the call data based on whether we have an authorization\n const callData = params.authorization\n ? this.buildAuthorizedTransferCallData(params)\n : this.buildTransferCallData(params);\n\n // Create the transaction intent\n const intent: TransactionIntent = {\n to: params.tokenAddress,\n value: 0n,\n data: callData,\n };\n\n // Estimate gas\n const gasEstimate = await this.estimateGas(intent);\n\n // Get paymaster data if configured\n const paymasterData = await this.getPaymasterData(gasEstimate);\n\n // Build the UserOperation\n const userOp = await this.builder.buildUserOp(\n this.signer,\n intent,\n this.publicClient,\n gasEstimate,\n paymasterData,\n );\n\n // Sign the UserOperation\n const signedUserOp = await this.builder.signUserOp(\n userOp,\n this.signer,\n this.publicClient,\n this.chainId,\n );\n\n // Submit to bundler\n return this.bundler.sendUserOperation(signedUserOp);\n }\n\n /**\n * Execute multiple T402 payments in a single UserOperation\n *\n * @param payments - Array of payment parameters to batch together\n * @returns Result containing the user operation hash and wait function\n */\n async executeBatchPayments(payments: GaslessPaymentParams[]): Promise<UserOperationResult> {\n // Build transaction intents for all payments\n const intents: TransactionIntent[] = payments.map(params => ({\n to: params.tokenAddress,\n value: 0n,\n data: params.authorization\n ? this.buildAuthorizedTransferCallData(params)\n : this.buildTransferCallData(params),\n }));\n\n // Estimate gas for batch\n const gasEstimate = await this.estimateBatchGas(intents);\n\n // Get paymaster data\n const paymasterData = await this.getPaymasterData(gasEstimate);\n\n // Build batch UserOperation\n const userOp = await this.builder.buildBatchUserOp(\n this.signer,\n intents,\n this.publicClient,\n gasEstimate,\n paymasterData,\n );\n\n // Sign and submit\n const signedUserOp = await this.builder.signUserOp(\n userOp,\n this.signer,\n this.publicClient,\n this.chainId,\n );\n\n return this.bundler.sendUserOperation(signedUserOp);\n }\n\n /**\n * Check if a payment can be sponsored (gasless)\n *\n * @param params - Payment parameters to check for sponsorship eligibility\n * @returns True if the payment can be sponsored by the paymaster\n */\n async canSponsor(params: GaslessPaymentParams): Promise<boolean> {\n if (!this.paymaster) return false;\n\n const intent: TransactionIntent = {\n to: params.tokenAddress,\n value: 0n,\n data: this.buildTransferCallData(params),\n };\n\n const sender = await this.signer.getAddress();\n\n return this.paymaster.willSponsor(\n { sender, callData: this.signer.encodeExecute(intent.to, 0n, intent.data!) },\n this.chainId,\n ENTRYPOINT_V07_ADDRESS,\n );\n }\n\n /**\n * Get the smart account address\n *\n * @returns The address of the smart account\n */\n async getAccountAddress(): Promise<Address> {\n return this.signer.getAddress();\n }\n\n /**\n * Check if the smart account is deployed\n *\n * @returns True if the smart account contract is deployed on-chain\n */\n async isAccountDeployed(): Promise<boolean> {\n return this.signer.isDeployed();\n }\n\n /**\n * Build call data for a simple ERC20 transfer\n *\n * @param params - Payment parameters including recipient and amount\n * @returns Encoded call data for ERC20 transfer function\n */\n private buildTransferCallData(params: GaslessPaymentParams): Hex {\n return encodeFunctionData({\n abi: ERC20_TRANSFER_ABI,\n functionName: \"transfer\",\n args: [params.to, params.amount],\n });\n }\n\n /**\n * Build call data for an authorized transfer (EIP-3009)\n *\n * @param params - Payment parameters including authorization signature\n * @returns Encoded call data for transferWithAuthorization function\n */\n private buildAuthorizedTransferCallData(params: GaslessPaymentParams): Hex {\n if (!params.authorization) {\n throw new Error(\"Authorization required for authorized transfer\");\n }\n\n // Parse the signature\n const sig = params.authorization.signature;\n const r = `0x${sig.slice(2, 66)}` as Hex;\n const s = `0x${sig.slice(66, 130)}` as Hex;\n const v = parseInt(sig.slice(130, 132), 16);\n\n return encodeFunctionData({\n abi: EIP3009_TRANSFER_ABI,\n functionName: \"transferWithAuthorization\",\n args: [\n params.to, // from (will be overwritten by smart account)\n params.to,\n params.amount,\n params.authorization.validAfter,\n params.authorization.validBefore,\n params.authorization.nonce,\n v,\n r,\n s,\n ],\n });\n }\n\n /**\n * Estimate gas for a single transaction\n *\n * @param intent - Transaction intent with target, value, and data\n * @returns Gas estimates for the UserOperation\n */\n private async estimateGas(intent: TransactionIntent): Promise<GasEstimate> {\n const sender = await this.signer.getAddress();\n const callData = this.signer.encodeExecute(intent.to, intent.value ?? 0n, intent.data ?? \"0x\");\n\n try {\n return await this.bundler.estimateUserOperationGas({\n sender,\n callData,\n });\n } catch {\n // Return defaults if estimation fails\n return {\n verificationGasLimit: 150000n,\n callGasLimit: 100000n,\n preVerificationGas: 50000n,\n };\n }\n }\n\n /**\n * Estimate gas for a batch transaction\n *\n * @param intents - Array of transaction intents to batch\n * @returns Gas estimates for the batched UserOperation\n */\n private async estimateBatchGas(intents: TransactionIntent[]): Promise<GasEstimate> {\n const sender = await this.signer.getAddress();\n const callData = this.signer.encodeExecuteBatch(\n intents.map(i => i.to),\n intents.map(i => i.value ?? 0n),\n intents.map(i => (i.data ?? \"0x\") as Hex),\n );\n\n try {\n return await this.bundler.estimateUserOperationGas({\n sender,\n callData,\n });\n } catch {\n // Return defaults with multiplier for batch size\n return {\n verificationGasLimit: 150000n,\n callGasLimit: 100000n * BigInt(intents.length),\n preVerificationGas: 50000n,\n };\n }\n }\n\n /**\n * Get paymaster data if configured\n *\n * @param _ - Gas estimates (unused but kept for potential future use)\n * @returns Paymaster data or undefined if no paymaster configured\n */\n private async getPaymasterData(_: GasEstimate): Promise<\n | {\n paymaster: Address;\n paymasterVerificationGasLimit: bigint;\n paymasterPostOpGasLimit: bigint;\n paymasterData: Hex;\n }\n | undefined\n > {\n if (!this.paymaster) return undefined;\n\n const sender = await this.signer.getAddress();\n\n return this.paymaster.getPaymasterData({ sender }, this.chainId, ENTRYPOINT_V07_ADDRESS);\n }\n}\n\n/**\n * Create a GaslessT402Client instance\n *\n * @param config - Configuration including signer, bundler, paymaster, and chain settings\n * @returns A new GaslessT402Client instance\n */\nexport function createGaslessT402Client(config: GaslessClientConfig): GaslessT402Client {\n return new GaslessT402Client(config);\n}\n"],"mappings":"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","names":["ExactLegacyEvmScheme","getAddress","ExactLegacyEvmScheme","getAddress","PaymasterType","concat","pad","toHex","concat","pad","toHex","concat","pad","toHex","concat","keccak256","encodeFunctionData","encodeFunctionData"]}