@t402/evm 2.0.1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.js +9 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.mjs +16 -3
- package/dist/esm/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/esm/index.mjs.map
CHANGED
|
@@ -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/constants.ts","../../src/bridge/client.ts","../../src/erc4337/constants.ts","../../src/erc4337/builder.ts","../../src/erc4337/bundler.ts","../../src/erc4337/paymaster.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 * 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 * 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 {\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} from \"./types.js\";\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 return {\n txHash,\n messageGuid: \"0x\" + \"0\".repeat(64) as `0x${string}`, // Would be extracted from event logs\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 * 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 * 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 * 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","encodeFunctionData","encodeFunctionData"]}
|
|
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/constants.ts","../../src/bridge/client.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 * 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 * 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 {\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} from \"./types.js\";\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 return {\n txHash,\n messageGuid: \"0x\" + \"0\".repeat(64) as `0x${string}`, // Would be extracted from event logs\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 * 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 * 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"]}
|