{"version":3,"sources":["../../../../src/exact/facilitator/scheme.ts"],"sourcesContent":["import {\n  scValToNative,\n  Transaction,\n  FeeBumpTransaction,\n  Address,\n  Operation,\n  xdr,\n  rpc,\n  TransactionBuilder,\n  SignerKey,\n  BASE_FEE,\n} from \"@stellar/stellar-sdk\";\nimport { Api } from \"@stellar/stellar-sdk/rpc\";\nimport { STELLAR_WILDCARD_CAIP2 } from \"../../constants\";\nimport { gatherAuthEntrySignatureStatus } from \"../../shared\";\nimport { ExactStellarPayloadV2 } from \"../../types\";\nimport {\n  getEstimatedLedgerCloseTimeSeconds,\n  getRpcClient,\n  getNetworkPassphrase,\n  isStellarNetwork,\n  RpcConfig,\n} from \"../../utils\";\nimport type { FacilitatorStellarSigner } from \"../../signer\";\nimport type {\n  Network,\n  PaymentPayload,\n  PaymentRequirements,\n  SchemeNetworkFacilitator,\n  SettleResponse,\n  VerifyResponse,\n} from \"@x402/core/types\";\n\nconst DEFAULT_TIMEOUT_SECONDS = 60;\nconst SUPPORTED_X402_VERSION = 2;\nconst DEFAULT_MAX_TRANSACTION_FEE_STROOPS = 50_000;\nconst SIGNATURE_EXPIRATION_LEDGER_TOLERANCE = 2;\n\n/**\n * Returns a round-robin selector for choosing which signer to use.\n * Each invocation returns a new selector with its own counter.\n *\n * @returns A function that selects the next address from the given array on each call\n */\nconst roundRobinSelectSigner = (): ((addresses: readonly string[]) => string) => {\n  let index = 0;\n  return addrs => addrs[index++ % addrs.length];\n};\n\n/**\n * Helper to create a `VerifyResponse` with `isValid: false`.\n *\n * @param reason - The error reason code\n * @param payer - Optional payer address\n * @param message - Optional human-readable detail for invalidMessage\n * @returns a `VerifyResponse` with `isValid: false` and the provided reason and (optional) payer\n */\nexport function invalidVerifyResponse(\n  reason: string,\n  payer?: string,\n  message?: string,\n): VerifyResponse {\n  return { isValid: false, invalidReason: reason, payer, invalidMessage: message };\n}\n\n/**\n * Helper to create a `VerifyResponse` with `isValid: true`.\n *\n * @param payer - The payer address\n * @returns a `VerifyResponse` with `isValid: true` and the provided payer\n */\nexport function validVerifyResponse(payer: string): VerifyResponse {\n  return { isValid: true, payer };\n}\n\ntype VerifyResult = {\n  response: VerifyResponse;\n  /** Present only when simulation succeeded (used by settle to derive the fee + fresh Soroban data). */\n  simResponse?: Api.SimulateTransactionSuccessResponse;\n};\n\n/**\n * Stellar facilitator implementation for the Exact payment scheme.\n */\nexport class ExactStellarScheme implements SchemeNetworkFacilitator {\n  readonly scheme = \"exact\";\n  readonly caipFamily = STELLAR_WILDCARD_CAIP2;\n\n  public readonly signingAddresses: ReadonlySet<string>;\n  public readonly areFeesSponsored: boolean;\n  public readonly rpcConfig?: RpcConfig;\n  public readonly maxTransactionFeeStroops: number;\n  public readonly feeBumpSigner?: FacilitatorStellarSigner;\n  private readonly signerMap: Map<string, FacilitatorStellarSigner>;\n  private readonly selectSigner: (addresses: readonly string[]) => string;\n\n  /**\n   * Creates a new ExactStellarScheme instance.\n   *\n   * @param signers - One or more Stellar signers managed by the facilitator for settlement\n   * @param options - Configuration options\n   * @param options.rpcConfig - Optional RPC configuration with custom RPC URL\n   * @param options.areFeesSponsored - Indicates if fees are sponsored (default: true)\n   * @param options.maxTransactionFeeStroops - Safety ceiling in stroops; verify rejects if the simulation-derived fee exceeds this (default: 50_000)\n   * @param options.selectSigner - Callback to select which signer to use (default: round-robin)\n   * @param options.feeBumpSigner - Optional signer used as fee source in a fee bump transaction wrapper.\n   *   When provided, settle() wraps the inner transaction (signed by the selected signer) in a\n   *   FeeBumpTransaction where the feeBumpSigner pays the fees, decoupling fee payment from sequence number management.\n   * @returns ExactStellarScheme instance\n   */\n  constructor(\n    signers: FacilitatorStellarSigner[],\n    {\n      rpcConfig,\n      areFeesSponsored = true,\n      maxTransactionFeeStroops = DEFAULT_MAX_TRANSACTION_FEE_STROOPS,\n      selectSigner = roundRobinSelectSigner(),\n      feeBumpSigner,\n    }: {\n      /** Optional RPC configuration with custom RPC URL */\n      rpcConfig?: RpcConfig;\n      /** Indicates if fees are sponsored (default: true) */\n      areFeesSponsored?: boolean;\n      /** Safety ceiling in stroops; verify rejects if the simulation-derived fee exceeds this (default: 50_000) */\n      maxTransactionFeeStroops?: number;\n      /** Optional callback to select which signer to use. Receives addresses array, returns selected address. Defaults to round-robin. */\n      selectSigner?: (addresses: readonly string[]) => string;\n      /** Optional signer used as fee source in a fee bump transaction wrapper. Decouples fee payment from sequence number management. */\n      feeBumpSigner?: FacilitatorStellarSigner;\n    } = {},\n  ) {\n    // Validate signers and store their data\n    if (!signers || signers.length === 0) {\n      throw new Error(\"At least one signer is required\");\n    }\n    this.signerMap = new Map(signers.map(s => [s.address, s]));\n    this.signingAddresses = new Set(this.signerMap.keys());\n\n    // Apply configuration options (with defaults)\n    this.rpcConfig = rpcConfig;\n    this.areFeesSponsored = areFeesSponsored ?? true;\n    this.maxTransactionFeeStroops = maxTransactionFeeStroops ?? DEFAULT_MAX_TRANSACTION_FEE_STROOPS;\n    this.selectSigner = selectSigner ?? roundRobinSelectSigner();\n    this.feeBumpSigner = feeBumpSigner;\n  }\n\n  /**\n   * Get mechanism-specific extra data for the supported kinds endpoint.\n   * For Stellar, returns `areFeesSponsored` indicating to clients if they can expect fees to be sponsored.\n   * As of now, the spec only supports `areFeesSponsored: true`.\n   *\n   * @param _ - The network identifier (unused, offset is network-agnostic)\n   * @returns Extra data with the `areFeesSponsored` flag\n   */\n  getExtra(_: Network): Record<string, unknown> | undefined {\n    return {\n      areFeesSponsored: this.areFeesSponsored,\n    };\n  }\n\n  /**\n   * Get signer addresses used by this facilitator.\n   * For Stellar, returns all facilitator addresses including the fee bump signer when configured.\n   *\n   * @param _ - The network identifier (unused for Stellar)\n   * @returns Array containing all facilitator addresses\n   */\n  getSigners(_: string): string[] {\n    const signers = [...this.signingAddresses];\n    if (this.feeBumpSigner && !this.signingAddresses.has(this.feeBumpSigner.address)) {\n      signers.push(this.feeBumpSigner.address);\n    }\n    return signers;\n  }\n\n  /**\n   * Verifies a payment payload.\n   *\n   * @param payload - The payment payload to verify\n   * @param requirements - The payment requirements\n   * @returns Promise resolving to verification response\n   */\n  async verify(\n    payload: PaymentPayload,\n    requirements: PaymentRequirements,\n  ): Promise<VerifyResponse> {\n    return (await this._verify(payload, requirements)).response;\n  }\n\n  /**\n   * Settles a payment by submitting the transaction on-chain.\n   *\n   * @param payload - The payment payload to settle\n   * @param requirements - The payment requirements\n   * @returns Promise resolving to settlement response\n   */\n  async settle(\n    payload: PaymentPayload,\n    requirements: PaymentRequirements,\n  ): Promise<SettleResponse> {\n    const server = getRpcClient(requirements.network, this.rpcConfig);\n    const networkPassphrase = getNetworkPassphrase(requirements.network);\n    let payer: string | undefined;\n    let txHash: string | undefined;\n\n    try {\n      // Step 1: Verify payment before settlement\n      const { response: verifyResult, simResponse } = await this._verify(payload, requirements);\n\n      if (!verifyResult.isValid) {\n        return {\n          success: false,\n          network: payload.accepted.network,\n          transaction: \"\",\n          errorReason: verifyResult.invalidReason ?? \"verification_failed\",\n          payer: verifyResult.payer,\n        };\n      }\n\n      if (!simResponse) {\n        return {\n          success: false,\n          network: payload.accepted.network,\n          transaction: \"\",\n          errorReason: \"unexpected_settle_error\",\n          payer: verifyResult.payer,\n        };\n      }\n\n      payer = verifyResult.payer!;\n\n      // Step 2: Parse transaction envelope to extract the operation\n      const stellarPayload = payload.payload as ExactStellarPayloadV2;\n      const transaction = new Transaction(stellarPayload.transaction, networkPassphrase);\n      const sorobanData = simResponse.transactionData.build();\n\n      // Step 3: Extract operation\n      const invokeOp = transaction.operations[0] as Operation.InvokeHostFunction;\n\n      // Step 4: Rebuild transaction with facilitator as source and simulation-derived fee\n      const signer = this.signerMap.get(this.selectSigner([...this.signingAddresses]));\n      if (!signer) {\n        return {\n          success: false,\n          network: payload.accepted.network,\n          transaction: \"\",\n          errorReason: \"settle_exact_stellar_signer_selection_failed\",\n          payer,\n        };\n      }\n      const facilitatorAccount = await server.getAccount(signer.address);\n\n      // SDK v16: `fee` is the inclusion buffer only; build() adds sorobanData.resourceFee()\n      // from the settle-time simulation, so tx.fee = BASE_FEE + minResourceFee.\n      const rebuiltTx = new TransactionBuilder(facilitatorAccount, {\n        fee: BASE_FEE,\n        networkPassphrase,\n        ledgerbounds: transaction.ledgerBounds,\n        memo: transaction.memo,\n        minAccountSequence: transaction.minAccountSequence,\n        minAccountSequenceAge: transaction.minAccountSequenceAge,\n        minAccountSequenceLedgerGap: transaction.minAccountSequenceLedgerGap,\n        extraSigners: transaction.extraSigners?.map(signerKey =>\n          SignerKey.encodeSignerKey(signerKey),\n        ),\n        sorobanData,\n      })\n        .setTimeout(requirements.maxTimeoutSeconds ?? DEFAULT_TIMEOUT_SECONDS)\n        .addOperation(Operation.invokeHostFunction(invokeOp))\n        .build();\n\n      // Step 5: Sign inner transaction with the selected signer's key\n      const { signedTxXdr, error: signError } = await signer.signTransaction(rebuiltTx.toXDR(), {\n        networkPassphrase,\n      });\n\n      if (signError) {\n        return {\n          success: false,\n          network: payload.accepted.network,\n          transaction: \"\",\n          errorReason: \"settle_exact_stellar_transaction_signing_failed\",\n          payer,\n        };\n      }\n\n      // Step 6: Optionally wrap in a fee bump transaction\n      let txToSubmit: Transaction | FeeBumpTransaction;\n\n      if (this.feeBumpSigner) {\n        const signedInnerTx = TransactionBuilder.fromXDR(\n          signedTxXdr,\n          networkPassphrase,\n        ) as Transaction;\n\n        const feeBumpTx = TransactionBuilder.buildFeeBumpTransaction(\n          this.feeBumpSigner.address,\n          // Same inclusion-only base fee; SDK adds the inner tx resource fee.\n          BASE_FEE,\n          signedInnerTx,\n          networkPassphrase,\n        );\n\n        const { signedTxXdr: signedFeeBumpXdr, error: feeBumpSignError } =\n          await this.feeBumpSigner.signTransaction(feeBumpTx.toXDR(), { networkPassphrase });\n\n        if (feeBumpSignError) {\n          return {\n            success: false,\n            network: payload.accepted.network,\n            transaction: \"\",\n            errorReason: \"settle_exact_stellar_fee_bump_signing_failed\",\n            payer,\n          };\n        }\n\n        txToSubmit = TransactionBuilder.fromXDR(\n          signedFeeBumpXdr,\n          networkPassphrase,\n        ) as FeeBumpTransaction;\n      } else {\n        txToSubmit = TransactionBuilder.fromXDR(signedTxXdr, networkPassphrase) as Transaction;\n      }\n\n      // Step 7: Submit transaction to network\n      const sendResult = await server.sendTransaction(txToSubmit);\n\n      if (sendResult.status !== \"PENDING\") {\n        return {\n          success: false,\n          network: payload.accepted.network,\n          transaction: \"\",\n          errorReason: \"settle_exact_stellar_transaction_submission_failed\",\n          payer,\n        };\n      }\n\n      // Step 8: Poll for transaction confirmation\n      txHash = sendResult.hash;\n      const maxPollAttempts = requirements.maxTimeoutSeconds ?? DEFAULT_TIMEOUT_SECONDS;\n      const confirmResult = await this.pollForTransaction(server, txHash, maxPollAttempts);\n\n      if (!confirmResult.success) {\n        return {\n          success: false,\n          network: payload.accepted.network,\n          transaction: txHash,\n          errorReason: \"settle_exact_stellar_transaction_failed\",\n          payer,\n        };\n      }\n\n      // Step 9: Return success\n      return {\n        success: true,\n        transaction: txHash,\n        network: payload.accepted.network,\n        payer: payer,\n      };\n    } catch (error) {\n      console.error(\"Unexpected settlement error:\", error);\n      return {\n        success: false,\n        network: payload.accepted.network,\n        transaction: txHash || \"\",\n        errorReason: \"unexpected_settle_error\",\n        payer,\n      };\n    }\n  }\n\n  /**\n   * Internal verification that also returns the simulation result for settlement.\n   *\n   * @param payload - The payment payload to verify\n   * @param requirements - The payment requirements\n   * @returns Verification response and optional simulation result\n   */\n  private async _verify(\n    payload: PaymentPayload,\n    requirements: PaymentRequirements,\n  ): Promise<VerifyResult> {\n    let fromAddress: string | undefined;\n    try {\n      // Step 1: Validate protocol version, scheme, and network\n      if (payload.x402Version !== SUPPORTED_X402_VERSION) {\n        return { response: invalidVerifyResponse(\"invalid_x402_version\") };\n      }\n\n      if (payload.accepted.scheme !== \"exact\" || requirements.scheme !== \"exact\") {\n        return { response: invalidVerifyResponse(\"unsupported_scheme\") };\n      }\n\n      if (requirements.network !== payload.accepted.network) {\n        return { response: invalidVerifyResponse(\"network_mismatch\") };\n      }\n      if (!isStellarNetwork(requirements.network)) {\n        return { response: invalidVerifyResponse(\"invalid_network\") };\n      }\n\n      const networkPassphrase = getNetworkPassphrase(requirements.network);\n      const server = getRpcClient(requirements.network, this.rpcConfig);\n\n      // Step 2: Parse and decode transaction\n      const stellarPayload = payload.payload as ExactStellarPayloadV2;\n      if (!stellarPayload || typeof stellarPayload.transaction !== \"string\") {\n        return { response: invalidVerifyResponse(\"invalid_exact_stellar_payload_malformed\") };\n      }\n\n      let transaction: Transaction;\n      try {\n        transaction = new Transaction(stellarPayload.transaction, networkPassphrase);\n      } catch (error) {\n        console.error(\"Error parsing transaction:\", error);\n        return { response: invalidVerifyResponse(\"invalid_exact_stellar_payload_malformed\") };\n      }\n\n      // Step 3: Validate transaction structure\n      if (transaction.operations.length !== 1) {\n        return { response: invalidVerifyResponse(\"invalid_exact_stellar_payload_wrong_operation\") };\n      }\n\n      const operation = transaction.operations[0];\n      if (operation.type !== \"invokeHostFunction\") {\n        return { response: invalidVerifyResponse(\"invalid_exact_stellar_payload_wrong_operation\") };\n      }\n\n      if (\n        this.signingAddresses.has(operation.source ?? \"\") ||\n        this.signingAddresses.has(transaction.source)\n      ) {\n        return {\n          response: invalidVerifyResponse(\"invalid_exact_stellar_payload_unsafe_tx_or_op_source\"),\n        };\n      }\n\n      // Step 4: Extract and validate contract invocation details\n      const invokeOp = operation as Operation.InvokeHostFunction;\n      const func = invokeOp.func;\n\n      if (!func || func.switch().name !== \"hostFunctionTypeInvokeContract\") {\n        return { response: invalidVerifyResponse(\"invalid_exact_stellar_payload_wrong_operation\") };\n      }\n\n      // Step 5: Validate contract address and function name\n      const invokeContractArgs = func.invokeContract();\n      const contractAddress = Address.fromScAddress(\n        invokeContractArgs.contractAddress(),\n      ).toString();\n      const functionName = invokeContractArgs.functionName().toString();\n\n      const args = invokeContractArgs.args();\n      if (contractAddress !== requirements.asset) {\n        return { response: invalidVerifyResponse(\"invalid_exact_stellar_payload_wrong_asset\") };\n      }\n\n      if (functionName !== \"transfer\" || args.length !== 3) {\n        return {\n          response: invalidVerifyResponse(\"invalid_exact_stellar_payload_wrong_function_name\"),\n        };\n      }\n\n      // Step 6: Extract and validate transfer arguments\n      fromAddress = scValToNative(args[0]) as string;\n      const toAddress = scValToNative(args[1]) as string;\n      const amount = scValToNative(args[2]) as bigint;\n\n      if (this.signingAddresses.has(fromAddress)) {\n        return {\n          response: invalidVerifyResponse(\"invalid_exact_stellar_payload_facilitator_is_payer\"),\n        };\n      }\n\n      if (toAddress !== requirements.payTo) {\n        return {\n          response: invalidVerifyResponse(\n            \"invalid_exact_stellar_payload_wrong_recipient\",\n            fromAddress,\n          ),\n        };\n      }\n\n      const expectedAmount = BigInt(requirements.amount);\n      if (amount !== expectedAmount) {\n        return {\n          response: invalidVerifyResponse(\n            \"invalid_exact_stellar_payload_wrong_amount\",\n            fromAddress,\n          ),\n        };\n      }\n\n      // Step 7: Re-simulate to ensure transaction will succeed\n      const simResponse = await server.simulateTransaction(transaction);\n      if (!Api.isSimulationSuccess(simResponse)) {\n        const errorMsg = simResponse.error ? `: ${simResponse.error}` : \"\";\n        console.error(\"Simulation error:\", errorMsg);\n        return {\n          response: invalidVerifyResponse(\n            \"invalid_exact_stellar_payload_simulation_failed\",\n            fromAddress,\n          ),\n        };\n      }\n\n      // Step 8: Validate the simulation-derived settlement fee against the safety ceiling\n      const minResourceFee = parseInt(simResponse.minResourceFee, 10);\n      const settlementFeeStroops = minResourceFee + parseInt(BASE_FEE, 10);\n      if (settlementFeeStroops > this.maxTransactionFeeStroops) {\n        return {\n          response: invalidVerifyResponse(\n            \"invalid_exact_stellar_payload_fee_exceeds_maximum\",\n            fromAddress,\n            `simulation-derived fee ${settlementFeeStroops} stroops exceeds ceiling ${this.maxTransactionFeeStroops} stroops`,\n          ),\n        };\n      }\n\n      // Step 9: Validate simulation events for expected transfer only.\n      const eventValidation = this.validateSimulationEvents(\n        simResponse.events,\n        fromAddress,\n        requirements.payTo,\n        expectedAmount,\n        requirements.asset,\n      );\n      if (eventValidation) {\n        return { response: eventValidation };\n      }\n\n      const latestLedger = await server.getLatestLedger();\n      const currentLedger = latestLedger.sequence;\n      const maxTimeoutSeconds = requirements.maxTimeoutSeconds ?? DEFAULT_TIMEOUT_SECONDS;\n      const estimatedLedgerSeconds = await getEstimatedLedgerCloseTimeSeconds(requirements.network);\n      const maxLedgerOffset = Math.ceil(maxTimeoutSeconds / estimatedLedgerSeconds);\n      const maxLedger = currentLedger + maxLedgerOffset;\n\n      // Step 10: Validate auth entries (structure, credential type, expiration, facilitator safety, and signature status).\n      const authValidation = this.validateAuthEntries(\n        invokeOp,\n        this.signingAddresses,\n        fromAddress,\n        maxLedger,\n        transaction,\n        simResponse,\n      );\n      if (authValidation) {\n        return { response: authValidation };\n      }\n\n      return { response: validVerifyResponse(fromAddress), simResponse };\n    } catch (error) {\n      console.error(\"Unexpected verification error:\", error);\n      return { response: invalidVerifyResponse(\"unexpected_verify_error\", fromAddress) };\n    }\n  }\n\n  /**\n   * Polls for transaction confirmation on Soroban.\n   *\n   * @param server - Soroban RPC server\n   * @param txHash - Transaction hash to poll for\n   * @param maxPollAttempts - Maximum number of polling attempts (default: 15)\n   * @param delayMs - Delay between attempts in milliseconds (default: 1000)\n   * @returns Result with success status\n   */\n  private async pollForTransaction(\n    server: rpc.Server,\n    txHash: string,\n    maxPollAttempts = 15,\n    delayMs = 1000,\n  ): Promise<{ success: boolean }> {\n    for (let i = 0; i < maxPollAttempts; i++) {\n      try {\n        const txResult = await server.getTransaction(txHash);\n\n        if (txResult.status === \"SUCCESS\") {\n          return { success: true };\n        } else if (txResult.status === \"FAILED\") {\n          return { success: false };\n        }\n\n        // Transaction still pending, wait and retry\n        await new Promise(resolve => setTimeout(resolve, delayMs));\n      } catch (error: unknown) {\n        if (error instanceof Error && !error.message.includes(\"NOT_FOUND\")) {\n          console.warn(`Poll attempt ${i} failed:`, error);\n        }\n        await new Promise(resolve => setTimeout(resolve, delayMs));\n      }\n    }\n\n    // Timeout\n    return { success: false };\n  }\n\n  /**\n   * Validates simulation events for transfer correctness.\n   * Ensures there is exactly one token transfer event, the transfer matches the\n   * expected sender, recipient, amount, and asset (contract address), and the\n   * facilitator address is not involved in the transfer.\n   *\n   * @param events - The array of DiagnosticEvent objects from the simulation\n   * @param fromAddress - The payer's address\n   * @param toAddress - The recipient's address\n   * @param expectedAmount - The expected transfer amount\n   * @param expectedAsset - The expected token contract address\n   * @returns undefined if the validation succeeds, otherwise an invalid VerifyResponse\n   */\n  private validateSimulationEvents(\n    events: xdr.DiagnosticEvent[],\n    fromAddress: string,\n    toAddress: string,\n    expectedAmount: bigint,\n    expectedAsset: string,\n  ): VerifyResponse | undefined {\n    // Soroban token transfer events follow the [CAP-46](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0046-06.md) format:\n    // Topic: [\"transfer\", from, to], Data: amount\n    const transferEvents: Array<{\n      from: string;\n      to: string;\n      amount: bigint;\n    }> = [];\n\n    // Parse events into\n    for (const diagnosticEvent of events) {\n      try {\n        const event = diagnosticEvent.event();\n\n        // Skip non-contract events\n        if (event.type().name !== \"contract\") {\n          continue;\n        }\n\n        const body = event.body().v0();\n        const topics = body.topics();\n\n        // Check if this is a transfer event (first topic is \"transfer\" symbol)\n        if (topics.length < 3) {\n          return invalidVerifyResponse(\n            \"invalid_exact_stellar_payload_event_not_transfer\",\n            fromAddress,\n          );\n        }\n\n        const topicType = topics[0].switch().name;\n        if (topicType !== \"scvSymbol\") {\n          return invalidVerifyResponse(\n            \"invalid_exact_stellar_payload_event_not_transfer\",\n            fromAddress,\n          );\n        }\n\n        const symbol = topics[0].sym().toString();\n        if (symbol !== \"transfer\") {\n          return invalidVerifyResponse(\n            \"invalid_exact_stellar_payload_event_not_transfer\",\n            fromAddress,\n          );\n        }\n\n        const contractIdHash = event.contractId();\n        if (!contractIdHash)\n          return invalidVerifyResponse(\n            \"invalid_exact_stellar_payload_event_missing_contract_id\",\n            fromAddress,\n          );\n        const eventContractAddress = Address.fromScAddress(\n          xdr.ScAddress.scAddressTypeContract(contractIdHash),\n        ).toString();\n        if (eventContractAddress !== expectedAsset) {\n          return invalidVerifyResponse(\n            \"invalid_exact_stellar_payload_event_wrong_asset\",\n            fromAddress,\n          );\n        }\n\n        // Extract from, to, and amount\n        const from = scValToNative(topics[1]) as string;\n        const to = scValToNative(topics[2]) as string;\n        const amount = scValToNative(body.data()) as bigint;\n\n        transferEvents.push({ from, to, amount });\n      } catch (error: unknown) {\n        if (error instanceof Error) {\n          console.error(\"Error parsing diagnostic event:\", error.message);\n        } else {\n          console.error(\"Error parsing diagnostic event:\", String(error));\n        }\n        return invalidVerifyResponse(\"unexpected_verify_error\", fromAddress);\n      }\n    }\n\n    // If no transfer events are present, reject.\n    if (transferEvents.length === 0) {\n      return invalidVerifyResponse(\"invalid_exact_stellar_payload_no_transfer_events\", fromAddress);\n    }\n\n    if (transferEvents.length > 1) {\n      return invalidVerifyResponse(\"invalid_exact_stellar_payload_multiple_transfers\", fromAddress);\n    }\n\n    const transferEvent = transferEvents[0];\n\n    // Validate the transfer matches the expected sender, recipient, and amount\n    if (transferEvent.from !== fromAddress) {\n      return invalidVerifyResponse(\"invalid_exact_stellar_payload_event_wrong_from\", fromAddress);\n    }\n    if (transferEvent.to !== toAddress) {\n      return invalidVerifyResponse(\"invalid_exact_stellar_payload_event_wrong_to\", fromAddress);\n    }\n    if (transferEvent.amount !== expectedAmount) {\n      return invalidVerifyResponse(\"invalid_exact_stellar_payload_event_wrong_amount\", fromAddress);\n    }\n\n    return undefined;\n  }\n\n  /**\n   * Validates authorization entries: structure, credential type, expiration,\n   * facilitator safety, no sub-invocations, and that the payer has signed and\n   * no other signatures are pending (per simulation).\n   *\n   * @param invokeOp - The invoke host function operation\n   * @param facilitatorAddresses - Set of all facilitator addresses\n   * @param fromAddress - The payer's address (for error reporting)\n   * @param maxLedger - The maximum allowed expiration ledger\n   * @param transaction - The full transaction (for signature status)\n   * @param simResponse - The simulation result (used to interpret auth entry signatures)\n   * @returns Invalid VerifyResponse when validation fails\n   */\n  private validateAuthEntries(\n    invokeOp: Operation.InvokeHostFunction,\n    facilitatorAddresses: ReadonlySet<string>,\n    fromAddress: string,\n    maxLedger: number,\n    transaction: Transaction,\n    simResponse: Api.SimulateTransactionSuccessResponse,\n  ): VerifyResponse | undefined {\n    if (!invokeOp.auth || invokeOp.auth.length === 0) {\n      return invalidVerifyResponse(\"invalid_exact_stellar_payload_no_auth_entries\", fromAddress);\n    }\n\n    for (const auth of invokeOp.auth) {\n      const credentialsType = auth.credentials().switch();\n\n      // Only address-based credentials are allowed\n      if (credentialsType !== xdr.SorobanCredentialsType.sorobanCredentialsAddress()) {\n        return invalidVerifyResponse(\n          \"invalid_exact_stellar_payload_unsupported_credential_type\",\n          fromAddress,\n        );\n      }\n\n      // Extract address from credentials\n      const addressCredentials = auth.credentials().address();\n      const authAddress = Address.fromScAddress(addressCredentials.address()).toString();\n\n      // Facilitator must not appear in auth entries\n      if (facilitatorAddresses.has(authAddress)) {\n        return invalidVerifyResponse(\n          \"invalid_exact_stellar_payload_facilitator_in_auth\",\n          fromAddress,\n        );\n      }\n\n      // Check signature expiration is within allowed window (with ledger tolerance for RPC skew)\n      const expirationLedger = addressCredentials.signatureExpirationLedger();\n      if (expirationLedger > maxLedger + SIGNATURE_EXPIRATION_LEDGER_TOLERANCE) {\n        return invalidVerifyResponse(\n          \"invalid_exact_stellar_signature_expiration_too_far\",\n          fromAddress,\n        );\n      }\n\n      // No sub-invocations allowed\n      const rootInvocation = auth.rootInvocation();\n      if (rootInvocation.subInvocations().length > 0) {\n        return invalidVerifyResponse(\n          \"invalid_exact_stellar_payload_has_subinvocations\",\n          fromAddress,\n        );\n      }\n    }\n\n    const authStatus = gatherAuthEntrySignatureStatus({\n      transaction,\n      simulationResponse: simResponse,\n    });\n    if (!authStatus.alreadySigned.includes(fromAddress)) {\n      return invalidVerifyResponse(\n        \"invalid_exact_stellar_payload_missing_payer_signature\",\n        fromAddress,\n      );\n    }\n    if (authStatus.pendingSignature.length > 0) {\n      return invalidVerifyResponse(\n        \"invalid_exact_stellar_payload_unexpected_pending_signatures\",\n        fromAddress,\n      );\n    }\n\n    return undefined;\n  }\n}\n"],"mappings":"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","names":[]}