{"version":3,"sources":["../../src/exact/v1/client/scheme.ts"],"sourcesContent":["import {\n  getSetComputeUnitLimitInstruction,\n  setTransactionMessageComputeUnitPrice,\n} from \"@solana-program/compute-budget\";\nimport { TOKEN_PROGRAM_ADDRESS } from \"@solana-program/token\";\nimport {\n  fetchMint,\n  findAssociatedTokenPda,\n  getTransferCheckedInstruction,\n  TOKEN_2022_PROGRAM_ADDRESS,\n} from \"@solana-program/token-2022\";\nimport {\n  appendTransactionMessageInstructions,\n  createTransactionMessage,\n  getBase64EncodedWireTransaction,\n  partiallySignTransactionMessageWithSigners,\n  pipe,\n  prependTransactionMessageInstruction,\n  setTransactionMessageFeePayer,\n  setTransactionMessageLifetimeUsingBlockhash,\n  type Address,\n} from \"@solana/kit\";\nimport type {\n  Network,\n  PaymentPayload,\n  PaymentRequirements,\n  SchemeNetworkClient,\n} from \"@payai/x402/types\";\nimport type { PaymentRequirementsV1 } from \"@payai/x402/types/v1\";\nimport {\n  DEFAULT_COMPUTE_UNIT_LIMIT,\n  DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS,\n  MAX_MEMO_BYTES,\n  MEMO_PROGRAM_ADDRESS,\n} from \"../../../constants\";\nimport type { ClientSvmConfig, ClientSvmSigner } from \"../../../signer\";\nimport type { ExactSvmPayloadV1 } from \"../../../types\";\nimport { createRpcClient } from \"../../../utils\";\n\n/**\n * SVM client implementation for the Exact payment scheme (V1).\n */\nexport class ExactSvmSchemeV1 implements SchemeNetworkClient {\n  readonly scheme = \"exact\";\n\n  /**\n   * Creates a new ExactSvmClientV1 instance.\n   *\n   * @param signer - The SVM signer for client operations\n   * @param config - Optional configuration with custom RPC URL\n   * @returns ExactSvmClientV1 instance\n   */\n  constructor(\n    private readonly signer: ClientSvmSigner,\n    private readonly config?: ClientSvmConfig,\n  ) {}\n\n  /**\n   * Creates a payment payload for the Exact scheme (V1).\n   *\n   * @param x402Version - The x402 protocol version\n   * @param paymentRequirements - The payment requirements\n   * @returns Promise resolving to a payment payload\n   */\n  async createPaymentPayload(\n    x402Version: number,\n    paymentRequirements: PaymentRequirements,\n  ): Promise<\n    Pick<PaymentPayload, \"x402Version\" | \"payload\"> & { scheme: string; network: Network }\n  > {\n    const selectedV1 = paymentRequirements as unknown as PaymentRequirementsV1;\n    const rpc = createRpcClient(selectedV1.network, this.config?.rpcUrl);\n\n    const tokenMint = await fetchMint(rpc, selectedV1.asset as Address);\n    const tokenProgramAddress = tokenMint.programAddress;\n\n    if (\n      tokenProgramAddress.toString() !== TOKEN_PROGRAM_ADDRESS.toString() &&\n      tokenProgramAddress.toString() !== TOKEN_2022_PROGRAM_ADDRESS.toString()\n    ) {\n      throw new Error(\"Asset was not created by a known token program\");\n    }\n\n    const [sourceATA] = await findAssociatedTokenPda({\n      mint: selectedV1.asset as Address,\n      owner: this.signer.address,\n      tokenProgram: tokenProgramAddress,\n    });\n\n    const [destinationATA] = await findAssociatedTokenPda({\n      mint: selectedV1.asset as Address,\n      owner: selectedV1.payTo as Address,\n      tokenProgram: tokenProgramAddress,\n    });\n\n    const transferIx = getTransferCheckedInstruction(\n      {\n        source: sourceATA,\n        mint: selectedV1.asset as Address,\n        destination: destinationATA,\n        authority: this.signer,\n        amount: BigInt(selectedV1.maxAmountRequired),\n        decimals: tokenMint.data.decimals,\n      },\n      { programAddress: tokenProgramAddress },\n    );\n\n    // Facilitator must provide feePayer to cover transaction fees\n    const feePayer = selectedV1.extra?.feePayer as Address;\n    if (!feePayer) {\n      throw new Error(\"feePayer is required in paymentRequirements.extra for SVM transactions\");\n    }\n\n    const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();\n\n    const sellerMemo = selectedV1.extra?.memo as string | undefined;\n    let memoData: Uint8Array;\n    if (sellerMemo) {\n      memoData = new TextEncoder().encode(sellerMemo);\n      if (memoData.byteLength > MAX_MEMO_BYTES) {\n        throw new Error(`extra.memo exceeds maximum ${MAX_MEMO_BYTES} bytes`);\n      }\n    } else {\n      const nonce = crypto.getRandomValues(new Uint8Array(16));\n      memoData = new TextEncoder().encode(\n        Array.from(nonce)\n          .map(b => b.toString(16).padStart(2, \"0\"))\n          .join(\"\"),\n      );\n    }\n    const memoIx = {\n      programAddress: MEMO_PROGRAM_ADDRESS as Address,\n      accounts: [] as const,\n      data: memoData,\n    };\n\n    const tx = pipe(\n      createTransactionMessage({ version: 0 }),\n      tx => setTransactionMessageComputeUnitPrice(DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS, tx),\n      tx => setTransactionMessageFeePayer(feePayer, tx),\n      tx =>\n        prependTransactionMessageInstruction(\n          getSetComputeUnitLimitInstruction({ units: DEFAULT_COMPUTE_UNIT_LIMIT }),\n          tx,\n        ),\n      tx => appendTransactionMessageInstructions([transferIx, memoIx], tx),\n      tx => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),\n    );\n\n    const signedTransaction = await partiallySignTransactionMessageWithSigners(tx);\n    const base64EncodedWireTransaction = getBase64EncodedWireTransaction(signedTransaction);\n\n    const payload: ExactSvmPayloadV1 = {\n      transaction: base64EncodedWireTransaction,\n    };\n\n    return {\n      x402Version,\n      scheme: selectedV1.scheme,\n      network: selectedV1.network,\n      payload,\n    };\n  }\n}\n"],"mappings":"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","names":["tx"]}