{"version":3,"sources":["../../src/schemes/exact/index.ts","../../src/schemes/exact/evm/index.ts","../../src/schemes/exact/evm/facilitator.ts","../../src/schemes/exact/svm/index.ts","../../src/schemes/exact/svm/facilitator/settle.ts","../../src/schemes/exact/svm/facilitator/verify.ts","../../src/schemes/exact/svm/facilitator/settlement-cache.ts"],"sourcesContent":["export * as evm from \"./evm\";\nexport * as svm from \"./svm\";\n\nexport const SCHEME = \"exact\";\n","export * from \"./client\";\nexport * from \"./facilitator\";\nexport * from \"./utils/paymentUtils\";\n","import {\n  Account,\n  Address,\n  Chain,\n  getAddress,\n  Hex,\n  parseErc6492Signature,\n  parseSignature,\n  Transport,\n} from \"viem\";\nimport { getNetworkId } from \"../../../shared\";\nimport { getVersion, getERC20Balance } from \"../../../shared/evm\";\nimport {\n  usdcABI as abi,\n  authorizationTypes,\n  config,\n  ConnectedClient,\n  SignerWallet,\n} from \"../../../types/shared/evm\";\nimport {\n  PaymentPayload,\n  PaymentRequirements,\n  SettleResponse,\n  VerifyResponse,\n  ExactEvmPayload,\n} from \"../../../types/verify\";\nimport { SCHEME } from \"../../exact\";\n\n/**\n * Verifies a payment payload against the required payment details\n *\n * This function performs several verification steps:\n * - Verifies protocol version compatibility\n * - Validates the permit signature\n * - Confirms USDC contract address is correct for the chain\n * - Checks permit deadline is sufficiently in the future\n * - Verifies client has sufficient USDC balance\n * - Ensures payment amount meets required minimum\n *\n * @param client - The public client used for blockchain interactions\n * @param payload - The signed payment payload containing transfer parameters and signature\n * @param paymentRequirements - The payment requirements that the payload must satisfy\n * @returns A ValidPaymentRequest indicating if the payment is valid and any invalidation reason\n */\nexport async function verify<\n  transport extends Transport,\n  chain extends Chain,\n  account extends Account | undefined,\n>(\n  client: ConnectedClient<transport, chain, account>,\n  payload: PaymentPayload,\n  paymentRequirements: PaymentRequirements,\n): Promise<VerifyResponse> {\n  /* TODO: work with security team on brainstorming more verification steps\n  verification steps:\n    - ✅ verify payload version\n    - ✅ verify usdc address is correct for the chain\n    - ✅ verify permit signature\n    - ✅ verify deadline\n    - verify nonce is current\n    - ✅ verify client has enough funds to cover paymentRequirements.maxAmountRequired\n    - ✅ verify value in payload is enough to cover paymentRequirements.maxAmountRequired\n    - check min amount is above some threshold we think is reasonable for covering gas\n    - verify resource is not already paid for (next version)\n    */\n\n  const exactEvmPayload = payload.payload as ExactEvmPayload;\n\n  // Verify payload version\n  if (payload.scheme !== SCHEME || paymentRequirements.scheme !== SCHEME) {\n    return {\n      isValid: false,\n      invalidReason: `unsupported_scheme`,\n      payer: exactEvmPayload.authorization.from,\n    };\n  }\n\n  let name: string;\n  let chainId: number;\n  let erc20Address: Address;\n  let version: string;\n  try {\n    chainId = getNetworkId(payload.network);\n    name = paymentRequirements.extra?.name ?? config[chainId.toString()].usdcName;\n    erc20Address = paymentRequirements.asset as Address;\n    version = paymentRequirements.extra?.version ?? (await getVersion(client));\n  } catch {\n    return {\n      isValid: false,\n      invalidReason: `invalid_network`,\n      payer: (payload.payload as ExactEvmPayload).authorization.from,\n    };\n  }\n  // Verify permit signature is recoverable for the owner address\n  const permitTypedData = {\n    types: authorizationTypes,\n    primaryType: \"TransferWithAuthorization\" as const,\n    domain: {\n      name,\n      version,\n      chainId,\n      verifyingContract: erc20Address,\n    },\n    message: {\n      from: exactEvmPayload.authorization.from,\n      to: exactEvmPayload.authorization.to,\n      value: exactEvmPayload.authorization.value,\n      validAfter: exactEvmPayload.authorization.validAfter,\n      validBefore: exactEvmPayload.authorization.validBefore,\n      nonce: exactEvmPayload.authorization.nonce,\n    },\n  };\n  const recoveredAddress = await client.verifyTypedData({\n    address: exactEvmPayload.authorization.from as Address,\n    ...permitTypedData,\n    signature: exactEvmPayload.signature as Hex,\n  });\n  if (!recoveredAddress) {\n    return {\n      isValid: false,\n      invalidReason: \"invalid_exact_evm_payload_signature\", //\"Invalid permit signature\",\n      payer: exactEvmPayload.authorization.from,\n    };\n  }\n\n  // Verify that payment was made to the correct address\n  if (getAddress(exactEvmPayload.authorization.to) !== getAddress(paymentRequirements.payTo)) {\n    return {\n      isValid: false,\n      invalidReason: \"invalid_exact_evm_payload_recipient_mismatch\",\n      payer: exactEvmPayload.authorization.from,\n    };\n  }\n\n  // Verify deadline is not yet expired\n  // Pad 3 block to account for round tripping\n  if (\n    BigInt(exactEvmPayload.authorization.validBefore) < BigInt(Math.floor(Date.now() / 1000) + 6)\n  ) {\n    return {\n      isValid: false,\n      invalidReason: \"invalid_exact_evm_payload_authorization_valid_before\", //\"Deadline on permit isn't far enough in the future\",\n      payer: exactEvmPayload.authorization.from,\n    };\n  }\n  // Verify deadline is not yet valid\n  if (BigInt(exactEvmPayload.authorization.validAfter) > BigInt(Math.floor(Date.now() / 1000))) {\n    return {\n      isValid: false,\n      invalidReason: \"invalid_exact_evm_payload_authorization_valid_after\", //\"Deadline on permit is in the future\",\n      payer: exactEvmPayload.authorization.from,\n    };\n  }\n  // Verify client has enough funds to cover paymentRequirements.maxAmountRequired\n  const balance = await getERC20Balance(\n    client,\n    erc20Address,\n    exactEvmPayload.authorization.from as Address,\n  );\n  if (balance < BigInt(paymentRequirements.maxAmountRequired)) {\n    return {\n      isValid: false,\n      invalidReason: \"insufficient_funds\", //\"Client does not have enough funds\",\n      payer: exactEvmPayload.authorization.from,\n    };\n  }\n  // Verify value in payload is enough to cover paymentRequirements.maxAmountRequired\n  if (BigInt(exactEvmPayload.authorization.value) < BigInt(paymentRequirements.maxAmountRequired)) {\n    return {\n      isValid: false,\n      invalidReason: \"invalid_exact_evm_payload_authorization_value\", //\"Value in payload is not enough to cover paymentRequirements.maxAmountRequired\",\n      payer: exactEvmPayload.authorization.from,\n    };\n  }\n\n  // Check if smart wallet is deployed\n  // Smart wallet signatures are detected by length > 130 (65 bytes = 130 hex chars for EOA)\n  const signature = exactEvmPayload.signature;\n  const signatureLength = signature.startsWith(\"0x\") ? signature.length - 2 : signature.length;\n  const isSmartWallet = signatureLength > 130;\n\n  if (isSmartWallet) {\n    const payerAddress = exactEvmPayload.authorization.from as Address;\n    const bytecode = await client.getCode({ address: payerAddress });\n\n    if (!bytecode || bytecode === \"0x\") {\n      // Wallet is not deployed. Check if it's EIP-6492 with deployment info.\n      // EIP-6492 signatures contain factory address and calldata needed for deployment.\n      // Non-EIP-6492 undeployed wallets cannot succeed (no way to deploy them).\n      const erc6492Data = parseErc6492Signature(exactEvmPayload.signature as Hex);\n      const hasDeploymentInfo = erc6492Data.address && erc6492Data.data;\n\n      if (!hasDeploymentInfo) {\n        // Non-EIP-6492 undeployed smart wallet - will always fail at settlement\n        // since EIP-3009 requires on-chain EIP-1271 validation\n        return {\n          isValid: false,\n          invalidReason: \"invalid_exact_evm_payload_undeployed_smart_wallet\",\n          payer: payerAddress,\n        };\n      }\n      // EIP-6492 signature with deployment info - allow through\n      // Facilitators with sponsored deployment support can handle this in settle()\n    }\n  }\n\n  return {\n    isValid: true,\n    invalidReason: undefined,\n    payer: exactEvmPayload.authorization.from,\n  };\n}\n\n/**\n * Settles a payment by executing a USDC transferWithAuthorization transaction\n *\n * This function executes the actual USDC transfer using the signed authorization from the user.\n * The facilitator wallet submits the transaction but does not need to hold or transfer any tokens itself.\n *\n * @param wallet - The facilitator wallet that will submit the transaction\n * @param paymentPayload - The signed payment payload containing the transfer parameters and signature\n * @param paymentRequirements - The original payment details that were used to create the payload\n * @returns A PaymentExecutionResponse containing the transaction status and hash\n */\nexport async function settle<transport extends Transport, chain extends Chain>(\n  wallet: SignerWallet<chain, transport>,\n  paymentPayload: PaymentPayload,\n  paymentRequirements: PaymentRequirements,\n): Promise<SettleResponse> {\n  const payload = paymentPayload.payload as ExactEvmPayload;\n\n  // re-verify to ensure the payment is still valid\n  const valid = await verify(wallet, paymentPayload, paymentRequirements);\n\n  if (!valid.isValid) {\n    return {\n      success: false,\n      network: paymentPayload.network,\n      transaction: \"\",\n      errorReason: valid.invalidReason ?? \"invalid_scheme\", //`Payment is no longer valid: ${valid.invalidReason}`,\n      payer: payload.authorization.from,\n    };\n  }\n\n  // Check if smart wallet is deployed before attempting settlement\n  // EIP-3009's transferWithAuthorization requires on-chain signature validation via EIP-1271,\n  // which fails for undeployed contracts.\n  //\n  // Note: If we reach this point with an undeployed wallet, it must be an EIP-6492 signature\n  // (non-EIP-6492 undeployed wallets are rejected earlier in verify()).\n  //\n  // Facilitators that want to support undeployed EIP-6492 smart wallets should:\n  // 1. Parse the EIP-6492 signature to extract factory address and calldata\n  // 2. Deploy the wallet by calling the factory\n  // 3. Verify deployment succeeded\n  // 4. Then proceed with the transfer below\n  const signature = payload.signature;\n  const signatureLength = signature.startsWith(\"0x\") ? signature.length - 2 : signature.length;\n  const isSmartWallet = signatureLength > 130;\n\n  if (isSmartWallet) {\n    const bytecode = await wallet.getCode({ address: payload.authorization.from as Address });\n    if (!bytecode || bytecode === \"0x\") {\n      return {\n        success: false,\n        network: paymentPayload.network,\n        transaction: \"\",\n        errorReason: \"invalid_exact_evm_payload_undeployed_smart_wallet\",\n        payer: payload.authorization.from,\n      };\n    }\n  }\n\n  let tx: Hex;\n\n  if (isSmartWallet) {\n    // Smart wallets: Use bytes signature overload (requires FiatToken v2.0+)\n    // Unwrap EIP-6492 if present (no-op for regular signatures)\n    const { signature: unwrappedSignature } = parseErc6492Signature(payload.signature as Hex);\n\n    tx = await wallet.writeContract({\n      address: paymentRequirements.asset as Address,\n      abi,\n      functionName: \"transferWithAuthorization\" as const,\n      args: [\n        payload.authorization.from as Address,\n        payload.authorization.to as Address,\n        BigInt(payload.authorization.value),\n        BigInt(payload.authorization.validAfter),\n        BigInt(payload.authorization.validBefore),\n        payload.authorization.nonce as Hex,\n        unwrappedSignature,\n      ],\n      chain: wallet.chain as Chain,\n    });\n  } else {\n    // EOA: Use (v, r, s) overload for maximum compatibility\n    const parsedSig = parseSignature(payload.signature as Hex);\n    const v = parsedSig.v !== undefined ? Number(parsedSig.v) : 27 + parsedSig.yParity;\n\n    tx = await wallet.writeContract({\n      address: paymentRequirements.asset as Address,\n      abi,\n      functionName: \"transferWithAuthorization\" as const,\n      args: [\n        payload.authorization.from as Address,\n        payload.authorization.to as Address,\n        BigInt(payload.authorization.value),\n        BigInt(payload.authorization.validAfter),\n        BigInt(payload.authorization.validBefore),\n        payload.authorization.nonce as Hex,\n        v,\n        parsedSig.r,\n        parsedSig.s,\n      ],\n      chain: wallet.chain as Chain,\n    });\n  }\n\n  const receipt = await wallet.waitForTransactionReceipt({ hash: tx });\n\n  if (receipt.status !== \"success\") {\n    return {\n      success: false,\n      errorReason: \"invalid_transaction_state\", //`Transaction failed`,\n      transaction: tx,\n      network: paymentPayload.network,\n      payer: payload.authorization.from,\n    };\n  }\n\n  return {\n    success: true,\n    transaction: tx,\n    network: paymentPayload.network,\n    payer: payload.authorization.from,\n  };\n}\n","export * from \"./facilitator/index\";\nexport * from \"./client\";\n","import {\n  SettleResponse,\n  PaymentPayload,\n  PaymentRequirements,\n  ExactSvmPayload,\n  ErrorReasons,\n} from \"../../../../types/verify\";\nimport { X402Config } from \"../../../../types/config\";\nimport {\n  assertIsTransactionMessageWithBlockhashLifetime,\n  Commitment,\n  decompileTransactionMessageFetchingLookupTables,\n  getBase64EncodedWireTransaction,\n  getCompiledTransactionMessageDecoder,\n  getSignatureFromTransaction,\n  isSolanaError,\n  type Transaction,\n  type TransactionSigner,\n  SendTransactionApi,\n  SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED,\n  SolanaRpcApiDevnet,\n  SolanaRpcApiMainnet,\n  RpcDevnet,\n  RpcMainnet,\n} from \"@solana/kit\";\nimport {\n  decodeTransactionFromPayload,\n  getTokenPayerFromTransaction,\n  signTransactionWithSigner,\n} from \"../../../../shared/svm\";\nimport { getRpcClient, getRpcSubscriptions } from \"../../../../shared/svm/rpc\";\nimport {\n  createBlockHeightExceedencePromiseFactory,\n  waitForRecentTransactionConfirmation,\n  createRecentSignatureConfirmationPromiseFactory,\n} from \"@solana/transaction-confirmation\";\nimport { verify } from \"./verify\";\nimport { SettlementCache } from \"./settlement-cache\";\n\n/**\n * Settle the payment payload against the payment requirements.\n * TODO: handle durable nonce lifetime transactions\n *\n * @param signer - The signer that will sign the transaction\n * @param payload - The payment payload to settle\n * @param paymentRequirements - The payment requirements to settle against\n * @param config - Optional configuration for X402 operations (e.g., custom RPC URLs)\n * @returns A SettleResponse indicating if the payment is settled and any error reason\n */\nconst settlementCache = new SettlementCache();\n\n/**\n * Settles an exact SVM payment by verifying the payment and recording the settlement.\n *\n * @param signer - Transaction signer used to verify the payment\n * @param payload - The payment payload to settle\n * @param paymentRequirements - The payment requirements to settle against\n * @param config - Optional configuration for X402 operations (e.g., custom RPC URLs)\n * @returns A promise that resolves to a SettleResponse indicating success or failure\n */\nexport async function settle(\n  signer: TransactionSigner,\n  payload: PaymentPayload,\n  paymentRequirements: PaymentRequirements,\n  config?: X402Config,\n): Promise<SettleResponse> {\n  const verifyResponse = await verify(signer, payload, paymentRequirements, config);\n  if (!verifyResponse.isValid) {\n    return {\n      success: false,\n      errorReason: verifyResponse.invalidReason,\n      network: payload.network,\n      transaction: \"\",\n    };\n  }\n\n  const svmPayload = payload.payload as ExactSvmPayload;\n\n  // Duplicate settlement check: reject if this transaction is already being settled.\n  // Must occur before any async work so concurrent calls for the same tx are caught.\n  const txKey = svmPayload.transaction;\n  if (settlementCache.isDuplicate(txKey)) {\n    return {\n      success: false,\n      errorReason: \"duplicate_settlement\",\n      network: payload.network,\n      transaction: \"\",\n    };\n  }\n  const decodedTransaction = decodeTransactionFromPayload(svmPayload);\n  const signedTransaction = await signTransactionWithSigner(signer, decodedTransaction);\n  assertTransactionFullySigned(signedTransaction);\n  const payer = getTokenPayerFromTransaction(signedTransaction);\n\n  const rpc = getRpcClient(paymentRequirements.network, config?.svmConfig?.rpcUrl);\n  const rpcSubscriptions = getRpcSubscriptions(\n    paymentRequirements.network,\n    config?.svmConfig?.rpcUrl,\n  );\n\n  try {\n    const { success, errorReason, signature } = await sendAndConfirmSignedTransaction(\n      signedTransaction,\n      rpc,\n      rpcSubscriptions,\n    );\n\n    return {\n      success,\n      errorReason,\n      payer,\n      transaction: signature,\n      network: payload.network,\n    };\n  } catch (error) {\n    console.error(\"Unexpected error during transaction settlement:\", error);\n    return {\n      success: false,\n      errorReason: \"unexpected_settle_error\",\n      network: payload.network,\n      transaction: getSignatureFromTransaction(signedTransaction),\n      payer,\n    };\n  }\n}\n\n/**\n * Send a signed transaction to the RPC.\n * TODO: should this be moved to the shared/svm/rpc.ts file?\n *\n * @param signedTransaction - The signed transaction to send\n * @param rpc - The RPC client to use to send the transaction\n * @param sendTxConfig - The configuration for the transaction send\n * @returns The signature of the sent transaction\n */\nexport async function sendSignedTransaction(\n  signedTransaction: Transaction,\n  rpc: RpcDevnet<SolanaRpcApiDevnet> | RpcMainnet<SolanaRpcApiMainnet>,\n  sendTxConfig: Parameters<SendTransactionApi[\"sendTransaction\"]>[1] = {\n    skipPreflight: true,\n    encoding: \"base64\",\n  },\n): Promise<string> {\n  const base64EncodedTransaction = getBase64EncodedWireTransaction(signedTransaction);\n  return await rpc.sendTransaction(base64EncodedTransaction, sendTxConfig).send();\n}\n\n/**\n * Confirm a signed transaction.\n * TODO: can some of this be refactored to be moved to the shared/svm/rpc.ts file?\n * TODO: should the commitment and the timeout be passed in as parameters?\n *\n * @param signedTransaction - The signed transaction to confirm\n * @param rpc - The RPC client to use to confirm the transaction\n * @param rpcSubscriptions - The RPC subscriptions to use to confirm the transaction\n * @returns The success and signature of the confirmed transaction\n */\nexport async function confirmSignedTransaction(\n  signedTransaction: Transaction,\n  rpc: RpcDevnet<SolanaRpcApiDevnet> | RpcMainnet<SolanaRpcApiMainnet>,\n  rpcSubscriptions: ReturnType<typeof getRpcSubscriptions>,\n): Promise<{ success: boolean; errorReason?: (typeof ErrorReasons)[number]; signature: string }> {\n  // get the signature from the signed transaction\n  const signature = getSignatureFromTransaction(signedTransaction);\n\n  // set a timeout for the transaction confirmation\n  const abortController = new AbortController();\n  const timeout = setTimeout(() => {\n    abortController.abort(\"Transaction confirmation timed out after 60 seconds\");\n  }, 60000);\n\n  try {\n    // decompile the transaction message to get the blockhash lifetime\n    const compiledTransactionMessage = getCompiledTransactionMessageDecoder().decode(\n      signedTransaction.messageBytes,\n    );\n    const decompiledTransactionMessage = await decompileTransactionMessageFetchingLookupTables(\n      compiledTransactionMessage,\n      rpc,\n    );\n    assertIsTransactionMessageWithBlockhashLifetime(decompiledTransactionMessage);\n\n    // add the blockhash lifetime to the signed transaction\n    const signedTransactionWithBlockhashLifetime = {\n      ...signedTransaction,\n      lifetimeConstraint: decompiledTransactionMessage.lifetimeConstraint,\n    };\n\n    // create the config for the transaction confirmation\n    const commitment: Commitment = \"confirmed\";\n\n    const getRecentSignatureConfirmationPromise = createRecentSignatureConfirmationPromiseFactory({\n      rpc,\n      rpcSubscriptions,\n    } as Parameters<typeof createRecentSignatureConfirmationPromiseFactory>[0]);\n\n    const getBlockHeightExceedencePromise = createBlockHeightExceedencePromiseFactory({\n      rpc,\n      rpcSubscriptions,\n    } as Parameters<typeof createBlockHeightExceedencePromiseFactory>[0]);\n\n    const config = {\n      abortSignal: abortController.signal,\n      commitment,\n      getBlockHeightExceedencePromise,\n      getRecentSignatureConfirmationPromise,\n    };\n\n    // wait for the transaction to be confirmed\n    await waitForRecentTransactionConfirmation({\n      ...config,\n      transaction: signedTransactionWithBlockhashLifetime as Parameters<\n        typeof waitForRecentTransactionConfirmation\n      >[0][\"transaction\"],\n    });\n\n    // return the success and signature\n    return {\n      success: true,\n      signature,\n    };\n  } catch (error) {\n    console.error(error);\n\n    // block height exceeded error\n    if (isSolanaError(error, SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED)) {\n      return {\n        success: false,\n        errorReason: \"settle_exact_svm_block_height_exceeded\",\n        signature,\n      };\n    }\n    // transaction confirmation timed out error\n    else if (error instanceof DOMException && error.name === \"AbortError\") {\n      return {\n        success: false,\n        errorReason: \"settle_exact_svm_transaction_confirmation_timed_out\",\n        signature,\n      };\n    }\n    // unexpected error\n    else {\n      throw error;\n    }\n  } finally {\n    // clear the timeout\n    clearTimeout(timeout);\n  }\n}\n\n/**\n * Send and confirm a signed transaction.\n *\n * @param signedTransaction - The signed transaction to send and confirm\n * @param rpc - The RPC client to use to send and confirm the transaction\n * @param rpcSubscriptions - The RPC subscriptions to use to send and confirm the transaction\n * @returns The success and signature of the confirmed transaction\n */\nexport async function sendAndConfirmSignedTransaction(\n  signedTransaction: Transaction,\n  rpc: RpcDevnet<SolanaRpcApiDevnet> | RpcMainnet<SolanaRpcApiMainnet>,\n  rpcSubscriptions: ReturnType<typeof getRpcSubscriptions>,\n): Promise<{ success: boolean; errorReason?: (typeof ErrorReasons)[number]; signature: string }> {\n  await sendSignedTransaction(signedTransaction, rpc);\n  return await confirmSignedTransaction(signedTransaction, rpc, rpcSubscriptions);\n}\n\n/**\n * Ensures the provided transaction contains a signature for every required address.\n *\n * @param transaction - Transaction to verify for complete signatures\n */\nfunction assertTransactionFullySigned(transaction: Transaction): void {\n  const missingAddresses = Object.entries(transaction.signatures)\n    .filter(([, signature]) => signature == null)\n    .map(([address]) => address);\n\n  if (missingAddresses.length > 0) {\n    throw new Error(`transaction_signer_missing_signatures:${missingAddresses.join(\",\")}`);\n  }\n}\n","import {\n  VerifyResponse,\n  PaymentPayload,\n  PaymentRequirements,\n  ExactSvmPayload,\n  ErrorReasons,\n} from \"../../../../types/verify\";\nimport { SupportedSVMNetworks } from \"../../../../types/shared\";\nimport { X402Config } from \"../../../../types/config\";\nimport {\n  Address,\n  assertIsInstructionWithAccounts,\n  assertIsInstructionWithData,\n  decompileTransactionMessage,\n  fetchEncodedAccounts,\n  getCompiledTransactionMessageDecoder,\n  type TransactionSigner,\n  SolanaRpcApiDevnet,\n  SolanaRpcApiMainnet,\n  RpcDevnet,\n  RpcMainnet,\n  Instruction,\n  AccountLookupMeta,\n  AccountMeta,\n  InstructionWithData,\n  BaseTransactionMessage,\n  TransactionMessageWithFeePayer,\n  TransactionMessageWithLifetime,\n} from \"@solana/kit\";\nimport {\n  parseSetComputeUnitLimitInstruction,\n  parseSetComputeUnitPriceInstruction,\n  COMPUTE_BUDGET_PROGRAM_ADDRESS,\n} from \"@solana-program/compute-budget\";\nimport {\n  findAssociatedTokenPda,\n  identifyToken2022Instruction,\n  parseTransferCheckedInstruction as parseTransferCheckedInstruction2022,\n  Token2022Instruction,\n  TOKEN_2022_PROGRAM_ADDRESS,\n} from \"@solana-program/token-2022\";\nimport {\n  identifyTokenInstruction,\n  parseTransferCheckedInstruction as parseTransferCheckedInstructionToken,\n  TOKEN_PROGRAM_ADDRESS,\n  TokenInstruction,\n} from \"@solana-program/token\";\nimport {\n  decodeTransactionFromPayload,\n  signAndSimulateTransaction,\n  getTokenPayerFromTransaction,\n} from \"../../../../shared/svm\";\nimport { getRpcClient } from \"../../../../shared/svm/rpc\";\nimport { SCHEME } from \"../../\";\n\n/**\n * Verify the payment payload against the payment requirements.\n *\n * @param signer - The signer that will sign and simulate the transaction\n * @param payload - The payment payload to verify\n * @param paymentRequirements - The payment requirements to verify against\n * @param config - Optional configuration for X402 operations (e.g., custom RPC URLs)\n * @returns A VerifyResponse indicating if the payment is valid and any invalidation reason\n */\nexport async function verify(\n  signer: TransactionSigner,\n  payload: PaymentPayload,\n  paymentRequirements: PaymentRequirements,\n  config?: X402Config,\n): Promise<VerifyResponse> {\n  try {\n    // verify that the scheme and network are supported\n    verifySchemesAndNetworks(payload, paymentRequirements);\n\n    // decode the base64 encoded transaction\n    const svmPayload = payload.payload as ExactSvmPayload;\n    const decodedTransaction = decodeTransactionFromPayload(svmPayload);\n    const rpc = getRpcClient(paymentRequirements.network, config?.svmConfig?.rpcUrl);\n\n    // perform transaction introspection to validate the transaction structure and details\n    await transactionIntrospection(svmPayload, paymentRequirements, signer, config);\n\n    // simulate the transaction to ensure it will execute successfully\n    const simulateResult = await signAndSimulateTransaction(signer, decodedTransaction, rpc);\n    if (simulateResult.value?.err) {\n      throw new Error(`invalid_exact_svm_payload_transaction_simulation_failed`);\n    }\n\n    return {\n      isValid: true,\n      invalidReason: undefined,\n      payer: getTokenPayerFromTransaction(decodedTransaction),\n    };\n  } catch (error) {\n    // if the error is one of the known error reasons, return the error reason\n    if (error instanceof Error) {\n      if (ErrorReasons.includes(error.message as (typeof ErrorReasons)[number])) {\n        return {\n          isValid: false,\n          invalidReason: error.message as (typeof ErrorReasons)[number],\n          payer: (() => {\n            try {\n              const tx = decodeTransactionFromPayload(payload.payload as ExactSvmPayload);\n              return getTokenPayerFromTransaction(tx);\n            } catch {\n              return undefined;\n            }\n          })(),\n        };\n      }\n    }\n\n    // if the error is not one of the known error reasons, return an unexpected error reason\n    console.error(error);\n    return {\n      isValid: false,\n      invalidReason: \"unexpected_verify_error\",\n      payer: (() => {\n        try {\n          const tx = decodeTransactionFromPayload(payload.payload as ExactSvmPayload);\n          return getTokenPayerFromTransaction(tx);\n        } catch {\n          return undefined;\n        }\n      })(),\n    };\n  }\n}\n\n/**\n * Verify that the scheme and network are supported.\n *\n * @param payload - The payment payload to verify\n * @param paymentRequirements - The payment requirements to verify against\n */\nexport function verifySchemesAndNetworks(\n  payload: PaymentPayload,\n  paymentRequirements: PaymentRequirements,\n): void {\n  if (payload.scheme !== SCHEME || paymentRequirements.scheme !== SCHEME) {\n    throw new Error(\"unsupported_scheme\");\n  }\n\n  if (\n    payload.network !== paymentRequirements.network ||\n    !SupportedSVMNetworks.includes(paymentRequirements.network)\n  ) {\n    throw new Error(\"invalid_network\");\n  }\n}\n\n/**\n * Perform transaction introspection to validate the transaction structure and transfer details.\n * This function handles decoding the transaction, validating the transfer instruction,\n * and verifying all transfer details against the payment requirements.\n *\n * @param svmPayload - The SVM payload containing the transaction\n * @param paymentRequirements - The payment requirements to verify against\n * @param signer - The signer that will sign the transaction\n * @param config - Optional configuration for X402 operations (e.g., custom RPC URLs)\n */\nexport async function transactionIntrospection(\n  svmPayload: ExactSvmPayload,\n  paymentRequirements: PaymentRequirements,\n  signer: TransactionSigner,\n  config?: X402Config,\n): Promise<void> {\n  const rpc = getRpcClient(paymentRequirements.network, config?.svmConfig?.rpcUrl);\n  const decodedTransaction = decodeTransactionFromPayload(svmPayload);\n  const compiledTransactionMessage = getCompiledTransactionMessageDecoder().decode(\n    decodedTransaction.messageBytes,\n  );\n  const transactionMessage = decompileTransactionMessage(compiledTransactionMessage);\n\n  await verifyTransactionInstructions(transactionMessage, paymentRequirements, signer, rpc);\n}\n\n/**\n * Verify that the transaction contains the expected instructions.\n *\n * @param transactionMessage - The transaction message to verify\n * @param paymentRequirements - The payment requirements to verify against\n * @param signer - The signer that will sign the transaction\n * @param rpc - The RPC client to use for verifying account existence\n * @throws Error if the transaction does not contain the expected instructions\n */\nexport async function verifyTransactionInstructions(\n  transactionMessage: BaseTransactionMessage &\n    TransactionMessageWithFeePayer &\n    TransactionMessageWithLifetime,\n  paymentRequirements: PaymentRequirements,\n  signer: TransactionSigner,\n  rpc: RpcDevnet<SolanaRpcApiDevnet> | RpcMainnet<SolanaRpcApiMainnet>,\n) {\n  // validate the number of expected instructions\n  if (transactionMessage.instructions.length !== 3) {\n    throw new Error(`invalid_exact_svm_payload_transaction_instructions_length`);\n  }\n\n  // verify that the compute limit and price instructions are valid\n  verifyComputeLimitInstruction(transactionMessage.instructions[0]);\n  verifyComputePriceInstruction(transactionMessage.instructions[1]);\n\n  // verify that the fee payer is not included in any instruction's accounts\n  transactionMessage.instructions.forEach(instruction => {\n    if (instruction.accounts?.some(account => account.address === signer.address)) {\n      throw new Error(\n        `invalid_exact_svm_payload_transaction_fee_payer_included_in_instruction_accounts`,\n      );\n    }\n  });\n\n  // verify that the transfer instruction is valid\n  // this expects the destination ATA to already exist\n  await verifyTransferInstruction(\n    transactionMessage.instructions[2],\n    paymentRequirements,\n    signer,\n    rpc,\n  );\n}\n\n/**\n * Verify that the compute limit instruction is valid.\n *\n * @param instruction - The compute limit instruction to verify\n * @throws Error if the compute limit instruction is invalid\n */\nexport function verifyComputeLimitInstruction(\n  instruction: Instruction<\n    string,\n    readonly (AccountLookupMeta<string, string> | AccountMeta<string>)[]\n  >,\n) {\n  try {\n    if (\n      instruction.programAddress.toString() !== COMPUTE_BUDGET_PROGRAM_ADDRESS.toString() ||\n      instruction.data?.[0] !== 2 // discriminator of set compute unit limit instruction\n    ) {\n      throw new Error(\n        `invalid_exact_svm_payload_transaction_instructions_compute_limit_instruction`,\n      );\n    }\n    parseSetComputeUnitLimitInstruction(\n      instruction as InstructionWithData<Uint8Array<ArrayBufferLike>>,\n    );\n  } catch (error) {\n    console.error(error);\n    throw new Error(`invalid_exact_svm_payload_transaction_instructions_compute_limit_instruction`);\n  }\n}\n\n/**\n * Verify that the compute price instruction is valid.\n * This function throws an error if the compute unit price is greater than 5 lamports,\n * to protect the facilitator against gas fee abuse from the client.\n *\n * @param instruction - The compute price instruction to verify\n * @throws Error if the compute price instruction is invalid\n */\nexport function verifyComputePriceInstruction(\n  instruction: Instruction<\n    string,\n    readonly (AccountLookupMeta<string, string> | AccountMeta<string>)[]\n  >,\n) {\n  if (\n    instruction.programAddress.toString() !== COMPUTE_BUDGET_PROGRAM_ADDRESS.toString() ||\n    instruction.data?.[0] !== 3 // discriminator of set compute unit price instruction\n  ) {\n    throw new Error(`invalid_exact_svm_payload_transaction_instructions_compute_price_instruction`);\n  }\n  const parsedInstruction = parseSetComputeUnitPriceInstruction(\n    instruction as InstructionWithData<Uint8Array<ArrayBufferLike>>,\n  );\n\n  // TODO: allow the facilitator to pass in an optional max compute unit price\n  if (parsedInstruction.data.microLamports > 5 * 1_000_000) {\n    throw new Error(\n      `invalid_exact_svm_payload_transaction_instructions_compute_price_instruction_too_high`,\n    );\n  }\n}\n\n/**\n * Verify that the create ATA instruction is valid.\n *\n * @param instruction - The create ATA instruction to verify\n * @param paymentRequirements - The payment requirements to verify against\n * @throws Error if the create ATA instruction is invalid\n */\n/**\n * Verify that the transfer instruction is valid.\n *\n * @param instruction - The transfer instruction to verify\n * @param paymentRequirements - The payment requirements to verify against\n * @param signer - The signer that will sign the transaction\n * @param rpc - The RPC client to use for verifying account existence\n * @throws Error if the transfer instruction is invalid\n */\nexport async function verifyTransferInstruction(\n  instruction: Instruction<\n    string,\n    readonly (AccountLookupMeta<string, string> | AccountMeta<string>)[]\n  >,\n  paymentRequirements: PaymentRequirements,\n  signer: TransactionSigner,\n  rpc: RpcDevnet<SolanaRpcApiDevnet> | RpcMainnet<SolanaRpcApiMainnet>,\n) {\n  // get a validated and parsed transferChecked instruction\n  const tokenInstruction = getValidatedTransferCheckedInstruction(instruction);\n  await verifyTransferCheckedInstruction(tokenInstruction, paymentRequirements, signer, rpc);\n}\n\n/**\n * Verify that the transfer checked instruction is valid.\n *\n * @param parsedInstruction - The parsed transfer checked instruction to verify\n * @param paymentRequirements - The payment requirements to verify against\n * @param signer - The signer that will sign the transaction\n * @param rpc - The RPC client to use for verifying account existence\n * @throws Error if the transfer checked instruction is invalid\n */\nexport async function verifyTransferCheckedInstruction(\n  parsedInstruction: ReturnType<typeof parseTransferCheckedInstruction2022>,\n  paymentRequirements: PaymentRequirements,\n  signer: TransactionSigner,\n  rpc: RpcDevnet<SolanaRpcApiDevnet> | RpcMainnet<SolanaRpcApiMainnet>,\n) {\n  // get the token program address\n  const tokenProgramAddress =\n    parsedInstruction.programAddress.toString() === TOKEN_PROGRAM_ADDRESS.toString()\n      ? TOKEN_PROGRAM_ADDRESS\n      : TOKEN_2022_PROGRAM_ADDRESS;\n\n  // verify that the fee payer is not transferring funds\n  if (parsedInstruction.accounts.authority.address === signer.address) {\n    throw new Error(`invalid_exact_svm_payload_transaction_fee_payer_transferring_funds`);\n  }\n\n  // get the expected receiver's ATA\n  const payToATA = await findAssociatedTokenPda({\n    mint: paymentRequirements.asset as Address,\n    owner: paymentRequirements.payTo as Address,\n    tokenProgram: tokenProgramAddress,\n  });\n\n  // verify that the transfer is to the expected ATA\n  if (parsedInstruction.accounts.destination.address !== payToATA[0]) {\n    throw new Error(`invalid_exact_svm_payload_transaction_transfer_to_incorrect_ata`);\n  }\n\n  // verify that the source and destination ATAs exist\n  const addresses = [parsedInstruction.accounts.source.address, payToATA[0]];\n  const maybeAccounts = await fetchEncodedAccounts(rpc, addresses);\n  const missingAccounts = maybeAccounts.filter(a => !a.exists);\n  for (const missingAccount of missingAccounts) {\n    if (missingAccount.address === parsedInstruction.accounts.source.address) {\n      throw new Error(`invalid_exact_svm_payload_transaction_sender_ata_not_found`);\n    }\n    if (missingAccount.address === payToATA[0]) {\n      throw new Error(`invalid_exact_svm_payload_transaction_receiver_ata_not_found`);\n    }\n  }\n\n  // verify that the amount is correct\n  const instructionAmount = parsedInstruction.data.amount;\n  const paymentRequirementsAmount = BigInt(paymentRequirements.maxAmountRequired);\n  if (instructionAmount !== paymentRequirementsAmount) {\n    throw new Error(`invalid_exact_svm_payload_transaction_amount_mismatch`);\n  }\n}\n\n/**\n * Inspect the decompiled transaction message to make sure that it is a valid\n * transfer instruction.\n *\n * @param instruction - The instruction to get the transfer instruction from\n * @returns The validated transfer instruction\n * @throws Error if the instruction is not a valid transfer checked instruction\n */\nexport function getValidatedTransferCheckedInstruction(\n  instruction: Instruction<\n    string,\n    readonly (AccountLookupMeta<string, string> | AccountMeta<string>)[]\n  >,\n) {\n  try {\n    assertIsInstructionWithData(instruction);\n    assertIsInstructionWithAccounts(instruction);\n  } catch (error) {\n    console.error(error);\n    throw new Error(`invalid_exact_svm_payload_transaction_instructions`);\n  }\n\n  let tokenInstruction;\n\n  // spl-token program\n  if (instruction.programAddress.toString() === TOKEN_PROGRAM_ADDRESS.toString()) {\n    const identifiedInstruction = identifyTokenInstruction(instruction);\n    if (identifiedInstruction !== TokenInstruction.TransferChecked) {\n      throw new Error(\n        `invalid_exact_svm_payload_transaction_instruction_not_spl_token_transfer_checked`,\n      );\n    }\n    tokenInstruction = parseTransferCheckedInstructionToken({\n      ...instruction,\n      data: new Uint8Array(instruction.data),\n    });\n  }\n  // token-2022 program\n  else if (instruction.programAddress.toString() === TOKEN_2022_PROGRAM_ADDRESS.toString()) {\n    const identifiedInstruction = identifyToken2022Instruction(instruction);\n    if (identifiedInstruction !== Token2022Instruction.TransferChecked) {\n      throw new Error(\n        `invalid_exact_svm_payload_transaction_instruction_not_token_2022_transfer_checked`,\n      );\n    }\n    tokenInstruction = parseTransferCheckedInstruction2022({\n      ...instruction,\n      data: new Uint8Array(instruction.data),\n    });\n  }\n  // invalid instruction\n  else {\n    throw new Error(`invalid_exact_svm_payload_transaction_not_a_transfer_instruction`);\n  }\n\n  return tokenInstruction;\n}\n","/**\n * How long a transaction is held in the duplicate settlement cache (ms).\n * Covers the Solana blockhash lifetime (~60-90s) with margin.\n */\nexport const SETTLEMENT_TTL_MS = 120_000;\n\n/**\n * In-memory cache for deduplicating concurrent settlement requests.\n *\n * Because Node.js is single-threaded, no lock is required — the cache\n * check + insert must simply occur before the first `await` in the settle path.\n */\nexport class SettlementCache {\n  private readonly entries = new Map<string, number>();\n\n  /**\n   * Returns `true` if `key` is already pending settlement (duplicate),\n   * or `false` after recording it as newly pending.\n   *\n   * Callers should reject the settlement when this returns `true`.\n   *\n   * @param key - The unique identifier for the settlement (typically the base64 transaction).\n   * @returns `true` if the key was already present (duplicate); `false` otherwise.\n   */\n  isDuplicate(key: string): boolean {\n    this.prune();\n    if (this.entries.has(key)) {\n      return true;\n    }\n    this.entries.set(key, Date.now());\n    return false;\n  }\n\n  /**\n   * Remove entries older than the settlement TTL.\n   * Leverages Map insertion-order guarantee to break early.\n   */\n  private prune(): void {\n    const cutoff = Date.now() - SETTLEMENT_TTL_MS;\n    for (const [key, timestamp] of this.entries) {\n      if (timestamp < cutoff) {\n        this.entries.delete(key);\n      } else {\n        break;\n      }\n    }\n  }\n}\n"],"mappings":"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","names":["createPaymentHeader","settle","verify","getCompiledTransactionMessageDecoder","verify","config","settle","config","verify","getCompiledTransactionMessageDecoder"]}