{"version":3,"sources":["../../src/exact/v1/client/scheme.ts"],"sourcesContent":["import {\n  Network,\n  PaymentPayload,\n  PaymentRequirements,\n  SchemeNetworkClient,\n} from \"@aeon-ai-pay/core/types\";\nimport { PaymentRequirementsV1 } from \"@aeon-ai-pay/core/types/v1\";\nimport {encodeFunctionData, getAddress, Hex} from \"viem\";\nimport {aeonAuthorizationPrimaryType, aeonAuthorizationTypes, authorizationTypes, ERC20_ABI} from \"../../../constants\";\nimport { ClientEvmSigner } from \"../../../signer\";\nimport { ExactEvmPayloadV1 } from \"../../../types\";\nimport { createNonce, getEvmChainId } from \"../../../utils\";\nimport {verifyTransferWithAuthorizationSupport} from \"../../../contractUtils\";\nimport console from \"node:console\";\n\n/**\n * EVM client implementation for the Exact payment scheme (V1).\n */\nexport class ExactEvmSchemeV1 implements SchemeNetworkClient {\n  readonly scheme = \"exact\";\n\n  /**\n   * Creates a new ExactEvmClientV1 instance.\n   *\n   * @param signer - The EVM signer for client operations\n   */\n  constructor(private readonly signer: ClientEvmSigner) {}\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 nonce = createNonce();\n    const now = Math.floor(Date.now() / 1000);\n\n    const authorization: ExactEvmPayloadV1[\"authorization\"] = {\n      from: this.signer.address,\n      to: getAddress(selectedV1.payTo),\n      value: selectedV1.maxAmountRequired,\n      validAfter: (now - 600).toString(), // 10 minutes before\n      validBefore: (now + selectedV1.maxTimeoutSeconds).toString(),\n      nonce,\n    };\n\n    // 验证代币合约是否有TransferWithAuthorization函数\n    const supportsTransferWithAuthorization = await verifyTransferWithAuthorizationSupport(\n        this.signer,\n        paymentRequirements.asset,\n    );\n    console.log(\"[DEBUG] tokenAddress:\", paymentRequirements.asset);\n    console.log(\"[DEBUG] supportsTransferWithAuthorization:\", supportsTransferWithAuthorization);\n\n    let authorizationResult;\n    if (supportsTransferWithAuthorization) {\n      authorizationResult = await this.signAuthorization(authorization, selectedV1);\n    } else {\n      authorizationResult = await this.signAuthorizationNoSuperEip3009(\n          authorization,\n          selectedV1,\n      );\n    }\n\n    const signature = authorizationResult;\n    // Sign the authorization\n    // const signature = await this.signAuthorization(authorization, selectedV1);\n\n    const payload: ExactEvmPayloadV1 = {\n      authorization,\n      signature,\n    };\n\n    return {\n      x402Version,\n      scheme: selectedV1.scheme,\n      network: selectedV1.network,\n      payload,\n    };\n  }\n\n  /**\n   * Sign the EIP-3009 authorization using EIP-712\n   *\n   * @param authorization - The authorization to sign\n   * @param requirements - The payment requirements\n   * @returns Promise resolving to the signature\n   */\n  private async signAuthorization(\n    authorization: ExactEvmPayloadV1[\"authorization\"],\n    requirements: PaymentRequirementsV1,\n  ): Promise<`0x${string}`> {\n    const chainId = getEvmChainId(requirements.network);\n\n    if (!requirements.extra?.name || !requirements.extra?.version) {\n      throw new Error(\n        `EIP-712 domain parameters (name, version) are required in payment requirements for asset ${requirements.asset}`,\n      );\n    }\n\n    const { name, version } = requirements.extra;\n\n    const domain = {\n      name,\n      version,\n      chainId,\n      verifyingContract: getAddress(requirements.asset),\n    };\n\n    const message = {\n      from: getAddress(authorization.from),\n      to: getAddress(authorization.to),\n      value: BigInt(authorization.value),\n      validAfter: BigInt(authorization.validAfter),\n      validBefore: BigInt(authorization.validBefore),\n      nonce: authorization.nonce,\n    };\n\n    return await this.signer.signTypedData({\n      domain,\n      types: authorizationTypes,\n      primaryType: \"TransferWithAuthorization\",\n      message,\n    });\n  }\n\n  /**\n   * Sign the EIP-3009 authorization using EIP-712\n   *\n   * @param authorization - The authorization to sign\n   * @param requirements - The payment requirements\n   * @returns Promise resolving to the signature\n   */\n  private async signAuthorizationNoSuperEip3009(\n      authorization: ExactEvmPayloadV1[\"authorization\"],\n      requirements: PaymentRequirementsV1,\n  ): Promise<`0x${string}`> {\n    const chainId = getEvmChainId(requirements.network);\n\n    if (!requirements.extra?.name || !requirements.extra?.version) {\n      throw new Error(\n          `EIP-712 domain parameters (name, version) are required in payment requirements for asset ${requirements.asset}`,\n      );\n    }\n\n    const from = getAddress(authorization.from);\n    const facilitatorAddress = getAddress(\"0x555e3311a9893c9B17444C1Ff0d88192a57Ef13e\");\n\n    // Read current allowance and auto-approve if needed\n    const currentAllowance = (await this.signer.readContract({\n      address: getAddress(requirements.asset) as Hex,\n      abi: ERC20_ABI,\n      functionName: \"allowance\",\n      args: [from, facilitatorAddress],\n    })) as bigint;\n\n    const requiredAmount = BigInt(authorization.value);\n    if (currentAllowance < requiredAmount) {\n      const approveData = encodeFunctionData({\n        abi: ERC20_ABI,\n        functionName: \"approve\",\n        args: [facilitatorAddress, requiredAmount],\n      });\n      const  tx=await this.signer.sendTransaction({\n        to: getAddress(requirements.asset),\n        data: approveData,\n      });\n\n      console.log(\" Wait for approval transaction to be confirmed requiredAmount:\",requiredAmount)\n      // Wait for approval transaction to be confirmed\n      const approvalReceipt = await this.signer.waitForTransactionReceipt({\n        hash: tx,\n      });\n\n      if (approvalReceipt.status !== \"success\") {\n        throw new Error(\"Token approval transaction failed\");\n      }\n      console.log(\"approve tx:\", tx);\n    }\n\n\n\n    // const { name, version } = requirements.extra;\n\n    const domain = {\n      name: \"Facilitator\",\n      version: \"1\",\n      chainId,\n      verifyingContract: getAddress(\"0x555e3311a9893c9B17444C1Ff0d88192a57Ef13e\"),\n    };\n\n    const message = {\n      token: getAddress(requirements.asset),\n      from: getAddress(authorization.from),\n      to: getAddress(authorization.to),\n      value: BigInt(authorization.value),\n      validAfter: BigInt(authorization.validAfter),\n      validBefore: BigInt(authorization.validBefore),\n      nonce: authorization.nonce,\n      needApprove: true,\n    };\n\n    return await this.signer.signTypedData({\n      domain,\n      types: aeonAuthorizationTypes,\n      primaryType: aeonAuthorizationPrimaryType,\n      message,\n    });\n  }\n}\n"],"mappings":"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","names":[]}