{"version":3,"sources":["../../src/exact/client/scheme.ts","../../src/exact/client/register.ts"],"sourcesContent":["import { PaymentPayload, PaymentRequirements, SchemeNetworkClient } from '@x402/core/types'\nimport { getAddress } from 'viem'\nimport { eip3009AuthorizationTypes, permitNonceABI, permitTypes } from '../../constants'\nimport { X402xClientEvmSigner, X402xPublicEvmClient } from '../../signer'\nimport { createNonce, resolveEip712Domain } from '../../utils'\nimport { X402X_EVM_SCHEME } from '../../constants'\nimport { PermitType, ExactX402xEvmPayload } from '../../types'\n\nexport interface ExactX402xEvmClientConfig {\n  signer: X402xClientEvmSigner\n  /**\n   * Permit 需要链上读取 nonces(owner)；如果你需要在客户端使用 permitType=permit，\n   * 必须提供一个可 readContract 的公共 client。\n   */\n  publicClient?: X402xPublicEvmClient\n  /**\n   * 默认签名类型（当 PaymentRequirements.extra.permitType 未指定时生效）\n   *\n   * @default \"eip3009\"\n   */\n  defaultPermitType?: PermitType\n}\n\n/**\n * x402x EVM client implementation for x402 \"exact\" scheme.\n *\n * - 支持 EIP-3009（默认）\n * - 支持 EIP-2612 Permit（需要 publicClient 读 nonce）\n */\nexport class ExactX402xEvmClient implements SchemeNetworkClient {\n  readonly scheme = X402X_EVM_SCHEME\n  private readonly defaultPermitType: PermitType\n\n  /**\n   * Creates a new ExactX402xEvmClient instance.\n   *\n   * @param config - The configuration for the client\n   */\n  constructor(private readonly config: ExactX402xEvmClientConfig) {\n    this.defaultPermitType = config.defaultPermitType ?? 'eip3009'\n  }\n\n  /**\n   * Creates a new ExactX402xEvmClient instance.\n   *\n   * @param x402Version - The x402 version\n   * @param paymentRequirements - The payment requirements\n   * @returns The payment payload\n   */\n  async createPaymentPayload(\n    x402Version: number,\n    paymentRequirements: PaymentRequirements,\n  ): Promise<Pick<PaymentPayload, 'x402Version' | 'payload'>> {\n    const permitType =\n      (paymentRequirements.extra?.permitType as PermitType | undefined) ?? this.defaultPermitType\n\n    if (permitType === 'permit') {\n      const payload = await this.createPermitPayload(paymentRequirements)\n      return { x402Version, payload }\n    }\n\n    if (permitType === 'permit2') {\n      throw new Error('permit2 is not implemented in x402x-evm yet')\n    }\n\n    const payload = await this.createEip3009Payload(paymentRequirements)\n    return { x402Version, payload }\n  }\n\n  /**\n   * Creates a new ExactX402xEvmClient instance.\n   *\n   * @param requirements - The payment requirements\n   * @returns The payment payload\n   */\n  private async createEip3009Payload(\n    requirements: PaymentRequirements,\n  ): Promise<ExactX402xEvmPayload> {\n    const nonce = createNonce()\n    const now = Math.floor(Date.now() / 1000)\n\n    const authorization = {\n      from: this.config.signer.address,\n      to: getAddress(requirements.payTo),\n      value: requirements.amount,\n      validAfter: (now - 600).toString(),\n      validBefore: (now + requirements.maxTimeoutSeconds).toString(),\n      nonce,\n    } as const\n\n    const chainId = parseInt(requirements.network.split(':')[1])\n\n    // 如果服务端没提供 name/version，则尽量用 publicClient 读取（否则无法签名）\n    let name = requirements.extra?.name as string | undefined\n    let version = requirements.extra?.version as string | undefined\n    if ((!name || !version) && this.config.publicClient) {\n      const domain = await resolveEip712Domain(\n        this.config.publicClient,\n        getAddress(requirements.asset),\n      )\n      name = name ?? domain.name\n      version = version ?? domain.version\n    }\n    if (!name || !version) {\n      throw new Error(\n        `EIP-712 domain parameters (name, version) are required to sign EIP-3009 for asset ${requirements.asset}`,\n      )\n    }\n\n    const signature = await this.config.signer.signTypedData({\n      domain: {\n        name,\n        version,\n        chainId,\n        verifyingContract: getAddress(requirements.asset),\n      },\n      types: eip3009AuthorizationTypes,\n      primaryType: 'TransferWithAuthorization',\n      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\n    return {\n      authorization,\n      signature,\n    }\n  }\n\n  /**\n   * Creates a new ExactX402xEvmClient instance.\n   *\n   * @param requirements - The payment requirements\n   * @returns The payment payload\n   */\n  private async createPermitPayload(\n    requirements: PaymentRequirements,\n  ): Promise<ExactX402xEvmPayload> {\n    const reader = this.config.publicClient\n    if (!reader) {\n      throw new Error('Permit signing requires publicClient (readContract) to fetch nonces(owner)')\n    }\n\n    const chainId = parseInt(requirements.network.split(':')[1])\n    const token = getAddress(requirements.asset)\n    const owner = getAddress(this.config.signer.address)\n    const spender = getAddress(requirements.payTo)\n    const deadline = Math.floor(Date.now() / 1000 + requirements.maxTimeoutSeconds).toString()\n\n    const nonce = (await reader.readContract({\n      address: token,\n      abi: permitNonceABI,\n      functionName: 'nonces',\n      args: [owner],\n    })) as bigint\n\n    // domain：优先使用服务端写入的 extra.name/version，缺失则链上读取\n    let name = requirements.extra?.name as string | undefined\n    let version = requirements.extra?.version as string | undefined\n    if (!name || !version) {\n      const domain = await resolveEip712Domain(reader, token)\n      name = name ?? domain.name\n      version = version ?? domain.version\n    }\n\n    const signature = await this.config.signer.signTypedData({\n      domain: {\n        name,\n        version,\n        chainId,\n        verifyingContract: token,\n      },\n      types: permitTypes,\n      primaryType: 'Permit',\n      message: {\n        owner,\n        spender,\n        value: BigInt(requirements.amount),\n        nonce,\n        deadline: BigInt(deadline),\n      },\n    })\n\n    return {\n      authorization: {\n        owner,\n        spender,\n        value: requirements.amount,\n        deadline,\n        nonce: nonce.toString(),\n      },\n      signature,\n    }\n  }\n}\n","import { x402Client } from '@x402/core/client'\nimport { Network } from '@x402/core/types'\nimport { X402xClientEvmSigner, X402xPublicEvmClient } from '../../signer'\nimport { PermitType } from '../../types'\nimport { ExactX402xEvmClient } from './scheme'\n\nexport interface X402xEvmClientRegistrationConfig {\n  signer: X402xClientEvmSigner\n  publicClient?: X402xPublicEvmClient\n  /**\n   * 可选：指定注册哪些网络；不填则注册 eip155:*（推荐）\n   */\n  networks?: Network[]\n  /**\n   * 默认签名类型（当 requirements.extra.permitType 未写时）\n   *\n   * @default \"eip3009\"\n   */\n  defaultPermitType?: PermitType\n}\n\n/**\n * 将 x402x 的 EVM exact 机制注册到 @x402/core 的 client。\n *\n * @param client - The x402Client instance to register schemes to\n * @param config - Configuration for EVM client registration\n * @returns The client instance for chaining\n */\nexport function registerExactX402xEvmScheme(\n  client: x402Client,\n  config: X402xEvmClientRegistrationConfig,\n): x402Client {\n  const scheme = new ExactX402xEvmClient({\n    signer: config.signer,\n    publicClient: config.publicClient,\n    defaultPermitType: config.defaultPermitType,\n  })\n\n  if (config.networks && config.networks.length > 0) {\n    config.networks.forEach((n) => client.register(n, scheme))\n  } else {\n    client.register('eip155:*', scheme)\n  }\n\n  return client\n}\n"],"mappings":"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","names":["payload"]}