{"version":3,"sources":["../../src/signer.ts"],"sourcesContent":["/**\n * ClientEvmSigner - Used by x402 clients to sign payment authorizations.\n *\n * Typically a viem WalletClient extended with publicActions:\n * ```typescript\n * const client = createWalletClient({\n * account: privateKeyToAccount('0x...'),\n * chain: baseSepolia,\n * transport: http(),\n * }).extend(publicActions);\n * ```\n *\n * Or composed via `toClientEvmSigner(account, publicClient)`.\n */\nexport type ClientEvmSigner = {\n readonly address: `0x${string}`;\n signTypedData(message: {\n domain: Record;\n types: Record;\n primaryType: string;\n message: Record;\n }): Promise<`0x${string}`>;\n readContract(args: {\n address: `0x${string}`;\n abi: readonly unknown[];\n functionName: string;\n args?: readonly unknown[];\n }): Promise;\n /**\n * Optional: Signs a raw EIP-1559 transaction without broadcasting.\n * Required for ERC-20 approval gas sponsoring when the token lacks EIP-2612.\n */\n signTransaction?(args: {\n to: `0x${string}`;\n data: `0x${string}`;\n nonce: number;\n gas: bigint;\n maxFeePerGas: bigint;\n maxPriorityFeePerGas: bigint;\n chainId: number;\n }): Promise<`0x${string}`>;\n /**\n * Optional: Gets the current transaction count (nonce) for an address.\n * Required for ERC-20 approval gas sponsoring.\n */\n getTransactionCount?(args: { address: `0x${string}` }): Promise;\n /**\n * Optional: Estimates current gas fees per gas.\n * Required for ERC-20 approval gas sponsoring.\n */\n estimateFeesPerGas?(): Promise<{ maxFeePerGas: bigint; maxPriorityFeePerGas: bigint }>;\n};\n\n/**\n * FacilitatorEvmSigner - Used by x402 facilitators to verify and settle payments\n * This is typically a viem PublicClient + WalletClient combination that can\n * read contract state, verify signatures, write transactions, and wait for receipts\n *\n * Supports multiple addresses for load balancing, key rotation, and high availability\n */\nexport type FacilitatorEvmSigner = {\n /**\n * Get all addresses this facilitator can use for signing\n * Enables dynamic address selection for load balancing and key rotation\n */\n getAddresses(): readonly `0x${string}`[];\n\n readContract(args: {\n address: `0x${string}`;\n abi: readonly unknown[];\n functionName: string;\n args?: readonly unknown[];\n }): Promise;\n verifyTypedData(args: {\n address: `0x${string}`;\n domain: Record;\n types: Record;\n primaryType: string;\n message: Record;\n signature: `0x${string}`;\n }): Promise;\n writeContract(args: {\n address: `0x${string}`;\n abi: readonly unknown[];\n functionName: string;\n args: readonly unknown[];\n }): Promise<`0x${string}`>;\n sendTransaction(args: { to: `0x${string}`; data: `0x${string}` }): Promise<`0x${string}`>;\n waitForTransactionReceipt(args: { hash: `0x${string}` }): Promise<{ status: string }>;\n getCode(args: { address: `0x${string}` }): Promise<`0x${string}` | undefined>;\n};\n\n/**\n * Composes a ClientEvmSigner from a local account and a public client.\n *\n * Use this when your signer (e.g., `privateKeyToAccount`) doesn't have\n * `readContract`. The `publicClient` provides the on-chain read capability.\n *\n * Alternatively, use a WalletClient extended with publicActions directly:\n * ```typescript\n * const signer = createWalletClient({\n * account: privateKeyToAccount('0x...'),\n * chain: baseSepolia,\n * transport: http(),\n * }).extend(publicActions);\n * ```\n *\n * @param signer - A signer with `address` and `signTypedData` (and optionally `readContract`)\n * @param publicClient - A client with `readContract` (required if signer lacks it)\n * @param publicClient.readContract - The readContract method from the public client\n * @param publicClient.getTransactionCount - Optional getTransactionCount for ERC-20 approval\n * @param publicClient.estimateFeesPerGas - Optional estimateFeesPerGas for ERC-20 approval\n * @returns A complete ClientEvmSigner\n *\n * @example\n * ```typescript\n * const account = privateKeyToAccount(\"0x...\");\n * const publicClient = createPublicClient({ chain: baseSepolia, transport: http() });\n * const signer = toClientEvmSigner(account, publicClient);\n * ```\n */\nexport function toClientEvmSigner(\n signer: Omit & {\n readContract?: ClientEvmSigner[\"readContract\"];\n },\n publicClient?: {\n readContract(args: {\n address: `0x${string}`;\n abi: readonly unknown[];\n functionName: string;\n args?: readonly unknown[];\n }): Promise;\n getTransactionCount?(args: { address: `0x${string}` }): Promise;\n estimateFeesPerGas?(): Promise<{ maxFeePerGas: bigint; maxPriorityFeePerGas: bigint }>;\n },\n): ClientEvmSigner {\n const readContract = signer.readContract ?? publicClient?.readContract.bind(publicClient);\n\n if (!readContract) {\n throw new Error(\n \"toClientEvmSigner requires either a signer with readContract or a publicClient. \" +\n \"Use createWalletClient(...).extend(publicActions) or pass a publicClient.\",\n );\n }\n\n const result: ClientEvmSigner = {\n address: signer.address,\n signTypedData: msg => signer.signTypedData(msg),\n readContract,\n };\n\n // Forward optional capabilities from signer or publicClient\n const signTransaction = signer.signTransaction;\n if (signTransaction) {\n result.signTransaction = args => signTransaction(args);\n }\n\n const getTransactionCount =\n signer.getTransactionCount ?? publicClient?.getTransactionCount?.bind(publicClient);\n if (getTransactionCount) {\n result.getTransactionCount = args => getTransactionCount(args);\n }\n\n const estimateFeesPerGas =\n signer.estimateFeesPerGas ?? publicClient?.estimateFeesPerGas?.bind(publicClient);\n if (estimateFeesPerGas) {\n result.estimateFeesPerGas = () => estimateFeesPerGas();\n }\n\n return result;\n}\n\n/**\n * Converts a viem client with single address to a FacilitatorEvmSigner\n * Wraps the single address in a getAddresses() function for compatibility\n *\n * @param client - The client to convert (must have 'address' property)\n * @returns FacilitatorEvmSigner with getAddresses() support\n */\nexport function toFacilitatorEvmSigner(\n client: Omit & { address: `0x${string}` },\n): FacilitatorEvmSigner {\n return {\n ...client,\n getAddresses: () => [client.address],\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAyHO,SAAS,kBACd,QAGA,cAUiB;AACjB,QAAM,eAAe,OAAO,gBAAgB,cAAc,aAAa,KAAK,YAAY;AAExF,MAAI,CAAC,cAAc;AACjB,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AAEA,QAAM,SAA0B;AAAA,IAC9B,SAAS,OAAO;AAAA,IAChB,eAAe,SAAO,OAAO,cAAc,GAAG;AAAA,IAC9C;AAAA,EACF;AAGA,QAAM,kBAAkB,OAAO;AAC/B,MAAI,iBAAiB;AACnB,WAAO,kBAAkB,UAAQ,gBAAgB,IAAI;AAAA,EACvD;AAEA,QAAM,sBACJ,OAAO,uBAAuB,cAAc,qBAAqB,KAAK,YAAY;AACpF,MAAI,qBAAqB;AACvB,WAAO,sBAAsB,UAAQ,oBAAoB,IAAI;AAAA,EAC/D;AAEA,QAAM,qBACJ,OAAO,sBAAsB,cAAc,oBAAoB,KAAK,YAAY;AAClF,MAAI,oBAAoB;AACtB,WAAO,qBAAqB,MAAM,mBAAmB;AAAA,EACvD;AAEA,SAAO;AACT;AASO,SAAS,uBACd,QACsB;AACtB,SAAO;AAAA,IACL,GAAG;AAAA,IACH,cAAc,MAAM,CAAC,OAAO,OAAO;AAAA,EACrC;AACF;","names":[]}