{"version":3,"sources":["../../src/exact/v1/facilitator/scheme.ts"],"sourcesContent":["import {\n COMPUTE_BUDGET_PROGRAM_ADDRESS,\n parseSetComputeUnitLimitInstruction,\n parseSetComputeUnitPriceInstruction,\n} from \"@solana-program/compute-budget\";\nimport {\n parseTransferCheckedInstruction as parseTransferCheckedInstructionToken,\n TOKEN_PROGRAM_ADDRESS,\n} from \"@solana-program/token\";\nimport {\n findAssociatedTokenPda,\n parseTransferCheckedInstruction as parseTransferCheckedInstruction2022,\n TOKEN_2022_PROGRAM_ADDRESS,\n} from \"@solana-program/token-2022\";\nimport {\n decompileTransactionMessage,\n getCompiledTransactionMessageDecoder,\n type Address,\n} from \"@solana/kit\";\nimport type {\n PaymentPayload,\n PaymentRequirements,\n SchemeNetworkFacilitator,\n SettleResponse,\n VerifyResponse,\n} from \"@x402/core/types\";\nimport type { PaymentPayloadV1, PaymentRequirementsV1 } from \"@x402/core/types/v1\";\nimport {\n LIGHTHOUSE_PROGRAM_ADDRESS,\n MAX_COMPUTE_UNIT_PRICE_MICROLAMPORTS,\n MEMO_PROGRAM_ADDRESS,\n} from \"../../../constants\";\nimport { SettlementCache } from \"../../../settlement-cache\";\nimport type { FacilitatorSvmSigner } from \"../../../signer\";\nimport type { ExactSvmPayloadV1 } from \"../../../types\";\nimport { decodeTransactionFromPayload, getTokenPayerFromTransaction } from \"../../../utils\";\n\n/**\n * SVM facilitator implementation for the Exact payment scheme (V1).\n */\nexport class ExactSvmSchemeV1 implements SchemeNetworkFacilitator {\n readonly scheme = \"exact\";\n readonly caipFamily = \"solana:*\";\n\n private readonly settlementCache: SettlementCache;\n\n /**\n * Creates a new ExactSvmFacilitatorV1 instance.\n *\n * @param signer - The SVM RPC client for facilitator operations\n * @param settlementCache - Optional shared settlement cache (one is created if omitted)\n * @returns ExactSvmFacilitatorV1 instance\n */\n constructor(\n private readonly signer: FacilitatorSvmSigner,\n settlementCache?: SettlementCache,\n ) {\n this.settlementCache = settlementCache ?? new SettlementCache();\n }\n\n /**\n * Get mechanism-specific extra data for the supported kinds endpoint.\n * For SVM, this includes a randomly selected fee payer address.\n * Random selection distributes load across multiple signers.\n *\n * @param _ - The network identifier (unused for SVM)\n * @returns Extra data with feePayer address\n */\n getExtra(_: string): Record | undefined {\n // Randomly select from available signers to distribute load\n const addresses = this.signer.getAddresses();\n const randomIndex = Math.floor(Math.random() * addresses.length);\n\n return {\n feePayer: addresses[randomIndex],\n };\n }\n\n /**\n * Get signer addresses used by this facilitator.\n * For SVM, returns all available fee payer addresses.\n *\n * @param _ - The network identifier (unused for SVM)\n * @returns Array of fee payer addresses\n */\n getSigners(_: string): string[] {\n return [...this.signer.getAddresses()];\n }\n\n /**\n * Verifies a payment payload (V1).\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 {\n const requirementsV1 = requirements as unknown as PaymentRequirementsV1;\n const payloadV1 = payload as unknown as PaymentPayloadV1;\n const exactSvmPayload = payload.payload as ExactSvmPayloadV1;\n\n // Step 1: Validate Payment Requirements\n if (payloadV1.scheme !== \"exact\" || requirements.scheme !== \"exact\") {\n return {\n isValid: false,\n invalidReason: \"unsupported_scheme\",\n payer: \"\",\n };\n }\n\n if (payloadV1.network !== requirements.network) {\n return {\n isValid: false,\n invalidReason: \"network_mismatch\",\n payer: \"\",\n };\n }\n\n if (!requirementsV1.extra?.feePayer || typeof requirementsV1.extra.feePayer !== \"string\") {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_svm_payload_missing_fee_payer\",\n payer: \"\",\n };\n }\n\n // Verify that the requested feePayer is managed by this facilitator\n const signerAddresses = this.signer.getAddresses().map(addr => addr.toString());\n if (!signerAddresses.includes(requirementsV1.extra.feePayer)) {\n return {\n isValid: false,\n invalidReason: \"fee_payer_not_managed_by_facilitator\",\n payer: \"\",\n };\n }\n\n // Step 2: Parse and Validate Transaction Structure\n let transaction;\n try {\n transaction = decodeTransactionFromPayload(exactSvmPayload);\n } catch {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_svm_payload_transaction_could_not_be_decoded\",\n payer: \"\",\n };\n }\n\n const compiled = getCompiledTransactionMessageDecoder().decode(transaction.messageBytes);\n const decompiled = decompileTransactionMessage(compiled);\n const instructions = decompiled.instructions ?? [];\n\n // Allow 3-6 instructions:\n // - 3 instructions: ComputeLimit + ComputePrice + TransferChecked\n // - 4 instructions: ComputeLimit + ComputePrice + TransferChecked + Lighthouse or Memo\n // - 5 instructions: ComputeLimit + ComputePrice + TransferChecked + Lighthouse + Lighthouse or Memo\n // - 6 instructions: ComputeLimit + ComputePrice + TransferChecked + Lighthouse + Lighthouse + Memo\n // See: https://github.com/coinbase/x402/issues/828\n if (instructions.length < 3 || instructions.length > 6) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_svm_payload_transaction_instructions_length\",\n payer: \"\",\n };\n }\n\n // Step 3: Verify Compute Budget Instructions\n try {\n this.verifyComputeLimitInstruction(instructions[0] as never);\n this.verifyComputePriceInstruction(instructions[1] as never);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n isValid: false,\n invalidReason: errorMessage,\n payer: \"\",\n };\n }\n\n const payer = getTokenPayerFromTransaction(transaction);\n if (!payer) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_svm_payload_no_transfer_instruction\",\n payer: \"\",\n };\n }\n\n // Step 4: Verify Transfer Instruction\n const transferIx = instructions[2];\n const programAddress = transferIx.programAddress.toString();\n\n if (\n programAddress !== TOKEN_PROGRAM_ADDRESS.toString() &&\n programAddress !== TOKEN_2022_PROGRAM_ADDRESS.toString()\n ) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_svm_payload_no_transfer_instruction\",\n payer,\n };\n }\n\n // Parse the transfer instruction using the appropriate library helper\n let parsedTransfer;\n try {\n if (programAddress === TOKEN_PROGRAM_ADDRESS.toString()) {\n parsedTransfer = parseTransferCheckedInstructionToken(transferIx as never);\n } else {\n parsedTransfer = parseTransferCheckedInstruction2022(transferIx as never);\n }\n } catch {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_svm_payload_no_transfer_instruction\",\n payer,\n };\n }\n\n // Verify that the facilitator's signers are not transferring their own funds\n // SECURITY: Prevent facilitator from signing away their own tokens\n const authorityAddress = parsedTransfer.accounts.authority.address.toString();\n if (signerAddresses.includes(authorityAddress)) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_svm_payload_transaction_fee_payer_transferring_funds\",\n payer,\n };\n }\n\n // Verify mint address matches requirements\n const mintAddress = parsedTransfer.accounts.mint.address.toString();\n if (mintAddress !== requirements.asset) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_svm_payload_mint_mismatch\",\n payer,\n };\n }\n\n // Verify destination ATA matches expected ATA for payTo address\n const destATA = parsedTransfer.accounts.destination.address.toString();\n try {\n const [expectedDestATA] = await findAssociatedTokenPda({\n mint: requirements.asset as Address,\n owner: requirements.payTo as Address,\n tokenProgram:\n programAddress === TOKEN_PROGRAM_ADDRESS.toString()\n ? (TOKEN_PROGRAM_ADDRESS as Address)\n : (TOKEN_2022_PROGRAM_ADDRESS as Address),\n });\n\n if (destATA !== expectedDestATA.toString()) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_svm_payload_recipient_mismatch\",\n payer,\n };\n }\n } catch {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_svm_payload_recipient_mismatch\",\n payer,\n };\n }\n\n // Verify transfer amount exactly matches requirements\n const amount = parsedTransfer.data.amount;\n if (amount !== BigInt(requirementsV1.maxAmountRequired)) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_svm_payload_amount_mismatch\",\n payer,\n };\n }\n\n // Step 5: Verify optional instructions (if present)\n // Allowed optional programs: Lighthouse (wallet protection) and Memo (uniqueness)\n const optionalInstructions = instructions.slice(3);\n const invalidReasonByIndex = [\n \"invalid_exact_svm_payload_unknown_fourth_instruction\",\n \"invalid_exact_svm_payload_unknown_fifth_instruction\",\n \"invalid_exact_svm_payload_unknown_sixth_instruction\",\n ];\n\n for (let i = 0; i < optionalInstructions.length; i += 1) {\n const programAddress = optionalInstructions[i].programAddress.toString();\n if (\n programAddress === LIGHTHOUSE_PROGRAM_ADDRESS ||\n programAddress === MEMO_PROGRAM_ADDRESS\n ) {\n continue;\n }\n\n return {\n isValid: false,\n invalidReason:\n invalidReasonByIndex[i] ?? \"invalid_exact_svm_payload_unknown_optional_instruction\",\n payer,\n };\n }\n\n // Step 6: Sign and Simulate Transaction\n // CRITICAL: Simulation proves transaction will succeed (catches insufficient balance, invalid accounts, etc)\n try {\n const feePayer = requirementsV1.extra.feePayer as Address;\n\n // Sign transaction with the feePayer's signer\n const fullySignedTransaction = await this.signer.signTransaction(\n exactSvmPayload.transaction,\n feePayer,\n requirements.network,\n );\n\n // Simulate to verify transaction would succeed\n await this.signer.simulateTransaction(fullySignedTransaction, requirements.network);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n isValid: false,\n invalidReason: \"transaction_simulation_failed\",\n invalidMessage: errorMessage,\n payer,\n };\n }\n\n return {\n isValid: true,\n invalidReason: undefined,\n payer,\n };\n }\n\n /**\n * Settles a payment by submitting the transaction (V1).\n * Ensures the correct signer is used based on the feePayer specified in requirements.\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 {\n const payloadV1 = payload as unknown as PaymentPayloadV1;\n const exactSvmPayload = payload.payload as ExactSvmPayloadV1;\n\n const valid = await this.verify(payload, requirements);\n if (!valid.isValid) {\n return {\n success: false,\n network: payloadV1.network,\n transaction: \"\",\n errorReason: valid.invalidReason ?? \"verification_failed\",\n payer: valid.payer || \"\",\n };\n }\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 = exactSvmPayload.transaction;\n if (this.settlementCache.isDuplicate(txKey)) {\n return {\n success: false,\n network: payloadV1.network,\n transaction: \"\",\n errorReason: \"duplicate_settlement\",\n payer: valid.payer || \"\",\n };\n }\n\n try {\n // Extract feePayer from requirements (already validated in verify)\n const feePayer = requirements.extra.feePayer as Address;\n\n // Sign transaction with the feePayer's signer\n const fullySignedTransaction = await this.signer.signTransaction(\n exactSvmPayload.transaction,\n feePayer,\n requirements.network,\n );\n\n // Send transaction to network\n const signature = await this.signer.sendTransaction(\n fullySignedTransaction,\n requirements.network,\n );\n\n // Wait for confirmation\n await this.signer.confirmTransaction(signature, requirements.network);\n\n return {\n success: true,\n transaction: signature,\n network: payloadV1.network,\n payer: valid.payer,\n };\n } catch (error) {\n console.error(\"Failed to settle transaction:\", error);\n return {\n success: false,\n errorReason: \"transaction_failed\",\n transaction: \"\",\n network: payloadV1.network,\n payer: valid.payer || \"\",\n };\n }\n }\n\n /**\n * Verify compute limit instruction\n *\n * @param instruction - The compute limit instruction\n * @param instruction.programAddress - Program address\n * @param instruction.data - Instruction data bytes\n */\n private verifyComputeLimitInstruction(instruction: {\n programAddress: Address;\n data?: Readonly;\n }): void {\n const programAddress = instruction.programAddress.toString();\n\n if (\n programAddress !== COMPUTE_BUDGET_PROGRAM_ADDRESS.toString() ||\n !instruction.data ||\n instruction.data[0] !== 2\n ) {\n throw new Error(\n \"invalid_exact_svm_payload_transaction_instructions_compute_limit_instruction\",\n );\n }\n\n try {\n parseSetComputeUnitLimitInstruction(instruction as never);\n } catch {\n throw new Error(\n \"invalid_exact_svm_payload_transaction_instructions_compute_limit_instruction\",\n );\n }\n }\n\n /**\n * Verify compute price instruction\n *\n * @param instruction - The compute price instruction\n * @param instruction.programAddress - Program address\n * @param instruction.data - Instruction data bytes\n */\n private verifyComputePriceInstruction(instruction: {\n programAddress: Address;\n data?: Readonly;\n }): void {\n const programAddress = instruction.programAddress.toString();\n\n if (\n programAddress !== COMPUTE_BUDGET_PROGRAM_ADDRESS.toString() ||\n !instruction.data ||\n instruction.data[0] !== 3\n ) {\n throw new Error(\n \"invalid_exact_svm_payload_transaction_instructions_compute_price_instruction\",\n );\n }\n\n try {\n const parsedInstruction = parseSetComputeUnitPriceInstruction(instruction as never);\n\n // Check if price exceeds maximum (5 lamports per compute unit)\n if (\n (parsedInstruction as unknown as { microLamports: bigint }).microLamports >\n BigInt(MAX_COMPUTE_UNIT_PRICE_MICROLAMPORTS)\n ) {\n throw new Error(\n \"invalid_exact_svm_payload_transaction_instructions_compute_price_instruction_too_high\",\n );\n }\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"too_high\")) {\n throw error;\n }\n throw new Error(\n \"invalid_exact_svm_payload_transaction_instructions_compute_price_instruction\",\n );\n }\n }\n}\n"],"mappings":"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","names":["programAddress"]}