{"version":3,"sources":["../../src/shared/extensions/builderCode.ts","../../src/exact/extensions.ts","../../src/shared/extensions/gasSponsoring.ts","../../src/exact/client/eip2612.ts","../../src/exact/client/erc20approval.ts","../../src/shared/rpc.ts"],"sourcesContent":["import type {\n  FacilitatorContext,\n  FacilitatorExtension,\n  PaymentPayload,\n  PaymentRequirements,\n} from \"@x402/core/types\";\nimport type { Hex } from \"viem\";\n\nexport const BUILDER_CODE_KEY = \"builder-code\" as const;\n\nexport interface DataSuffixContext {\n  paymentPayload: PaymentPayload;\n  paymentRequirements: PaymentRequirements;\n}\n\nexport interface BuilderCodeFacilitatorExtension extends FacilitatorExtension {\n  key: typeof BUILDER_CODE_KEY;\n  buildDataSuffix?(ctx: DataSuffixContext): Hex | undefined | Promise<Hex | undefined>;\n}\n\ntype DataSuffixResolver = (\n  context: FacilitatorContext,\n  ctx: DataSuffixContext,\n) => Promise<Hex | undefined>;\n\nconst BUILDER_CODE_RESOLVER: DataSuffixResolver = async (context, ctx) => {\n  const ext = context.getExtension<BuilderCodeFacilitatorExtension>(BUILDER_CODE_KEY);\n  if (!ext?.buildDataSuffix) {\n    return undefined;\n  }\n\n  return ext.buildDataSuffix(ctx);\n};\n\nconst DATA_SUFFIX_RESOLVERS: DataSuffixResolver[] = [BUILDER_CODE_RESOLVER];\n\n/**\n * Resolves and concatenates data suffixes from registered extensions.\n *\n * @param context - Facilitator context with registered extensions\n * @param ctx - Data suffix context passed to extension resolvers\n * @returns Hex-encoded suffix to append to settlement calldata, or undefined if none\n */\nexport async function resolveDataSuffix(\n  context: FacilitatorContext | undefined,\n  ctx: DataSuffixContext,\n): Promise<Hex | undefined> {\n  if (!context) {\n    return undefined;\n  }\n\n  const parts: Hex[] = [];\n  for (const resolver of DATA_SUFFIX_RESOLVERS) {\n    const suffix = await resolver(context, ctx);\n    if (suffix && suffix !== \"0x\" && suffix.length > 2) {\n      parts.push(suffix);\n    }\n  }\n\n  if (parts.length === 0) {\n    return undefined;\n  }\n\n  if (parts.length === 1) {\n    return parts[0];\n  }\n\n  return parts.reduce((acc, part, index) => {\n    if (index === 0) {\n      return part;\n    }\n    const stripped = part.startsWith(\"0x\") ? part.slice(2) : part;\n    return `${acc}${stripped}` as Hex;\n  });\n}\n\n/**\n * Appends a hex data suffix to encoded contract calldata.\n *\n * @param calldata - Base encoded function calldata\n * @param suffix - Optional hex suffix (with or without 0x prefix)\n * @returns Calldata with suffix appended, or the original calldata when suffix is empty\n */\nexport function appendDataSuffix(calldata: Hex, suffix?: Hex): Hex {\n  if (!suffix || suffix === \"0x\" || suffix.length <= 2) {\n    return calldata;\n  }\n  const suffixHex = suffix.startsWith(\"0x\") ? suffix.slice(2) : suffix;\n  return `${calldata}${suffixHex}` as Hex;\n}\n","import type { PaymentPayload } from \"@x402/core/types\";\nimport type { FacilitatorEvmSigner } from \"../signer\";\n\nexport const EIP2612_GAS_SPONSORING_KEY = \"eip2612GasSponsoring\" as const;\nexport const ERC20_APPROVAL_GAS_SPONSORING_KEY = \"erc20ApprovalGasSponsoring\" as const;\nexport const ERC20_APPROVAL_GAS_SPONSORING_VERSION = \"1\" as const;\n\nexport interface Eip2612GasSponsoringInfo {\n  [key: string]: unknown;\n  from: string;\n  asset: string;\n  spender: string;\n  amount: string;\n  nonce: string;\n  deadline: string;\n  signature: string;\n  version: string;\n}\n\nexport interface Erc20ApprovalGasSponsoringInfo {\n  [key: string]: unknown;\n  from: `0x${string}`;\n  asset: `0x${string}`;\n  spender: `0x${string}`;\n  amount: string;\n  signedTransaction: `0x${string}`;\n  version: string;\n}\n\n/**\n * A single transaction to be executed by the signer.\n * - `0x${string}`: a pre-signed serialized transaction (broadcast as-is via sendRawTransaction)\n * - `{ to, data, gas? }`: an unsigned call intent (signer signs and broadcasts)\n */\nexport type TransactionRequest =\n  | `0x${string}`\n  | { to: `0x${string}`; data: `0x${string}`; gas?: bigint };\n\nexport type Erc20ApprovalGasSponsoringSigner = FacilitatorEvmSigner & {\n  sendTransactions(transactions: TransactionRequest[]): Promise<`0x${string}`[]>;\n  simulateTransactions?(transactions: TransactionRequest[]): Promise<boolean>;\n};\n\nexport interface Erc20ApprovalGasSponsoringFacilitatorExtension {\n  key: typeof ERC20_APPROVAL_GAS_SPONSORING_KEY;\n  signer?: Erc20ApprovalGasSponsoringSigner;\n  signerForNetwork?: (network: string) => Erc20ApprovalGasSponsoringSigner | undefined;\n}\n\n/**\n * Extracts a typed `info` payload from an extension entry.\n *\n * @param payload - Payment payload containing optional extensions.\n * @param extensionKey - Extension key to extract.\n * @returns The extension `info` object when present; otherwise null.\n */\nfunction _extractInfo(\n  payload: PaymentPayload,\n  extensionKey: string,\n): Record<string, unknown> | null {\n  const extensions = payload.extensions;\n  if (!extensions) return null;\n  const extension = extensions[extensionKey] as { info?: Record<string, unknown> } | undefined;\n  if (!extension?.info) return null;\n  return extension.info;\n}\n\n/**\n * Extracts and validates required EIP-2612 gas sponsoring fields.\n *\n * @param payload - Payment payload returned by the client scheme.\n * @returns Parsed EIP-2612 gas sponsoring info when available and complete.\n */\nexport function extractEip2612GasSponsoringInfo(\n  payload: PaymentPayload,\n): Eip2612GasSponsoringInfo | null {\n  const info = _extractInfo(payload, EIP2612_GAS_SPONSORING_KEY);\n  if (!info) return null;\n  if (\n    !info.from ||\n    !info.asset ||\n    !info.spender ||\n    !info.amount ||\n    !info.nonce ||\n    !info.deadline ||\n    !info.signature ||\n    !info.version\n  ) {\n    return null;\n  }\n  return info as unknown as Eip2612GasSponsoringInfo;\n}\n\n/**\n * Validates the structure and formatting of EIP-2612 sponsoring info.\n *\n * @param info - EIP-2612 extension info to validate.\n * @returns True when all required fields match expected patterns.\n */\nexport function validateEip2612GasSponsoringInfo(info: Eip2612GasSponsoringInfo): boolean {\n  const addressPattern = /^0x[a-fA-F0-9]{40}$/;\n  const numericPattern = /^[0-9]+$/;\n  const hexPattern = /^0x[a-fA-F0-9]+$/;\n  const versionPattern = /^[0-9]+(\\.[0-9]+)*$/;\n  return (\n    addressPattern.test(info.from) &&\n    addressPattern.test(info.asset) &&\n    addressPattern.test(info.spender) &&\n    numericPattern.test(info.amount) &&\n    numericPattern.test(info.nonce) &&\n    numericPattern.test(info.deadline) &&\n    hexPattern.test(info.signature) &&\n    versionPattern.test(info.version)\n  );\n}\n\n/**\n * Extracts and validates required ERC-20 approval sponsoring fields.\n *\n * @param payload - Payment payload returned by the client scheme.\n * @returns Parsed ERC-20 approval sponsoring info when available and complete.\n */\nexport function extractErc20ApprovalGasSponsoringInfo(\n  payload: PaymentPayload,\n): Erc20ApprovalGasSponsoringInfo | null {\n  const info = _extractInfo(payload, ERC20_APPROVAL_GAS_SPONSORING_KEY);\n  if (!info) return null;\n  if (\n    !info.from ||\n    !info.asset ||\n    !info.spender ||\n    !info.amount ||\n    !info.signedTransaction ||\n    !info.version\n  ) {\n    return null;\n  }\n  return info as unknown as Erc20ApprovalGasSponsoringInfo;\n}\n\n/**\n * Validates the structure and formatting of ERC-20 approval sponsoring info.\n *\n * @param info - ERC-20 approval extension info to validate.\n * @returns True when all required fields match expected patterns.\n */\nexport function validateErc20ApprovalGasSponsoringInfo(\n  info: Erc20ApprovalGasSponsoringInfo,\n): boolean {\n  const addressPattern = /^0x[a-fA-F0-9]{40}$/;\n  const numericPattern = /^[0-9]+$/;\n  const hexPattern = /^0x[a-fA-F0-9]+$/;\n  const versionPattern = /^[0-9]+(\\.[0-9]+)*$/;\n  return (\n    addressPattern.test(info.from) &&\n    addressPattern.test(info.asset) &&\n    addressPattern.test(info.spender) &&\n    numericPattern.test(info.amount) &&\n    hexPattern.test(info.signedTransaction) &&\n    versionPattern.test(info.version)\n  );\n}\n\n/**\n * Resolves the ERC-20 approval extension signer for a specific network.\n *\n * @param extension - Optional facilitator extension config.\n * @param network - CAIP-2 network identifier.\n * @returns A network-specific signer when available, else the default signer.\n */\nexport function resolveErc20ApprovalExtensionSigner(\n  extension: Erc20ApprovalGasSponsoringFacilitatorExtension | undefined,\n  network: string,\n): Erc20ApprovalGasSponsoringSigner | undefined {\n  if (!extension) return undefined;\n  return extension.signerForNetwork?.(network) ?? extension.signer;\n}\n","import type {\n  PaymentRequirements,\n  PaymentPayloadResult,\n  PaymentPayloadContext,\n} from \"@x402/core/types\";\nimport {\n  EIP2612_GAS_SPONSORING_KEY,\n  ERC20_APPROVAL_GAS_SPONSORING_KEY,\n} from \"../../exact/extensions\";\nimport { getAddress } from \"viem\";\nimport { PERMIT2_ADDRESS, erc20AllowanceAbi } from \"../../constants\";\nimport { getEvmChainId } from \"../../utils\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport { signEip2612Permit } from \"../../exact/client/eip2612\";\nimport { signErc20ApprovalTransaction } from \"../../exact/client/erc20approval\";\nimport { resolveExtensionRpcCapabilities, type ExactEvmSchemeOptions } from \"../rpc\";\n\n/**\n * Attempts to sign an EIP-2612 permit for gasless Permit2 approval.\n *\n * @param signer - The EVM client signer\n * @param options - Optional RPC configuration for backfilling capabilities\n * @param requirements - The payment requirements from the server\n * @param result - The payment payload result from the scheme\n * @param context - Optional context containing server extensions and metadata\n * @param approvalAmount - Optional amount to approve instead of `requirements.amount`\n * @returns Extension data for EIP-2612 gas sponsoring, or undefined if not applicable\n */\nexport async function trySignEip2612PermitExtension(\n  signer: ClientEvmSigner,\n  options: ExactEvmSchemeOptions | undefined,\n  requirements: PaymentRequirements,\n  result: PaymentPayloadResult,\n  context?: PaymentPayloadContext,\n  approvalAmount?: string,\n): Promise<Record<string, unknown> | undefined> {\n  const capabilities = resolveExtensionRpcCapabilities(requirements.network, signer, options);\n\n  if (!capabilities.readContract) {\n    return undefined;\n  }\n\n  if (!context?.extensions?.[EIP2612_GAS_SPONSORING_KEY]) {\n    return undefined;\n  }\n\n  const tokenName = requirements.extra?.name as string | undefined;\n  const tokenVersion = requirements.extra?.version as string | undefined;\n  if (!tokenName || !tokenVersion) {\n    return undefined;\n  }\n\n  const chainId = getEvmChainId(requirements.network);\n  const tokenAddress = getAddress(requirements.asset) as `0x${string}`;\n  const requiredAllowance = approvalAmount ?? requirements.amount;\n\n  try {\n    const allowance = (await capabilities.readContract({\n      address: tokenAddress,\n      abi: erc20AllowanceAbi,\n      functionName: \"allowance\",\n      args: [signer.address, PERMIT2_ADDRESS],\n    })) as bigint;\n\n    if (allowance >= BigInt(requiredAllowance)) {\n      return undefined;\n    }\n  } catch {\n    // Allowance check failed, proceed with signing\n  }\n\n  const permit2Auth = result.payload?.permit2Authorization as Record<string, unknown> | undefined;\n  const deadline =\n    (permit2Auth?.deadline as string) ??\n    Math.floor(Date.now() / 1000 + requirements.maxTimeoutSeconds).toString();\n\n  const info = await signEip2612Permit(\n    {\n      address: signer.address,\n      signTypedData: msg => signer.signTypedData(msg),\n      readContract: capabilities.readContract,\n    },\n    tokenAddress,\n    tokenName,\n    tokenVersion,\n    chainId,\n    deadline,\n    requiredAllowance,\n  );\n\n  return {\n    [EIP2612_GAS_SPONSORING_KEY]: { info },\n  };\n}\n\n/**\n * Attempts to sign an ERC-20 approval transaction for gasless Permit2 approval.\n *\n * @param signer - The EVM client signer\n * @param options - Optional RPC configuration for backfilling capabilities\n * @param requirements - The payment requirements from the server\n * @param context - Optional context containing server extensions and metadata\n * @param approvalAmount - Optional amount to check for Permit2 allowance\n * @returns Extension data for ERC-20 approval gas sponsoring, or undefined if not applicable\n */\nexport async function trySignErc20ApprovalExtension(\n  signer: ClientEvmSigner,\n  options: ExactEvmSchemeOptions | undefined,\n  requirements: PaymentRequirements,\n  context?: PaymentPayloadContext,\n  approvalAmount?: string,\n): Promise<Record<string, unknown> | undefined> {\n  const capabilities = resolveExtensionRpcCapabilities(requirements.network, signer, options);\n\n  if (!capabilities.readContract) {\n    return undefined;\n  }\n\n  if (!context?.extensions?.[ERC20_APPROVAL_GAS_SPONSORING_KEY]) {\n    return undefined;\n  }\n\n  if (!capabilities.signTransaction || !capabilities.getTransactionCount) {\n    return undefined;\n  }\n\n  const chainId = getEvmChainId(requirements.network);\n  const tokenAddress = getAddress(requirements.asset) as `0x${string}`;\n  const requiredAllowance = approvalAmount ?? requirements.amount;\n\n  try {\n    const allowance = (await capabilities.readContract({\n      address: tokenAddress,\n      abi: erc20AllowanceAbi,\n      functionName: \"allowance\",\n      args: [signer.address, PERMIT2_ADDRESS],\n    })) as bigint;\n\n    if (allowance >= BigInt(requiredAllowance)) {\n      return undefined;\n    }\n  } catch {\n    // Allowance check failed, proceed with signing\n  }\n\n  const info = await signErc20ApprovalTransaction(\n    {\n      address: signer.address,\n      signTransaction: capabilities.signTransaction,\n      getTransactionCount: capabilities.getTransactionCount,\n      estimateFeesPerGas: capabilities.estimateFeesPerGas,\n    },\n    tokenAddress,\n    chainId,\n  );\n\n  return {\n    [ERC20_APPROVAL_GAS_SPONSORING_KEY]: { info },\n  };\n}\n","import { getAddress } from \"viem\";\nimport { eip2612PermitTypes, eip2612NoncesAbi, PERMIT2_ADDRESS } from \"../../constants\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport type { Eip2612GasSponsoringInfo } from \"../extensions\";\n\nexport type Eip2612PermitSigner = Pick<ClientEvmSigner, \"address\" | \"signTypedData\"> & {\n  readContract: NonNullable<ClientEvmSigner[\"readContract\"]>;\n};\n\n/**\n * Signs an EIP-2612 permit authorizing the Permit2 contract to spend tokens.\n *\n * This creates a gasless off-chain signature that the facilitator can submit\n * on-chain via `x402Permit2Proxy.settleWithPermit()`.\n *\n * The `permittedAmount` must match the Permit2 `permitted.amount` exactly, as the\n * proxy contract enforces `permit2612.value == permittedAmount`.\n *\n * @param signer - The client EVM signer (must support readContract for nonce query)\n * @param tokenAddress - The ERC-20 token contract address\n * @param tokenName - The token name (from paymentRequirements.extra.name)\n * @param tokenVersion - The token version (from paymentRequirements.extra.version)\n * @param chainId - The chain ID\n * @param deadline - The deadline for the permit (unix timestamp as string)\n * @param permittedAmount - The Permit2 permitted amount (must match exactly)\n * @returns The EIP-2612 gas sponsoring info object\n */\nexport async function signEip2612Permit(\n  signer: Eip2612PermitSigner,\n  tokenAddress: `0x${string}`,\n  tokenName: string,\n  tokenVersion: string,\n  chainId: number,\n  deadline: string,\n  permittedAmount: string,\n): Promise<Eip2612GasSponsoringInfo> {\n  const owner = signer.address;\n  const spender = getAddress(PERMIT2_ADDRESS);\n\n  // Query the current EIP-2612 nonce from the token contract\n  const nonce = (await signer.readContract({\n    address: tokenAddress,\n    abi: eip2612NoncesAbi,\n    functionName: \"nonces\",\n    args: [owner],\n  })) as bigint;\n\n  // Construct EIP-712 domain for the token's permit function\n  const domain = {\n    name: tokenName,\n    version: tokenVersion,\n    chainId,\n    verifyingContract: tokenAddress,\n  };\n\n  const approvalAmount = BigInt(permittedAmount);\n\n  const message = {\n    owner,\n    spender,\n    value: approvalAmount,\n    nonce,\n    deadline: BigInt(deadline),\n  };\n\n  // Sign the EIP-2612 permit\n  const signature = await signer.signTypedData({\n    domain,\n    types: eip2612PermitTypes,\n    primaryType: \"Permit\",\n    message,\n  });\n\n  return {\n    from: owner,\n    asset: tokenAddress,\n    spender,\n    amount: approvalAmount.toString(),\n    nonce: nonce.toString(),\n    deadline,\n    signature,\n    version: \"1\",\n  };\n}\n","import { encodeFunctionData, getAddress, maxUint256 } from \"viem\";\nimport {\n  PERMIT2_ADDRESS,\n  erc20ApproveAbi,\n  ERC20_APPROVE_GAS_LIMIT,\n  DEFAULT_MAX_FEE_PER_GAS,\n  DEFAULT_MAX_PRIORITY_FEE_PER_GAS,\n} from \"../../constants\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport {\n  ERC20_APPROVAL_GAS_SPONSORING_VERSION,\n  type Erc20ApprovalGasSponsoringInfo,\n} from \"../extensions\";\n\nexport type Erc20ApprovalTxSigner = Pick<ClientEvmSigner, \"address\"> & {\n  signTransaction: NonNullable<ClientEvmSigner[\"signTransaction\"]>;\n  getTransactionCount: NonNullable<ClientEvmSigner[\"getTransactionCount\"]>;\n  estimateFeesPerGas?: NonNullable<ClientEvmSigner[\"estimateFeesPerGas\"]>;\n};\n\n/**\n * Signs an EIP-1559 `approve(Permit2, MaxUint256)` transaction for the given token.\n *\n * The signed transaction is NOT broadcast here — the facilitator broadcasts it\n * atomically before settling the Permit2 payment. This enables Permit2 payments\n * for generic ERC-20 tokens that do NOT implement EIP-2612.\n *\n * Always approves MaxUint256 regardless of the payment amount.\n *\n * @param signer - The client EVM signer (must support signTransaction, getTransactionCount)\n * @param tokenAddress - The ERC-20 token contract address\n * @param chainId - The chain ID\n * @returns The ERC-20 approval gas sponsoring info object\n */\nexport async function signErc20ApprovalTransaction(\n  signer: Erc20ApprovalTxSigner,\n  tokenAddress: `0x${string}`,\n  chainId: number,\n): Promise<Erc20ApprovalGasSponsoringInfo> {\n  const from = signer.address;\n  const spender = getAddress(PERMIT2_ADDRESS);\n\n  // Encode approve(PERMIT2_ADDRESS, MaxUint256) calldata\n  const data = encodeFunctionData({\n    abi: erc20ApproveAbi,\n    functionName: \"approve\",\n    args: [spender, maxUint256],\n  });\n\n  // Get current nonce for the sender\n  const nonce = await signer.getTransactionCount({ address: from });\n\n  // Get current fee estimates, with fallback values\n  let maxFeePerGas: bigint;\n  let maxPriorityFeePerGas: bigint;\n  try {\n    const fees = await signer.estimateFeesPerGas?.();\n    if (!fees) {\n      throw new Error(\"no fee estimates available\");\n    }\n    maxFeePerGas = fees.maxFeePerGas;\n    maxPriorityFeePerGas = fees.maxPriorityFeePerGas;\n  } catch {\n    maxFeePerGas = DEFAULT_MAX_FEE_PER_GAS;\n    maxPriorityFeePerGas = DEFAULT_MAX_PRIORITY_FEE_PER_GAS;\n  }\n\n  // Sign the EIP-1559 transaction (not broadcast)\n  const signedTransaction = await signer.signTransaction({\n    to: tokenAddress,\n    data,\n    nonce,\n    gas: ERC20_APPROVE_GAS_LIMIT,\n    maxFeePerGas,\n    maxPriorityFeePerGas,\n    chainId,\n  });\n\n  return {\n    from,\n    asset: tokenAddress,\n    spender,\n    amount: maxUint256.toString(),\n    signedTransaction,\n    version: ERC20_APPROVAL_GAS_SPONSORING_VERSION,\n  };\n}\n","import { createPublicClient, http } from \"viem\";\nimport type { ClientEvmSigner } from \"../signer\";\nimport { getEvmChainId } from \"../utils\";\n\nexport type EvmSchemeConfig = {\n  rpcUrl?: string;\n};\n\nexport type EvmSchemeConfigByChainId = Record<number, EvmSchemeConfig>;\n\nexport type EvmSchemeOptions = EvmSchemeConfig | EvmSchemeConfigByChainId;\n\n/** @deprecated Use EvmSchemeConfig */\nexport type ExactEvmSchemeConfig = EvmSchemeConfig;\n/** @deprecated Use EvmSchemeConfigByChainId */\nexport type ExactEvmSchemeConfigByChainId = EvmSchemeConfigByChainId;\n/** @deprecated Use EvmSchemeOptions */\nexport type ExactEvmSchemeOptions = EvmSchemeOptions;\n\ntype ExtensionRpcCapabilities = Pick<\n  ClientEvmSigner,\n  \"readContract\" | \"signTransaction\" | \"getTransactionCount\" | \"estimateFeesPerGas\"\n>;\n\nconst rpcClientCache = new Map<string, ReturnType<typeof createPublicClient>>();\n\n/**\n * Check if options is a per-chain-id configuration map.\n *\n * @param options - The EVM scheme options to check\n * @returns True if the options are keyed by chain ID\n */\nfunction isConfigByChainId(options: EvmSchemeOptions): options is EvmSchemeConfigByChainId {\n  const keys = Object.keys(options);\n  return keys.length > 0 && keys.every(key => /^\\d+$/.test(key));\n}\n\n/**\n * Get or create a cached viem public client for the given RPC URL.\n *\n * @param rpcUrl - The JSON-RPC endpoint URL\n * @returns A viem PublicClient instance\n */\nfunction getRpcClient(rpcUrl: string): ReturnType<typeof createPublicClient> {\n  const existing = rpcClientCache.get(rpcUrl);\n  if (existing) {\n    return existing;\n  }\n\n  const client = createPublicClient({\n    transport: http(rpcUrl),\n  });\n  rpcClientCache.set(rpcUrl, client);\n  return client;\n}\n\n/**\n * Resolve an RPC URL from scheme options for the given network.\n *\n * @param network - The CAIP-2 network identifier\n * @param options - Optional EVM scheme options (flat or per-chain-id)\n * @returns The resolved RPC URL, or undefined if not configured\n */\nexport function resolveRpcUrl(network: string, options?: EvmSchemeOptions): string | undefined {\n  if (!options) {\n    return undefined;\n  }\n\n  if (isConfigByChainId(options)) {\n    const chainId = getEvmChainId(network);\n    const optionsByChainId = options as EvmSchemeConfigByChainId;\n    return optionsByChainId[chainId]?.rpcUrl;\n  }\n\n  return (options as EvmSchemeConfig).rpcUrl;\n}\n\n/**\n * Resolve RPC capabilities for extensions, backfilling from a public RPC client when the signer lacks them.\n *\n * @param network - The CAIP-2 network identifier\n * @param signer - The client EVM signer\n * @param options - Optional EVM scheme options for RPC URL resolution\n * @returns Extension RPC capabilities (readContract, signTransaction, etc.)\n */\nexport function resolveExtensionRpcCapabilities(\n  network: string,\n  signer: ClientEvmSigner,\n  options?: EvmSchemeOptions,\n): ExtensionRpcCapabilities {\n  const capabilities: ExtensionRpcCapabilities = {\n    signTransaction: signer.signTransaction,\n    readContract: signer.readContract,\n    getTransactionCount: signer.getTransactionCount,\n    estimateFeesPerGas: signer.estimateFeesPerGas,\n  };\n\n  const needsRpcBackfill =\n    !capabilities.readContract ||\n    !capabilities.getTransactionCount ||\n    !capabilities.estimateFeesPerGas;\n  if (!needsRpcBackfill) {\n    return capabilities;\n  }\n\n  const rpcUrl = resolveRpcUrl(network, options);\n  if (!rpcUrl) {\n    return capabilities;\n  }\n  const rpcClient = getRpcClient(rpcUrl);\n  if (!capabilities.readContract) {\n    capabilities.readContract = args => rpcClient.readContract(args as never) as Promise<unknown>;\n  }\n  if (!capabilities.getTransactionCount) {\n    capabilities.getTransactionCount = async args =>\n      rpcClient.getTransactionCount({ address: args.address });\n  }\n  if (!capabilities.estimateFeesPerGas) {\n    capabilities.estimateFeesPerGas = async () => rpcClient.estimateFeesPerGas();\n  }\n\n  return capabilities;\n}\n"],"mappings":"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","names":["getAddress","getAddress","getAddress","getAddress"]}