@devlab.group/agent-commerce 0.2.0-beta.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +145 -59
- package/dist/{chunk-ASK67X56.js → chunk-64UZVJEO.js} +3 -3
- package/dist/{chunk-ASK67X56.js.map → chunk-64UZVJEO.js.map} +1 -1
- package/dist/{chunk-MQMKQGAB.js → chunk-M4I7I2UY.js} +88 -32
- package/dist/chunk-M4I7I2UY.js.map +1 -0
- package/dist/cli/index.js +279 -48
- package/dist/cli/index.js.map +1 -1
- package/dist/guardrails-Dmwi63KB.d.ts +38 -0
- package/dist/index.d.ts +11 -6
- package/dist/index.js +208 -30
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts +2 -2
- package/dist/mcp.js +1 -1
- package/dist/{protocol-adapter-CtB0sOnV.d.ts → protocol-adapter-DZ8qkkAa.d.ts} +22 -2
- package/dist/{runtime-Bie-9FAM.d.ts → runtime-CC6EFmLP.d.ts} +3 -3
- package/dist/x402.d.ts +20 -6
- package/dist/x402.js +79 -23
- package/dist/x402.js.map +1 -1
- package/package.json +8 -1
- package/dist/chunk-MQMKQGAB.js.map +0 -1
- package/dist/guardrails-Di_yI_DW.d.ts +0 -25
package/dist/x402.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/payments/x402/chain.ts","../src/payments/x402/client.ts","../src/payments/x402/amount.ts","../src/payments/x402/facilitator.ts","../src/payments/x402/payload.ts","../src/payments/x402/replay-key.ts","../src/payments/x402/provider.ts"],"names":["privateKeyToAccount","X402_VERSION","getAddress"],"mappings":"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","file":"x402.js","sourcesContent":["/**\n * Local deterministic chain wiring.\n *\n * The x402 SDK resolves RPC endpoints for public networks from its own\n * tables — exactly what we must never touch: the tests must stay\n * deterministic. Instead we build plain viem clients pointed at\n * `options.rpcUrl`, using a custom `Chain` object whose id is 84532, the\n * chain id carried by the CAIP-2 network identifier the gateway advertises\n * (`eip155:84532`).\n *\n * The `Local` prefix on everything here describes the *chain* these clients\n * are built for, not a test-only status: `provider.ts` calls\n * `createLocalPublicClient` and `createLocalFacilitatorClient` on the real\n * settlement path, for every payment. This is not demo scaffolding that a\n * production build could drop — v0.1 settles against the deterministic local\n * chain, so this file *is* the settlement transport. Supporting a public\n * network means making `buildLocalChain`'s hardcoded `LOCAL_CHAIN_ID` a\n * parameter, not bypassing this module.\n *\n * `dev-key-guard.ts` is the boundary that keeps that arrangement safe: it\n * refuses at provider construction if a dev key or dev `payTo` is pointed at\n * anything other than a loopback/private RPC.\n */\nimport {\n type Account,\n type Chain,\n type Client,\n createPublicClient,\n createWalletClient,\n http,\n type PublicActions,\n type PublicClient,\n publicActions,\n type Transport,\n type WalletActions,\n} from 'viem';\nimport { privateKeyToAccount } from 'viem/accounts';\n\n/** A wallet client that can also read chain state — matches x402's `SignerWallet`. */\nexport type LocalFacilitatorClient = Client<\n Transport,\n Chain,\n Account,\n undefined,\n PublicActions<Transport, Chain, Account> & WalletActions<Chain, Account>\n>;\n\n/**\n * Chain id of the local deterministic dev chain. Shared with the public Base\n * Sepolia testnet, which is why nothing may infer \"this is a public network\"\n * from the id alone — `provider.ts` probes for a real Anvil node instead.\n */\nexport const LOCAL_CHAIN_ID = 84532;\n\n/** CAIP-2 identifier the local dev chain is advertised under. */\nexport const LOCAL_NETWORK = `eip155:${LOCAL_CHAIN_ID}`;\n\n/**\n * Chain id carried by a CAIP-2 `eip155` network identifier.\n *\n * x402 v2 identifies networks as CAIP-2 strings rather than the v1 name table,\n * so the chain id a signature is bound to is read straight off the wire value\n * instead of looked up. Returns `undefined` for anything that is not an\n * `eip155` identifier — a caller must never fall back to a default chain id,\n * because the chain id is part of the EIP-712 domain a buyer signed.\n */\nexport function chainIdFromCaip2(network: string): number | undefined {\n const match = /^eip155:(\\d+)$/.exec(network);\n if (!match?.[1]) return undefined;\n const chainId = Number(match[1]);\n return Number.isSafeInteger(chainId) && chainId > 0 ? chainId : undefined;\n}\n\nexport function buildLocalChain(rpcUrl: string): Chain {\n return {\n id: LOCAL_CHAIN_ID,\n name: 'agent-commerce-local',\n nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },\n rpcUrls: {\n default: { http: [rpcUrl] },\n },\n } satisfies Chain;\n}\n\n/**\n * A viem `PublicClient` for the local chain — read-only, no signing capability.\n *\n * `timeoutMs`, when given, is passed straight to viem's `http()` transport,\n * which ties it to a real `AbortController` around the underlying `fetch`\n * (see viem's `utils/promise/withTimeout.js` — `signal: true`). That is a\n * genuine cancellation, unlike a bare `Promise.race` against a timer, which\n * only stops *waiting* for the request while the request itself keeps\n * running server-side. Omit it to keep viem's own default (10s).\n */\nexport function createLocalPublicClient(rpcUrl: string, timeoutMs?: number): PublicClient {\n return createPublicClient({\n chain: buildLocalChain(rpcUrl),\n transport: http(rpcUrl, timeoutMs !== undefined ? { timeout: timeoutMs } : undefined),\n });\n}\n\n/**\n * A viem `WalletClient` extended with public actions, for the local\n * facilitator signer only. x402's `settle()` calls `writeContract`,\n * `waitForTransactionReceipt` and `getCode` on this client — i.e. it needs\n * both `WalletActions` and `PublicActions`, matching x402's `SignerWallet`\n * type.\n *\n * LOCAL DEVELOPMENT ONLY — the private key behind this client must always be\n * an Anvil well-known development key, never a merchant or buyer key, and\n * never a production key of any kind.\n */\nexport function createLocalFacilitatorClient(\n rpcUrl: string,\n signerPrivateKey: `0x${string}`,\n): LocalFacilitatorClient {\n const chain = buildLocalChain(rpcUrl);\n const account = privateKeyToAccount(signerPrivateKey);\n return createWalletClient({\n account,\n chain,\n transport: http(rpcUrl),\n }).extend(publicActions);\n}\n","/**\n * CLIENT-SIDE payment helper.\n *\n * This module is used by the demo buyer agent (`demo/agent`) and by the\n * payment E2E test suite to build and EIP-712-sign an x402 v2 `exact`/EVM\n * payment authorisation, entirely on the buyer's side.\n *\n * The gateway NEVER calls this module and NEVER holds a buyer private key.\n * `buyerPrivateKey` here is always an Anvil well-known\n * development key (LOCAL DEVELOPMENT ONLY — DO NOT FUND) supplied by whoever\n * is driving the demo/test, not something the provider or gateway manages.\n *\n * It signs the EIP-712 authorisation directly rather than going through the\n * SDK's `x402Client`, for one reason: `overrides`. The negative payment tests\n * need authorisations that are deliberately wrong — wrong recipient, short\n * amount, reused nonce, expired window — and a conforming client will not\n * produce those. Interop with a real SDK client is proved separately, by a\n * test that pays the gateway using `x402Client` itself.\n */\n\nimport { PaymentRequirementsV2Schema } from '@x402/core/schemas';\nimport type { PaymentPayload, PaymentRequirements } from '@x402/core/types';\nimport { getAddress, toHex } from 'viem';\nimport { privateKeyToAccount } from 'viem/accounts';\nimport { chainIdFromCaip2 } from './chain.js';\n\nexport interface CreatePaymentProofOptions {\n /** Buyer's dev-only private key. LOCAL DEVELOPMENT ONLY — DO NOT FUND. */\n readonly buyerPrivateKey: `0x${string}`;\n readonly rpcUrl: string;\n /** One entry from PaymentRequiredEnvelope.payment.accepts, verbatim. */\n readonly accepts: Readonly<Record<string, unknown>>;\n /** Overrides used only by negative tests (wrong amount/recipient/nonce…). */\n readonly overrides?: {\n readonly value?: string;\n readonly payTo?: string;\n readonly nonce?: `0x${string}`;\n readonly validBefore?: number;\n readonly validAfter?: number;\n };\n}\n\nconst X402_VERSION = 2;\n\nconst TRANSFER_WITH_AUTHORIZATION_TYPES = {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n} as const;\n\n/** Returns the base64 `PAYMENT-SIGNATURE` value to send back to the gateway. */\nexport async function createPaymentProof(options: CreatePaymentProofOptions): Promise<string> {\n const requirements = PaymentRequirementsV2Schema.parse(options.accepts);\n if (\n !requirements.extra ||\n typeof requirements.extra['name'] !== 'string' ||\n typeof requirements.extra['version'] !== 'string'\n ) {\n throw new Error(\n 'createPaymentProof: payment requirement is missing extra.name/extra.version — cannot build the EIP-712 domain',\n );\n }\n\n const chainId = chainIdFromCaip2(requirements.network);\n if (chainId === undefined) {\n throw new Error(\n `createPaymentProof: network \"${requirements.network}\" is not a CAIP-2 eip155 identifier — cannot determine the chain id to sign against`,\n );\n }\n\n const account = privateKeyToAccount(options.buyerPrivateKey);\n // `rpcUrl` is part of the frozen `CreatePaymentProofOptions` shape for\n // interface parity with other providers, but the `exact`/EVM scheme signs\n // fully offline: the chain id comes from the CAIP-2 network identifier\n // (matching what the facilitator's verify()/settle() compute), and the\n // nonce is a fresh random value, not one read from chain state.\n void options.rpcUrl;\n\n const nonce = options.overrides?.nonce ?? randomNonce();\n const nowSeconds = Math.floor(Date.now() / 1000);\n // 0, matching the SDK's own v2 client: `validAfter` exists to delay an\n // authorisation, and nothing here wants one delayed. A backdated value would\n // only paper over clock skew that `validBefore` has to tolerate anyway.\n const validAfter = options.overrides?.validAfter ?? 0;\n const validBefore = options.overrides?.validBefore ?? nowSeconds + requirements.maxTimeoutSeconds;\n const to = getAddress((options.overrides?.payTo ?? requirements.payTo) as `0x${string}`);\n const value = BigInt(options.overrides?.value ?? requirements.amount);\n\n const signature = await account.signTypedData({\n domain: {\n name: requirements.extra['name'],\n version: requirements.extra['version'],\n chainId,\n verifyingContract: getAddress(requirements.asset as `0x${string}`),\n },\n types: TRANSFER_WITH_AUTHORIZATION_TYPES,\n primaryType: 'TransferWithAuthorization',\n message: {\n from: account.address,\n to,\n value,\n validAfter: BigInt(validAfter),\n validBefore: BigInt(validBefore),\n nonce,\n },\n });\n\n // v2 carries the selected requirement back to the server as `accepted`\n // rather than repeating scheme/network at the top level. The server treats\n // that echo as untrusted and verifies against its own copy; it is on the\n // wire so a stateless facilitator knows which offer was taken.\n const payload: PaymentPayload = {\n x402Version: X402_VERSION,\n accepted: requirements as PaymentRequirements,\n payload: {\n signature,\n authorization: {\n from: account.address,\n to,\n value: value.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n },\n },\n };\n\n return Buffer.from(JSON.stringify(payload), 'utf8').toString('base64');\n}\n\nfunction randomNonce(): `0x${string}` {\n const bytes = new Uint8Array(32);\n crypto.getRandomValues(bytes);\n return toHex(bytes);\n}\n","/**\n * Deterministic decimal <-> base-unit conversion.\n *\n * `DecimalAmount` (see src/core) is a decimal string in\n * *display* units (\"0.01\" USDC). x402 / EIP-3009 need base units (integer\n * string, e.g. \"10000\" for 0.01 USDC at 6 decimals). This conversion must\n * never go through a JS `number` — floating point cannot represent most\n * decimal fractions exactly, and a silently-rounded payment amount is a\n * security bug in a payment provider.\n *\n * viem's own `parseUnits` rounds silently when given more fractional digits\n * than `decimals` supports; we need a hard error instead (a merchant asking\n * for \"0.0000001\" against a 6-decimal asset is a configuration bug, not a\n * roundable amount), so this module implements its own strict parser.\n */\nimport { CommerceError } from '../../core/index.js';\n\nconst DECIMAL_STRING_PATTERN = /^\\d+(?:\\.\\d+)?$/;\n\n/**\n * Parses a canonical decimal display amount (e.g. \"0.01\") into base units\n * for an asset with the given number of decimals, without floating point.\n *\n * Throws `CommerceError('PAYMENT_INVALID')` if the string is not a plain\n * non-negative decimal, or if it carries more fractional digits than the\n * asset supports.\n */\nexport function parseCanonicalAmount(amount: string, decimals: number): bigint {\n if (!Number.isInteger(decimals) || decimals < 0) {\n throw new CommerceError('INTERNAL_ERROR', `Invalid asset decimals: ${decimals}`);\n }\n if (!DECIMAL_STRING_PATTERN.test(amount)) {\n throw new CommerceError(\n 'PAYMENT_INVALID',\n `Amount \"${amount}\" is not a valid non-negative decimal string`,\n {\n details: { amount },\n },\n );\n }\n\n const [integerPart = '0', fractionPart = ''] = amount.split('.');\n\n if (fractionPart.length > decimals) {\n throw new CommerceError(\n 'PAYMENT_INVALID',\n `Amount \"${amount}\" has more precision than the asset supports (${decimals} decimals)`,\n { details: { amount, assetDecimals: decimals } },\n );\n }\n\n const paddedFraction = fractionPart.padEnd(decimals, '0');\n const combined = `${integerPart}${paddedFraction}`;\n // Strip leading zeros so BigInt doesn't choke on e.g. \"007\" — BigInt() is\n // fine with leading zeros in decimal strings, but normalise defensively.\n return BigInt(combined);\n}\n\n/**\n * Formats base units back into a canonical decimal display string.\n *\n * Exact (no rounding is possible going from integer base units to a wider\n * decimal representation), so this is safe to implement directly.\n */\nexport function formatCanonicalAmount(baseUnits: bigint, decimals: number): string {\n if (!Number.isInteger(decimals) || decimals < 0) {\n throw new CommerceError('INTERNAL_ERROR', `Invalid asset decimals: ${decimals}`);\n }\n const negative = baseUnits < 0n;\n const abs = negative ? -baseUnits : baseUnits;\n const digits = abs.toString().padStart(decimals + 1, '0');\n const integerPart = digits.slice(0, digits.length - decimals) || '0';\n const fractionPart = digits.slice(digits.length - decimals).replace(/0+$/, '');\n const sign = negative ? '-' : '';\n return fractionPart.length > 0\n ? `${sign}${integerPart}.${fractionPart}`\n : `${sign}${integerPart}`;\n}\n","/**\n * The facilitator seam.\n *\n * A facilitator is whatever verifies an authorisation and broadcasts the\n * transfer. This gateway supports two, behind one interface:\n *\n * local the SDK's in-process `x402Facilitator` signing against a dev node\n * remote an HTTP facilitator, with or without a credential\n *\n * Both are the SDK's own `FacilitatorClient` contract underneath, so neither\n * is a bespoke reimplementation of the protocol — the local one is the same\n * code a hosted facilitator runs, pointed at the local chain.\n *\n * A *session* is opened per verify/settle call rather than reused, because\n * `transportFailed()` has to be scoped to one request: two concurrent\n * payments must not see each other's transport failures. The cost is an\n * object literal against an RPC or HTTP round-trip.\n */\nimport { x402Facilitator } from '@x402/core/facilitator';\nimport { FacilitatorResponseError, HTTPFacilitatorClient } from '@x402/core/http';\nimport type {\n Network,\n PaymentPayload,\n PaymentRequirements,\n SettleResponse,\n VerifyResponse,\n} from '@x402/core/types';\nimport { toFacilitatorEvmSigner } from '@x402/evm';\nimport { registerExactEvmScheme } from '@x402/evm/exact/facilitator';\nimport type { LocalFacilitatorClient } from './chain.js';\nimport type { FacilitatorAuth } from './guardrails.js';\n\n/** One verify or one settle, with its own transport-failure flag. */\nexport interface FacilitatorSession {\n verify(payload: PaymentPayload, requirements: PaymentRequirements): Promise<VerifyResponse>;\n settle(payload: PaymentPayload, requirements: PaymentRequirements): Promise<SettleResponse>;\n /**\n * True when the call failed to reach the facilitator (or the chain behind\n * it) rather than producing a verdict.\n *\n * The SDK's `exact`/EVM scheme catches its own RPC errors and reports them\n * as an ordinary verification failure — an unreachable node comes back as\n * `invalid_exact_evm_signature`. Fail-closed still holds, but the buyer is\n * told their signature is bad and the attempt is recorded as their fault,\n * when nothing about their payment was ever checked. This flag is how the\n * provider tells \"we looked and it was wrong\" apart from \"we could not\n * look\".\n */\n transportFailed(): boolean;\n}\n\nexport interface SupportedKind {\n readonly x402Version: number;\n readonly scheme: string;\n readonly network: string;\n}\n\nexport interface FacilitatorBinding {\n readonly kind: 'local' | 'remote';\n /** Human-readable, never a credential. */\n readonly describe: string;\n open(): FacilitatorSession;\n /** What the facilitator says it can settle. Used by health(), not by the payment path. */\n supported(): Promise<readonly SupportedKind[]>;\n}\n\n/** Bounds every receipt wait the in-process facilitator performs. */\nexport const SETTLEMENT_CONFIRMATION_TIMEOUT_MS = 60_000;\n\n/**\n * An in-process `x402Facilitator` with the `exact`/EVM scheme registered\n * against exactly one network.\n *\n * One network, not the `eip155:*` wildcard the SDK would otherwise derive: a\n * payload naming some other chain must find no facilitator at all rather than\n * reaching a scheme that would then have to reject it.\n */\nexport function createLocalFacilitatorBinding(\n client: LocalFacilitatorClient,\n network: string,\n isTransportError: (err: unknown) => boolean,\n): FacilitatorBinding {\n const build = (): { facilitator: x402Facilitator; failed: () => boolean } => {\n let failed = false;\n const watch = <T>(promise: Promise<T>): Promise<T> =>\n promise.catch((err: unknown) => {\n if (isTransportError(err)) failed = true;\n throw err;\n });\n\n // Exactly the `FacilitatorEvmSigner` surface, so the wrapper covers every\n // call the SDK can make. `toFacilitatorEvmSigner` wants a flat `address`,\n // which viem carries on `client.account` instead.\n const signer = {\n address: client.account.address,\n readContract: (args: Parameters<LocalFacilitatorClient['readContract']>[0]) =>\n watch(client.readContract(args)),\n verifyTypedData: (args: Parameters<LocalFacilitatorClient['verifyTypedData']>[0]) =>\n watch(client.verifyTypedData(args)),\n writeContract: (args: Parameters<LocalFacilitatorClient['writeContract']>[0]) =>\n watch(client.writeContract(args)),\n sendTransaction: (args: Parameters<LocalFacilitatorClient['sendTransaction']>[0]) =>\n watch(client.sendTransaction(args)),\n waitForTransactionReceipt: (\n args: Parameters<LocalFacilitatorClient['waitForTransactionReceipt']>[0],\n ) => watch(client.waitForTransactionReceipt(args)),\n getCode: (args: Parameters<LocalFacilitatorClient['getCode']>[0]) =>\n watch(client.getCode(args)),\n } as unknown as Parameters<typeof toFacilitatorEvmSigner>[0];\n\n // `confirmationTimeoutMs` is what turns a lost receipt wait into\n // `settlement_pending` + the broadcast hash instead of a discarded broadcast.\n const facilitator = registerExactEvmScheme(new x402Facilitator(), {\n signer: toFacilitatorEvmSigner(signer, {\n confirmationTimeoutMs: SETTLEMENT_CONFIRMATION_TIMEOUT_MS,\n }),\n networks: network as Network,\n });\n\n return { facilitator, failed: () => failed };\n };\n\n return {\n kind: 'local',\n describe: 'local (in-process)',\n open(): FacilitatorSession {\n const { facilitator, failed } = build();\n return {\n verify: (payload, requirements) => facilitator.verify(payload, requirements),\n settle: (payload, requirements) => facilitator.settle(payload, requirements),\n transportFailed: failed,\n };\n },\n async supported(): Promise<readonly SupportedKind[]> {\n return build().facilitator.getSupported().kinds;\n },\n };\n}\n\nexport interface RemoteFacilitatorOptions {\n readonly url: string;\n readonly auth: FacilitatorAuth;\n readonly timeoutMs?: number;\n}\n\n/**\n * An HTTP facilitator.\n *\n * Auth headers are produced per request by the SDK client and never logged,\n * never echoed into `/.well-known`, and never included in `describe`.\n */\nexport function createRemoteFacilitatorBinding(\n options: RemoteFacilitatorOptions,\n isTransportError: (err: unknown) => boolean,\n): FacilitatorBinding {\n const auth = options.auth;\n const createAuthHeaders =\n auth.type === 'bearer'\n ? async (): Promise<Record<string, Record<string, string>>> => {\n // The SDK requires a path-keyed object; a flat headers object throws\n // rather than silently dropping auth on every request.\n const headers = { Authorization: `Bearer ${auth.token}` };\n return { verify: headers, settle: headers, supported: headers };\n }\n : undefined;\n\n const client = new HTTPFacilitatorClient({\n url: options.url,\n timeoutMs: options.timeoutMs ?? SETTLEMENT_CONFIRMATION_TIMEOUT_MS,\n ...(createAuthHeaders ? { createAuthHeaders } : {}),\n });\n\n return {\n kind: 'remote',\n describe: `remote ${new URL(options.url).origin} (auth=${auth.type})`,\n open(): FacilitatorSession {\n let failed = false;\n const watch = async <T>(call: () => Promise<T>): Promise<T> => {\n try {\n return await call();\n } catch (err) {\n // A facilitator that timed out or answered with something\n // unparseable produced no verdict. Treating either as a payment\n // failure would blame the buyer for the facilitator being down —\n // and for settle(), a timeout is explicitly indeterminate: the\n // transfer may have gone through after we stopped waiting.\n if (err instanceof FacilitatorResponseError || isTransportError(err)) failed = true;\n throw err;\n }\n };\n return {\n verify: (payload, requirements) => watch(() => client.verify(payload, requirements)),\n settle: (payload, requirements) => watch(() => client.settle(payload, requirements)),\n transportFailed: () => failed,\n };\n },\n async supported(): Promise<readonly SupportedKind[]> {\n const response = await client.getSupported();\n return response.kinds as readonly SupportedKind[];\n },\n };\n}\n","/**\n * Decoding and validation for the base64 `PAYMENT-SIGNATURE` submission.\n *\n * A malformed payload (not base64, valid base64 but not JSON, valid JSON but\n * the wrong shape) must yield a `rejected` verification result, never a\n * thrown/crashed request — this module returns `undefined` on any failure so\n * callers can turn that into a typed rejection. That is why it parses the\n * schema itself rather than calling the SDK's `decodePaymentSignatureHeader`,\n * which throws.\n */\nimport { PaymentPayloadV2Schema } from '@x402/core/schemas';\nimport type { PaymentPayload } from '@x402/core/types';\nimport { type ExactEIP3009Payload, isEIP3009Payload } from '@x402/evm';\n\nexport function decodePaymentSubmission(payloadBase64: string): PaymentPayload | undefined {\n let json: unknown;\n try {\n const decoded = Buffer.from(payloadBase64, 'base64').toString('utf8');\n json = JSON.parse(decoded);\n } catch {\n return undefined;\n }\n\n const result = PaymentPayloadV2Schema.safeParse(json);\n return result.success ? (result.data as PaymentPayload) : undefined;\n}\n\n/**\n * Narrows a decoded payload to the EIP-3009 `exact`/EVM shape this provider\n * settles.\n *\n * x402 v2's `exact` scheme on EVM has two asset-transfer methods — EIP-3009\n * `transferWithAuthorization` and Permit2. Only the first is supported here,\n * and the challenge says so (`extra.assetTransferMethod`), so a Permit2\n * payload arriving anyway is rejected rather than handed to the SDK: the\n * Permit2 proxy is not deployed on the local chain and a failure there would\n * surface as an opaque settlement revert instead of a clear rejection.\n */\nexport function isExactEvmPayload(\n payload: PaymentPayload,\n): payload is PaymentPayload & { payload: ExactEIP3009Payload } {\n return (\n payload.accepted.scheme === 'exact' &&\n typeof payload.payload === 'object' &&\n payload.payload !== null &&\n isEIP3009Payload(payload.payload as ExactEIP3009Payload) &&\n typeof (payload.payload as ExactEIP3009Payload).signature === 'string'\n );\n}\n","/**\n * Replay-key derivation.\n *\n *Per docs/contracts.md, `PaymentResult.replayKey` MUST be\n * derived only from the payment authorisation (chain id, asset, payer,\n * nonce) — never from the request id — so that the same authorisation\n * replayed against a *different* request still collides in the gateway's\n * receipt-store reservation.\n */\nimport { encodeAbiParameters, keccak256 } from 'viem';\n\nexport interface ReplayKeyInput {\n readonly chainId: number;\n readonly asset: `0x${string}`;\n readonly from: `0x${string}`;\n readonly nonce: `0x${string}`;\n}\n\nexport function computeReplayKey(input: ReplayKeyInput): string {\n const encoded = encodeAbiParameters(\n [{ type: 'uint256' }, { type: 'address' }, { type: 'address' }, { type: 'bytes32' }],\n [BigInt(input.chainId), input.asset, input.from, input.nonce],\n );\n return keccak256(encoded);\n}\n","/**\n * x402 payment provider — protocol version 2, `exact` scheme, EVM,\n * EIP-3009 `transferWithAuthorization`.\n *\n * Implements the frozen `PaymentProvider` interface (src/core/domain/payment.ts).\n * `verify()` never moves funds; only `settle()` does, and only after a\n * successful `verify()` (enforced by the gateway's execution pipeline, not by\n * this file, but this file never calls settle-like RPCs from verify()).\n *\n * Verification and settlement run through the SDK's own `x402Facilitator`\n * with the `exact`/EVM scheme registered against a single CAIP-2 network. The\n * facilitator is in-process — it is the same code a hosted facilitator runs,\n * pointed at the local dev chain — so there is no network hop and no third\n * party in the settlement path.\n *\n * The SDK behaviour relied on here is verified, not assumed: see the notes\n * beside each call site below.\n */\n\nimport type {\n Network,\n PaymentRequired,\n PaymentRequirements,\n SettleResponse,\n VerifyResponse,\n} from '@x402/core/types';\nimport {\n ContractFunctionExecutionError,\n ContractFunctionRevertedError,\n getAddress,\n HttpRequestError,\n isAddress,\n TimeoutError,\n WaitForTransactionReceiptTimeoutError,\n} from 'viem';\nimport {\n type AdapterDescriptor,\n type AdapterHealth,\n type Clock,\n CommerceError,\n type IdGenerator,\n type Logger,\n NOOP_LOGGER,\n type PaymentContext,\n type PaymentProvider,\n type PaymentRequirement,\n type PaymentResult,\n type PaymentSettlementContext,\n type PaymentVerificationContext,\n systemClock,\n} from '../../core/index.js';\nimport { PACKAGE_VERSION } from '../../version.js';\nimport { formatCanonicalAmount, parseCanonicalAmount } from './amount.js';\nimport {\n chainIdFromCaip2,\n createLocalFacilitatorClient,\n createLocalPublicClient,\n type LocalFacilitatorClient,\n} from './chain.js';\nimport { assertDevKeyIsLocalOnly, assertPayToIsNotDevAddress } from './dev-key-guard.js';\nimport {\n createLocalFacilitatorBinding,\n createRemoteFacilitatorBinding,\n type FacilitatorBinding,\n} from './facilitator.js';\nimport { resolveX402Deployment, type X402FacilitatorConfig } from './guardrails.js';\nimport { describeDeploymentMode } from './networks.js';\nimport { decodePaymentSubmission, isExactEvmPayload } from './payload.js';\nimport { computeReplayKey } from './replay-key.js';\n\nconst X402_VERSION = 2;\nconst X402_PROTOCOL_VERSION = String(X402_VERSION);\nconst DEFAULT_MAX_TIMEOUT_SECONDS = 60;\nconst DEFAULT_MIME_TYPE = 'application/json';\nconst HEALTH_TIMEOUT_MS = 4_000;\n/** `SettleResponse.errorReason` the SDK uses for \"broadcast, not confirmed\". */\nconst SETTLEMENT_PENDING_REASON = 'settlement_pending';\n\nexport interface X402ProviderOptions {\n /**\n * CAIP-2 network identifier, e.g. `eip155:84532`. The chain id it carries is\n * part of the EIP-712 domain the buyer signs, so it is read from this value\n * rather than defaulted.\n */\n readonly network: string;\n /** RPC endpoint. Local chain: http://127.0.0.1:8545 */\n readonly rpcUrl: string;\n /** ERC-20 (EIP-3009) asset address used for settlement. */\n readonly asset: `0x${string}`;\n /** EIP-712 domain name of the asset, e.g. 'MockUSDC'. */\n readonly assetName: string;\n /** EIP-712 domain version of the asset, e.g. '2'. */\n readonly assetVersion: string;\n readonly assetDecimals: number;\n /** Merchant-controlled settlement destination. Never a gateway-owned wallet. */\n readonly payTo: `0x${string}`;\n readonly maxTimeoutSeconds?: number;\n /**\n * Which facilitator verifies and broadcasts.\n *\n * `local` runs the facilitator in this process against the dev chain, and\n * its `signerPrivateKey` must be an Anvil well-known key — LOCAL DEVELOPMENT\n * ONLY — DO NOT FUND. `remote` calls an HTTP facilitator, and this gateway\n * then holds no signing key at all.\n */\n readonly facilitator: X402FacilitatorConfig;\n /**\n * Required to be `true` before anything settles on a mainnet. Never a\n * default — see `guardrails.ts`.\n */\n readonly allowMainnet?: boolean;\n readonly logger?: Logger;\n readonly clock?: Clock;\n readonly ids?: IdGenerator;\n}\n\nconst DEFAULT_IDS: IdGenerator = {\n next: (prefix?: string) => `${prefix ? `${prefix}_` : ''}${crypto.randomUUID()}`,\n};\n\nexport function createX402PaymentProvider(options: X402ProviderOptions): PaymentProvider {\n if (!isAddress(options.asset)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `x402 provider: \"asset\" is not a valid EVM address: ${options.asset}`,\n );\n }\n if (!isAddress(options.payTo)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `x402 provider: \"payTo\" is not a valid EVM address: ${options.payTo}`,\n );\n }\n // Applies regardless of facilitator.mode — which account signs settlement\n // has no bearing on whether the destination address's private key is\n // public knowledge. `resolveX402Deployment` below covers the other half of\n // the same question: a dev payTo on any non-local *deployment*, where the\n // RPC host says nothing about where the money lands.\n assertPayToIsNotDevAddress(options.rpcUrl, options.payTo);\n if (!Number.isInteger(options.assetDecimals) || options.assetDecimals < 0) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `x402 provider: \"assetDecimals\" must be a non-negative integer`,\n );\n }\n // The chain id is not a display detail: it is signed into the buyer's\n // EIP-712 domain, so a network identifier we cannot resolve one from is a\n // startup failure, never a request-time default. `resolveX402Deployment`\n // also decides what this deployment *is* — local, testnet or mainnet — and\n // refuses every combination that could move real money by accident.\n const { profile, mode } = resolveX402Deployment({\n network: options.network,\n payTo: options.payTo,\n asset: options.asset,\n facilitator: options.facilitator,\n ...(options.allowMainnet !== undefined ? { allowMainnet: options.allowMainnet } : {}),\n });\n const network = options.network as Network;\n // Constructed once, here, rather than inside settle(): assertDevKeyIsLocalOnly\n // above already proves the key is well-formed, so privateKeyToAccount is not\n // expected to throw — but if it somehow does (or the key/RPC combination is\n // otherwise unusable), that is a *configuration* problem, and a bad key\n // should fail the provider at startup, not on the first paying customer's\n // request, after their replayKey is already reserved. This mirrors the other\n // CONFIG_INVALID checks above, which are all one-time, construction-time\n // validation rather than per-request checks.\n let binding: FacilitatorBinding;\n if (options.facilitator.mode === 'local') {\n assertDevKeyIsLocalOnly(options.rpcUrl, options.facilitator.signerPrivateKey);\n let client: LocalFacilitatorClient;\n try {\n client = createLocalFacilitatorClient(\n options.rpcUrl,\n options.facilitator.signerPrivateKey as `0x${string}`,\n );\n } catch (cause) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n 'x402 provider: could not construct a local facilitator signer from ' +\n 'facilitator.signerPrivateKey — it must be a valid 32-byte hex private key',\n { cause },\n );\n }\n binding = createLocalFacilitatorBinding(client, network, isProviderUnavailableError);\n } else {\n binding = createRemoteFacilitatorBinding(\n { url: options.facilitator.url, auth: options.facilitator.auth },\n isProviderUnavailableError,\n );\n }\n\n // health()'s own read-only client, with a real transport-level timeout (see\n // createLocalPublicClient's doc comment). Verification and settlement read\n // the chain through the facilitator signer instead, so this is the only\n // public client the provider builds.\n const healthPublicClient = createLocalPublicClient(options.rpcUrl, HEALTH_TIMEOUT_MS);\n\n const clock = options.clock ?? systemClock;\n const ids = options.ids ?? DEFAULT_IDS;\n const logger = options.logger ?? NOOP_LOGGER;\n const maxTimeoutSeconds = options.maxTimeoutSeconds ?? DEFAULT_MAX_TIMEOUT_SECONDS;\n\n const descriptor: AdapterDescriptor = {\n name: 'x402',\n kind: 'payment',\n implementationVersion: PACKAGE_VERSION,\n supportedSpec: `x402/v${X402_VERSION} scheme=exact family=eip155`,\n capabilities: [\n 'exact-evm',\n `${binding.kind}-facilitator`,\n 'eip-3009',\n 'caip-2',\n `mode=${mode}`,\n ],\n status: 'stable',\n unsupported: [\n 'svm',\n 'permit2',\n 'upto scheme',\n 'per-request signed facilitator credentials (e.g. CDP JWT)',\n ],\n };\n\n async function createRequirement(context: PaymentContext): Promise<PaymentRequirement> {\n const amount = parseCanonicalAmount(context.amount, options.assetDecimals).toString();\n\n const requirements: PaymentRequirements = {\n scheme: 'exact',\n network,\n asset: options.asset,\n amount,\n payTo: options.payTo,\n maxTimeoutSeconds,\n // `name`/`version` are what let a buyer and the facilitator build the\n // same EIP-712 domain without an on-chain `version()` call, so\n // verification stays deterministic against a token that has none.\n //\n // `assetTransferMethod` is stated rather than left to default: x402 v2's\n // `exact`/EVM scheme also has a Permit2 path, and a client that picked it\n // would produce a payload this provider cannot settle. Declaring the one\n // supported method turns that into a client-side non-choice instead of a\n // server-side rejection.\n extra: {\n name: options.assetName,\n version: options.assetVersion,\n assetTransferMethod: 'eip3009',\n },\n };\n\n // The v2 challenge document, verbatim on the wire: the HTTP adapter\n // base64-encodes this into `PAYMENT-REQUIRED`, and MCP passes it through\n // in the payment-required envelope. Built once, here, so both surfaces\n // describe the same challenge rather than each assembling their own.\n //\n // `resource.url` is descriptive metadata: nothing in the EIP-3009\n // authorisation (`from`/`to`/`value`/`validAfter`/`validBefore`/`nonce`)\n // covers it, nothing verifies against it, and the replay key is keyed on\n // the authorisation instead. It still carries `network` and `payTo` —\n // both already public in this same challenge — because the\n // `agent-commerce` authority is not reserved to us across the wider x402\n // ecosystem, so the pair is what keeps it unambiguous.\n const envelope: PaymentRequired = {\n x402Version: X402_VERSION,\n resource: {\n url: `resource://agent-commerce/${encodeURIComponent(options.network)}/${options.payTo}/resources/${encodeURIComponent(context.resource.id)}`,\n description: context.resource.description ?? context.resource.name,\n mimeType: DEFAULT_MIME_TYPE,\n },\n accepts: [requirements],\n };\n\n const expiresAt = new Date(clock.now().getTime() + maxTimeoutSeconds * 1000).toISOString();\n\n return {\n id: ids.next('payreq'),\n requestId: context.requestId,\n resourceId: context.resource.id,\n provider: 'x402',\n amount: context.amount,\n currency: context.currency,\n destination: options.payTo,\n network: options.network,\n asset: options.asset,\n expiresAt,\n challenge: {\n provider: 'x402',\n version: X402_PROTOCOL_VERSION,\n accepts: [requirements as unknown as Record<string, unknown>],\n envelope: envelope as unknown as Record<string, unknown>,\n },\n };\n }\n\n /**\n * Verifies a payment submission against a payment requirement.\n *\n * Every check below runs against *our* requirement — the one this provider\n * built and the pipeline held onto — never against `payload.accepted`, the\n * copy of the requirements the client echoes back. That echo is attacker\n * data; the SDK's scheme facilitator likewise takes the requirements as an\n * explicit argument rather than reading them off the payload.\n *\n * Deliberately accepts overpayment: only `authorizedValue < required` is\n * rejected (`wrong_amount`), never `authorizedValue > required`. This\n * matches x402's own semantics — the requirement's `amount` names a floor,\n * not an exact amount — and the settled `PaymentResult.amount` always\n * records the actual authorised value, so bookkeeping stays truthful to what\n * really moved rather than silently topping up or rejecting a generous\n * buyer.\n */\n async function verify(context: PaymentVerificationContext): Promise<PaymentResult> {\n const { requirement, submission } = context;\n\n const rejected = (reason: string): PaymentResult => ({\n status: 'rejected',\n provider: 'x402',\n amount: requirement.amount,\n currency: requirement.currency,\n ...(requirement.network !== undefined ? { network: requirement.network } : {}),\n ...(requirement.asset !== undefined ? { asset: requirement.asset } : {}),\n rejectionReason: reason,\n });\n\n if (requirement.provider !== 'x402' || requirement.challenge.provider !== 'x402') {\n return rejected('wrong_provider');\n }\n\n const requirements = requirement.challenge.accepts[0] as PaymentRequirements | undefined;\n if (!requirements) {\n return rejected('missing_payment_requirements');\n }\n\n // Defence in depth, not the real expiry: the pipeline calls\n // createRequirement() fresh on every request, so by the time verify()\n // runs this requirement is only ever seconds old — this check will\n // essentially never fire in the current flow. The actual expiry\n // enforcement is EIP-3009's validBefore, checked inside the SDK's scheme\n // facilitator. Kept because it is cheap and correct, not because it is\n // load-bearing.\n if (\n requirement.expiresAt !== undefined &&\n Date.parse(requirement.expiresAt) < clock.now().getTime()\n ) {\n return rejected('requirement_expired');\n }\n\n // Defensive invariant: the requirement we're verifying against must still\n // describe *this* provider's configured asset. It always will in normal\n // operation (we generated it), but a corrupted/mismatched requirement\n // must never be allowed to authorise a transfer for a different asset.\n if (\n !isAddress(requirements.asset) ||\n getAddress(requirements.asset) !== getAddress(options.asset)\n ) {\n return rejected('wrong_asset');\n }\n\n const payload = decodePaymentSubmission(submission.payload);\n if (!payload) {\n return rejected('malformed_payment_payload');\n }\n if (payload.x402Version !== X402_VERSION) {\n return rejected('unsupported_x402_version');\n }\n if (!isExactEvmPayload(payload)) {\n return rejected('unsupported_scheme');\n }\n\n const { authorization } = payload.payload;\n\n if (!isAddress(authorization.from) || !isAddress(authorization.to)) {\n return rejected('malformed_payment_payload');\n }\n // The network the buyer signed for is `accepted.network` — it is what the\n // scheme derives the EIP-712 chain id from — so a mismatch here means the\n // signature is bound to a different chain than the one we settle on.\n if (payload.accepted.network !== options.network) {\n return rejected('wrong_network');\n }\n if (getAddress(authorization.to) !== getAddress(options.payTo)) {\n return rejected('wrong_recipient');\n }\n let authorizedValue: bigint;\n let required: bigint;\n try {\n authorizedValue = BigInt(authorization.value);\n required = BigInt(requirements.amount);\n } catch {\n return rejected('malformed_payment_payload');\n }\n if (authorizedValue < required) {\n return rejected('wrong_amount'); // overpayment is allowed through — see the doc comment above\n }\n\n const scope = binding.open();\n let sdkResult: VerifyResponse;\n try {\n sdkResult = await scope.verify(payload, requirements);\n } catch (err) {\n if (isProviderUnavailableError(err) || scope.transportFailed()) {\n throw new CommerceError(\n 'PAYMENT_PROVIDER_UNAVAILABLE',\n `x402 provider: ${binding.kind} facilitator unreachable during verify()`,\n {\n cause: err,\n },\n );\n }\n logger.warn({ err: describeError(err) }, 'x402 verify(): unexpected SDK error');\n return rejected('unexpected_verify_error');\n }\n\n if (!sdkResult.isValid) {\n // An RPC that never answered is not a payment that failed a check.\n if (scope.transportFailed()) {\n throw new CommerceError(\n 'PAYMENT_PROVIDER_UNAVAILABLE',\n `x402 provider: ${binding.kind} facilitator unreachable during verify()`,\n { details: { reportedReason: sdkResult.invalidReason ?? 'invalid_payment' } },\n );\n }\n return rejected(sdkResult.invalidReason ?? 'invalid_payment');\n }\n\n // Derived from the chain id the authorisation is actually bound to, never\n // from a provider-instance constant, so the key stays correct the moment\n // there is more than one chain id in play.\n const payloadChainId = chainIdFromCaip2(payload.accepted.network);\n if (payloadChainId === undefined) {\n return rejected('wrong_network');\n }\n const replayKey = computeReplayKey({\n chainId: payloadChainId,\n asset: getAddress(requirements.asset),\n from: getAddress(authorization.from),\n nonce: authorization.nonce,\n });\n\n return {\n status: 'verified',\n provider: 'x402',\n payer: getAddress(authorization.from),\n payee: getAddress(authorization.to),\n amount: formatCanonicalAmount(authorizedValue, options.assetDecimals),\n currency: requirement.currency,\n network: payload.accepted.network,\n asset: getAddress(requirements.asset),\n replayKey,\n };\n }\n\n async function settle(context: PaymentSettlementContext): Promise<PaymentResult> {\n const { requirement, submission, verification } = context;\n\n if (verification.status !== 'verified') {\n throw new CommerceError(\n 'PAYMENT_INVALID',\n 'x402 provider: settle() called without a successful verify()',\n );\n }\n\n const requirements = requirement.challenge.accepts[0] as PaymentRequirements | undefined;\n if (!requirements) {\n throw new CommerceError(\n 'PAYMENT_INVALID',\n 'x402 provider: settle() found no payment requirements to settle against',\n );\n }\n\n const payload = decodePaymentSubmission(submission.payload);\n if (!payload || !isExactEvmPayload(payload)) {\n throw new CommerceError(\n 'PAYMENT_INVALID',\n 'x402 provider: settle() received an undecodable payment payload',\n );\n }\n\n const rejectedSettlement = (rejectionReason: string): PaymentResult => ({\n status: 'rejected',\n provider: 'x402',\n amount: verification.amount,\n currency: requirement.currency,\n ...(verification.network !== undefined ? { network: verification.network } : {}),\n ...(verification.asset !== undefined ? { asset: verification.asset } : {}),\n ...(verification.replayKey !== undefined ? { replayKey: verification.replayKey } : {}),\n rejectionReason,\n });\n\n const scope = binding.open();\n let sdkResult: SettleResponse;\n try {\n sdkResult = await scope.settle(payload, requirements);\n } catch (err) {\n if (isProviderUnavailableError(err) || scope.transportFailed()) {\n throw new CommerceError(\n 'PAYMENT_PROVIDER_UNAVAILABLE',\n `x402 provider: ${binding.kind} facilitator unreachable during settle()`,\n { cause: err },\n );\n }\n const rejectionReason = isOnChainRevertError(err)\n ? 'transaction_reverted'\n : 'unexpected_settle_error';\n logger.warn(\n { err: describeError(err), rejectionReason },\n 'x402 settle(): settlement transaction failed',\n );\n return rejectedSettlement(rejectionReason);\n }\n\n if (!sdkResult.success) {\n // \"Broadcast, never confirmed\" is not \"did not happen\": the transfer may\n // already be on-chain, so it surfaces as an *unavailable* provider\n // carrying the hash, letting the pipeline record\n // the attempt `settlement-uncertain` rather than `failed` and the payer\n // is told which transaction to check. Everything else is a real\n // rejection.\n if (sdkResult.errorReason === SETTLEMENT_PENDING_REASON || scope.transportFailed()) {\n throw new CommerceError(\n 'PAYMENT_PROVIDER_UNAVAILABLE',\n 'x402 provider: settlement was broadcast but could not be confirmed',\n {\n ...(sdkResult.transaction\n ? { details: { transactionHash: sdkResult.transaction } }\n : {}),\n },\n );\n }\n return {\n ...rejectedSettlement(sdkResult.errorReason ?? 'settlement_failed'),\n network: sdkResult.network,\n ...(sdkResult.payer !== undefined ? { payer: sdkResult.payer } : {}),\n };\n }\n\n return {\n status: 'settled',\n provider: 'x402',\n externalReference: sdkResult.transaction,\n ...(sdkResult.payer !== undefined ? { payer: sdkResult.payer } : {}),\n payee: requirements.payTo,\n amount: verification.amount,\n currency: requirement.currency,\n network: sdkResult.network,\n ...(verification.asset !== undefined ? { asset: verification.asset } : {}),\n ...(verification.replayKey !== undefined ? { replayKey: verification.replayKey } : {}),\n settledAt: clock.nowIso(),\n };\n }\n\n async function computeHealth(): Promise<AdapterHealth> {\n const startedAt = clock.monotonicMs();\n const checkedAt = clock.nowIso();\n\n try {\n const chainId = await healthPublicClient.getChainId();\n if (chainId !== profile.chainId) {\n return {\n status: 'fail',\n detail: `RPC at ${options.rpcUrl} reports chain id ${chainId}, expected ${profile.chainId} (${profile.displayName})`,\n checkedAt,\n durationMs: clock.monotonicMs() - startedAt,\n };\n }\n\n const code = await healthPublicClient.getCode({ address: options.asset });\n if (!code || code === '0x') {\n return {\n status: 'fail',\n detail: `No contract code found at configured asset address ${options.asset}`,\n checkedAt,\n durationMs: clock.monotonicMs() - startedAt,\n };\n }\n\n if (binding.kind === 'remote') {\n // \"Reachable\" is not the question — \"will it settle *this*\" is. A\n // facilitator that is up but does not carry our scheme on our network\n // fails every payment, and does it after the buyer has signed.\n const kinds = await binding.supported();\n const supportsUs = kinds.some(\n (kind) =>\n kind.x402Version === X402_VERSION &&\n kind.scheme === 'exact' &&\n kind.network === options.network,\n );\n if (!supportsUs) {\n return {\n status: 'fail',\n detail:\n `Facilitator ${binding.describe} does not advertise x402 v${X402_VERSION} scheme=exact ` +\n `on ${options.network} (${profile.displayName}); no payment on this deployment can settle`,\n checkedAt,\n durationMs: clock.monotonicMs() - startedAt,\n };\n }\n return {\n status: 'pass',\n detail:\n `${describeDeploymentMode(mode)} — RPC ${options.rpcUrl} reachable, chain id ` +\n `${profile.chainId} (${profile.displayName}), asset ${options.asset} has code, ` +\n `facilitator ${binding.describe} supports exact/${options.network}`,\n checkedAt,\n durationMs: clock.monotonicMs() - startedAt,\n };\n }\n\n // Chain id alone cannot prove this is a dev chain: real Base Sepolia\n // reports the same id (84532) as this project's local chain, by design.\n // Probe an Anvil-only RPC method — present only on a real Anvil node —\n // before trusting a well-known dev key against it.\n const isAnvil = await probeIsAnvilNode(healthPublicClient);\n if (!isAnvil) {\n return {\n status: 'fail',\n detail:\n `RPC at ${options.rpcUrl} reports chain id ${profile.chainId} but does not answer ` +\n '\"anvil_nodeInfo\" — it does not look like a local Anvil dev node. Refusing to treat it ' +\n 'as safe for a local-facilitator dev key.',\n checkedAt,\n durationMs: clock.monotonicMs() - startedAt,\n };\n }\n\n return {\n status: 'pass',\n detail:\n `${describeDeploymentMode(mode)} — RPC ${options.rpcUrl} reachable, chain id ` +\n `${profile.chainId}, asset ${options.asset} has code, confirmed Anvil dev node`,\n checkedAt,\n durationMs: clock.monotonicMs() - startedAt,\n };\n } catch (err) {\n return {\n status: 'fail',\n detail: `x402 health check failed: ${describeError(err)}`,\n checkedAt,\n durationMs: clock.monotonicMs() - startedAt,\n };\n }\n }\n\n // /ready has no auth, no cache and no\n // rate limit, and called computeHealth() — 3 live RPC calls — on every\n // single request; measured 3x amplification of billed upstream calls\n // under an unauthenticated flood. Memoise behind a short TTL and collapse\n // concurrent callers onto one in-flight probe, so N requests within the\n // window produce at most one round-trip instead of N.\n //\n // 5s: short enough that a readiness probe (Kubernetes' own default\n // `periodSeconds` is 10s) never observes data older than its own poll\n // interval, long enough to fully decouple RPC call volume from HTTP\n // request volume — which is the property that closes the amplification,\n // not the exact number of seconds.\n //\n // pass and fail are cached for the same TTL, deliberately: a shorter TTL\n // for fail would re-introduce the amplification exactly when an upstream\n // outage makes every call expensive/slow, which is the worst possible time\n // to remove the cache's protection. 5s of recovery latency after the RPC\n // comes back is an acceptable trade — it is already within the noise of a\n // single health probe's own round-trip time, and well inside a normal\n // probe's own poll interval.\n //\n // This only memoises this provider's own RPC probe. `core` separately\n // memoises the whole /ready aggregation (src/gateway/readiness.ts)\n // — a second, independent layer at a different scope; the two compose\n // without conflict since neither assumes anything about the other's TTL.\n //\n // Does not affect `doctor`'s deployment-mismatch cross-check: that reads\n // asset/network/payTo straight from `/.well-known/agent-commerce` (static\n // provider config, echoed live, never cached), not from health().\n const HEALTH_CACHE_MS = 5_000;\n let cachedHealth: { at: number; value: AdapterHealth } | undefined;\n let inFlightHealth: Promise<AdapterHealth> | undefined;\n\n async function health(): Promise<AdapterHealth> {\n const now = clock.monotonicMs();\n if (cachedHealth && now - cachedHealth.at < HEALTH_CACHE_MS) {\n return cachedHealth.value;\n }\n if (inFlightHealth) return inFlightHealth;\n\n inFlightHealth = computeHealth()\n .then((value) => {\n cachedHealth = { at: clock.monotonicMs(), value };\n return value;\n })\n .finally(() => {\n inFlightHealth = undefined;\n });\n return inFlightHealth;\n }\n\n return {\n name: 'x402',\n descriptor,\n createRequirement,\n verify,\n settle,\n health,\n };\n}\n\nfunction isOnChainRevertError(err: unknown): boolean {\n return (\n err instanceof ContractFunctionRevertedError || err instanceof ContractFunctionExecutionError\n );\n}\n\n/**\n * `instanceof` checks first — these are the real error classes the pinned\n * viem@2.55.18 HTTP transport throws (see viem's `utils/rpc/http.js`, which\n * wraps every fetch failure, including connection-refused, in\n * `HttpRequestError` unless it is already a `TimeoutError`), plus the error\n * `waitForTransactionReceipt` itself throws when it gives up polling for a\n * receipt — precisely the \"broadcast succeeded, confirmation didn't\" case\n * this classification exists to catch. Substring matching\n * is kept only as a fallback for shapes not covered by a typed viem class\n * (e.g. a raw Node/undici error surfacing through some other path) — pinning\n * behaviour to message text is brittle across viem/undici upgrades, so the\n * instanceof checks should be preferred and grown over time as more real\n * failure shapes are seen.\n */\nfunction isProviderUnavailableError(err: unknown): boolean {\n if (\n err instanceof HttpRequestError ||\n err instanceof TimeoutError ||\n err instanceof WaitForTransactionReceiptTimeoutError\n ) {\n return true;\n }\n const message = describeError(err).toLowerCase();\n return (\n message.includes('econnrefused') ||\n message.includes('fetch failed') ||\n message.includes('enotfound') ||\n message.includes('etimedout') ||\n message.includes('timed out') ||\n message.includes('network error')\n );\n}\n\n/** Never includes secrets: only error class name + message, never raw payloads or keys. */\nfunction describeError(err: unknown): string {\n if (err instanceof Error) return `${err.name}: ${err.message}`;\n return String(err);\n}\n\n/**\n * True only when the RPC answers Anvil's own `anvil_nodeInfo` method — a\n * real network (including real Base Sepolia, which shares chain id 84532\n * with this project's local chain by design) returns a JSON-RPC \"method\n * not found\" error instead. Never throws.\n */\nasync function probeIsAnvilNode(\n client: ReturnType<typeof createLocalPublicClient>,\n): Promise<boolean> {\n // Anvil-only method: not part of viem's typed PublicRpcSchema, hence the cast.\n const request = client.request as unknown as (args: {\n method: string;\n params: unknown[];\n }) => Promise<unknown>;\n try {\n await request({ method: 'anvil_nodeInfo', params: [] });\n return true;\n } catch {\n return false;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/payments/x402/chain.ts","../src/payments/x402/client.ts","../src/payments/x402/amount.ts","../src/payments/x402/facilitator.ts","../src/payments/x402/payload.ts","../src/payments/x402/replay-key.ts","../src/payments/x402/provider.ts"],"names":["privateKeyToAccount","X402_VERSION","getAddress"],"mappings":"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","file":"x402.js","sourcesContent":["/**\n * Local deterministic chain wiring.\n *\n * The x402 SDK resolves RPC endpoints for public networks from its own\n * tables — exactly what we must never touch: the tests must stay\n * deterministic. Instead we build plain viem clients pointed at\n * `options.rpcUrl`, using a custom `Chain` object whose id is 84532, the\n * chain id carried by the CAIP-2 network identifier the gateway advertises\n * (`eip155:84532`).\n *\n * The `Local` prefix on everything here describes the *chain* these clients\n * are built for, not a test-only status: `provider.ts` calls\n * `createLocalPublicClient` and `createLocalFacilitatorClient` on the real\n * settlement path, and this is not demo scaffolding a production build could\n * drop.\n *\n * Public networks are supported, and `buildLocalChain` now takes the chain id\n * as a parameter — exactly what this comment used to say would be required.\n * What stays local is the *facilitator* client: signing in-process is refused\n * on any mainnet, so that client can only ever exist on the dev chain. The\n * read-only health client is built for whatever network is configured.\n *\n * `dev-key-guard.ts` is the boundary that keeps that arrangement safe: it\n * refuses at provider construction if a dev key or dev `payTo` is pointed at\n * anything other than a loopback/private RPC.\n */\nimport {\n type Account,\n type Chain,\n type Client,\n createPublicClient,\n createWalletClient,\n http,\n type PublicActions,\n type PublicClient,\n publicActions,\n type Transport,\n type WalletActions,\n} from 'viem';\nimport { privateKeyToAccount } from 'viem/accounts';\n\n/** A wallet client that can also read chain state — matches x402's `SignerWallet`. */\nexport type LocalFacilitatorClient = Client<\n Transport,\n Chain,\n Account,\n undefined,\n PublicActions<Transport, Chain, Account> & WalletActions<Chain, Account>\n>;\n\n/**\n * Chain id of the local deterministic dev chain. Shared with the public Base\n * Sepolia testnet, which is why nothing may infer \"this is a public network\"\n * from the id alone — `provider.ts` probes for a real Anvil node instead.\n */\nexport const LOCAL_CHAIN_ID = 84532;\n\n/** CAIP-2 identifier the local dev chain is advertised under. */\nexport const LOCAL_NETWORK = `eip155:${LOCAL_CHAIN_ID}`;\n\n/**\n * Chain id carried by a CAIP-2 `eip155` network identifier.\n *\n * x402 v2 identifies networks as CAIP-2 strings rather than the v1 name table,\n * so the chain id a signature is bound to is read straight off the wire value\n * instead of looked up. Returns `undefined` for anything that is not an\n * `eip155` identifier — a caller must never fall back to a default chain id,\n * because the chain id is part of the EIP-712 domain a buyer signed.\n */\nexport function chainIdFromCaip2(network: string): number | undefined {\n const match = /^eip155:(\\d+)$/.exec(network);\n if (!match?.[1]) return undefined;\n const chainId = Number(match[1]);\n return Number.isSafeInteger(chainId) && chainId > 0 ? chainId : undefined;\n}\n\n/**\n * `chainId` defaults to the local dev chain because the *facilitator* client\n * can only ever exist there — a local facilitator is refused on any mainnet.\n * The read-only health client is different: it is built for whatever network\n * is configured, including Base, and inherited 84532 on every one of them.\n * Inert while it only issues raw `getChainId`/`getCode`/`anvil_nodeInfo`, and\n * wrong the moment anything through it consults `chain.id`.\n */\nexport function buildLocalChain(rpcUrl: string, chainId: number = LOCAL_CHAIN_ID): Chain {\n return {\n id: chainId,\n name: 'agent-commerce-local',\n nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },\n rpcUrls: {\n default: { http: [rpcUrl] },\n },\n } satisfies Chain;\n}\n\n/**\n * A viem `PublicClient` for the local chain — read-only, no signing capability.\n *\n * `timeoutMs`, when given, is passed straight to viem's `http()` transport,\n * which ties it to a real `AbortController` around the underlying `fetch`\n * (see viem's `utils/promise/withTimeout.js` — `signal: true`). That is a\n * genuine cancellation, unlike a bare `Promise.race` against a timer, which\n * only stops *waiting* for the request while the request itself keeps\n * running server-side. Omit it to keep viem's own default (10s).\n */\nexport function createLocalPublicClient(\n rpcUrl: string,\n timeoutMs?: number,\n chainId?: number,\n): PublicClient {\n return createPublicClient({\n chain: buildLocalChain(rpcUrl, chainId),\n transport: http(rpcUrl, timeoutMs !== undefined ? { timeout: timeoutMs } : undefined),\n });\n}\n\n/**\n * A viem `WalletClient` extended with public actions, for the local\n * facilitator signer only. x402's `settle()` calls `writeContract`,\n * `waitForTransactionReceipt` and `getCode` on this client — i.e. it needs\n * both `WalletActions` and `PublicActions`, matching x402's `SignerWallet`\n * type.\n *\n * LOCAL DEVELOPMENT ONLY — the private key behind this client must always be\n * an Anvil well-known development key, never a merchant or buyer key, and\n * never a production key of any kind.\n */\nexport function createLocalFacilitatorClient(\n rpcUrl: string,\n signerPrivateKey: `0x${string}`,\n): LocalFacilitatorClient {\n const chain = buildLocalChain(rpcUrl);\n const account = privateKeyToAccount(signerPrivateKey);\n return createWalletClient({\n account,\n chain,\n transport: http(rpcUrl),\n }).extend(publicActions);\n}\n","/**\n * CLIENT-SIDE payment helper.\n *\n * This module is used by the demo buyer agent (`demo/agent`) and by the\n * payment E2E test suite to build and EIP-712-sign an x402 v2 `exact`/EVM\n * payment authorisation, entirely on the buyer's side.\n *\n * The gateway NEVER calls this module and NEVER holds a buyer private key.\n * `buyerPrivateKey` here is always an Anvil well-known\n * development key (LOCAL DEVELOPMENT ONLY — DO NOT FUND) supplied by whoever\n * is driving the demo/test, not something the provider or gateway manages.\n *\n * It signs the EIP-712 authorisation directly rather than going through the\n * SDK's `x402Client`, for one reason: `overrides`. The negative payment tests\n * need authorisations that are deliberately wrong — wrong recipient, short\n * amount, reused nonce, expired window — and a conforming client will not\n * produce those. Interop with a real SDK client is proved separately, by a\n * test that pays the gateway using `x402Client` itself.\n */\n\nimport { PaymentRequirementsV2Schema } from '@x402/core/schemas';\nimport type { PaymentPayload, PaymentRequirements } from '@x402/core/types';\nimport { getAddress, toHex } from 'viem';\nimport { privateKeyToAccount } from 'viem/accounts';\nimport { chainIdFromCaip2 } from './chain.js';\n\nexport interface CreatePaymentProofOptions {\n /** Buyer's dev-only private key. LOCAL DEVELOPMENT ONLY — DO NOT FUND. */\n readonly buyerPrivateKey: `0x${string}`;\n readonly rpcUrl: string;\n /** One entry from PaymentRequiredEnvelope.payment.accepts, verbatim. */\n readonly accepts: Readonly<Record<string, unknown>>;\n /** Overrides used only by negative tests (wrong amount/recipient/nonce…). */\n readonly overrides?: {\n readonly value?: string;\n readonly payTo?: string;\n readonly nonce?: `0x${string}`;\n readonly validBefore?: number;\n readonly validAfter?: number;\n };\n}\n\nconst X402_VERSION = 2;\n\nconst TRANSFER_WITH_AUTHORIZATION_TYPES = {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n} as const;\n\n/** Returns the base64 `PAYMENT-SIGNATURE` value to send back to the gateway. */\nexport async function createPaymentProof(options: CreatePaymentProofOptions): Promise<string> {\n const requirements = PaymentRequirementsV2Schema.parse(options.accepts);\n if (\n !requirements.extra ||\n typeof requirements.extra['name'] !== 'string' ||\n typeof requirements.extra['version'] !== 'string'\n ) {\n throw new Error(\n 'createPaymentProof: payment requirement is missing extra.name/extra.version — cannot build the EIP-712 domain',\n );\n }\n\n const chainId = chainIdFromCaip2(requirements.network);\n if (chainId === undefined) {\n throw new Error(\n `createPaymentProof: network \"${requirements.network}\" is not a CAIP-2 eip155 identifier — cannot determine the chain id to sign against`,\n );\n }\n\n const account = privateKeyToAccount(options.buyerPrivateKey);\n // `rpcUrl` is part of the frozen `CreatePaymentProofOptions` shape for\n // interface parity with other providers, but the `exact`/EVM scheme signs\n // fully offline: the chain id comes from the CAIP-2 network identifier\n // (matching what the facilitator's verify()/settle() compute), and the\n // nonce is a fresh random value, not one read from chain state.\n void options.rpcUrl;\n\n const nonce = options.overrides?.nonce ?? randomNonce();\n const nowSeconds = Math.floor(Date.now() / 1000);\n // 0, matching the SDK's own v2 client: `validAfter` exists to delay an\n // authorisation, and nothing here wants one delayed. A backdated value would\n // only paper over clock skew that `validBefore` has to tolerate anyway.\n const validAfter = options.overrides?.validAfter ?? 0;\n const validBefore = options.overrides?.validBefore ?? nowSeconds + requirements.maxTimeoutSeconds;\n const to = getAddress((options.overrides?.payTo ?? requirements.payTo) as `0x${string}`);\n const value = BigInt(options.overrides?.value ?? requirements.amount);\n\n const signature = await account.signTypedData({\n domain: {\n name: requirements.extra['name'],\n version: requirements.extra['version'],\n chainId,\n verifyingContract: getAddress(requirements.asset as `0x${string}`),\n },\n types: TRANSFER_WITH_AUTHORIZATION_TYPES,\n primaryType: 'TransferWithAuthorization',\n message: {\n from: account.address,\n to,\n value,\n validAfter: BigInt(validAfter),\n validBefore: BigInt(validBefore),\n nonce,\n },\n });\n\n // v2 carries the selected requirement back to the server as `accepted`\n // rather than repeating scheme/network at the top level. The server treats\n // that echo as untrusted and verifies against its own copy; it is on the\n // wire so a stateless facilitator knows which offer was taken.\n const payload: PaymentPayload = {\n x402Version: X402_VERSION,\n accepted: requirements as PaymentRequirements,\n payload: {\n signature,\n authorization: {\n from: account.address,\n to,\n value: value.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n },\n },\n };\n\n return Buffer.from(JSON.stringify(payload), 'utf8').toString('base64');\n}\n\nfunction randomNonce(): `0x${string}` {\n const bytes = new Uint8Array(32);\n crypto.getRandomValues(bytes);\n return toHex(bytes);\n}\n","/**\n * Deterministic decimal <-> base-unit conversion.\n *\n * `DecimalAmount` (see src/core) is a decimal string in\n * *display* units (\"0.01\" USDC). x402 / EIP-3009 need base units (integer\n * string, e.g. \"10000\" for 0.01 USDC at 6 decimals). This conversion must\n * never go through a JS `number` — floating point cannot represent most\n * decimal fractions exactly, and a silently-rounded payment amount is a\n * security bug in a payment provider.\n *\n * viem's own `parseUnits` rounds silently when given more fractional digits\n * than `decimals` supports; we need a hard error instead (a merchant asking\n * for \"0.0000001\" against a 6-decimal asset is a configuration bug, not a\n * roundable amount), so this module implements its own strict parser.\n */\nimport { CommerceError } from '../../core/index.js';\n\nconst DECIMAL_STRING_PATTERN = /^\\d+(?:\\.\\d+)?$/;\n\n/**\n * Parses a canonical decimal display amount (e.g. \"0.01\") into base units\n * for an asset with the given number of decimals, without floating point.\n *\n * Throws `CommerceError('PAYMENT_INVALID')` if the string is not a plain\n * non-negative decimal, or if it carries more fractional digits than the\n * asset supports.\n */\nexport function parseCanonicalAmount(amount: string, decimals: number): bigint {\n if (!Number.isInteger(decimals) || decimals < 0) {\n throw new CommerceError('INTERNAL_ERROR', `Invalid asset decimals: ${decimals}`);\n }\n if (!DECIMAL_STRING_PATTERN.test(amount)) {\n throw new CommerceError(\n 'PAYMENT_INVALID',\n `Amount \"${amount}\" is not a valid non-negative decimal string`,\n {\n details: { amount },\n },\n );\n }\n\n const [integerPart = '0', fractionPart = ''] = amount.split('.');\n\n if (fractionPart.length > decimals) {\n throw new CommerceError(\n 'PAYMENT_INVALID',\n `Amount \"${amount}\" has more precision than the asset supports (${decimals} decimals)`,\n { details: { amount, assetDecimals: decimals } },\n );\n }\n\n const paddedFraction = fractionPart.padEnd(decimals, '0');\n const combined = `${integerPart}${paddedFraction}`;\n // Strip leading zeros so BigInt doesn't choke on e.g. \"007\" — BigInt() is\n // fine with leading zeros in decimal strings, but normalise defensively.\n return BigInt(combined);\n}\n\n/**\n * Formats base units back into a canonical decimal display string.\n *\n * Exact (no rounding is possible going from integer base units to a wider\n * decimal representation), so this is safe to implement directly.\n */\nexport function formatCanonicalAmount(baseUnits: bigint, decimals: number): string {\n if (!Number.isInteger(decimals) || decimals < 0) {\n throw new CommerceError('INTERNAL_ERROR', `Invalid asset decimals: ${decimals}`);\n }\n const negative = baseUnits < 0n;\n const abs = negative ? -baseUnits : baseUnits;\n const digits = abs.toString().padStart(decimals + 1, '0');\n const integerPart = digits.slice(0, digits.length - decimals) || '0';\n const fractionPart = digits.slice(digits.length - decimals).replace(/0+$/, '');\n const sign = negative ? '-' : '';\n return fractionPart.length > 0\n ? `${sign}${integerPart}.${fractionPart}`\n : `${sign}${integerPart}`;\n}\n","/**\n * The facilitator seam.\n *\n * A facilitator is whatever verifies an authorisation and broadcasts the\n * transfer. This gateway supports two, behind one interface:\n *\n * local the SDK's in-process `x402Facilitator` signing against a dev node\n * remote an HTTP facilitator, with or without a credential\n *\n * Both are the SDK's own `FacilitatorClient` contract underneath, so neither\n * is a bespoke reimplementation of the protocol — the local one is the same\n * code a hosted facilitator runs, pointed at the local chain.\n *\n * A *session* is opened per verify/settle call rather than reused, because\n * `transportFailed()` has to be scoped to one request: two concurrent\n * payments must not see each other's transport failures. The cost is an\n * object literal against an RPC or HTTP round-trip.\n */\nimport { x402Facilitator } from '@x402/core/facilitator';\nimport { HTTPFacilitatorClient } from '@x402/core/http';\nimport type {\n Network,\n PaymentPayload,\n PaymentRequirements,\n SettleResponse,\n VerifyResponse,\n} from '@x402/core/types';\nimport { toFacilitatorEvmSigner } from '@x402/evm';\nimport { registerExactEvmScheme } from '@x402/evm/exact/facilitator';\nimport { CommerceError } from '../../core/index.js';\nimport type { LocalFacilitatorClient } from './chain.js';\nimport type { FacilitatorAuth } from './guardrails.js';\n\n/** One verify or one settle, with its own transport-failure flag. */\nexport interface FacilitatorSession {\n verify(payload: PaymentPayload, requirements: PaymentRequirements): Promise<VerifyResponse>;\n settle(payload: PaymentPayload, requirements: PaymentRequirements): Promise<SettleResponse>;\n /**\n * True when the call failed to reach the facilitator (or the chain behind\n * it) rather than producing a verdict.\n *\n * The SDK's `exact`/EVM scheme catches its own RPC errors and reports them\n * as an ordinary verification failure — an unreachable node comes back as\n * `invalid_exact_evm_signature`. Fail-closed still holds, but the buyer is\n * told their signature is bad and the attempt is recorded as their fault,\n * when nothing about their payment was ever checked. This flag is how the\n * provider tells \"we looked and it was wrong\" apart from \"we could not\n * look\".\n */\n transportFailed(): boolean;\n}\n\nexport interface SupportedKind {\n readonly x402Version: number;\n readonly scheme: string;\n readonly network: string;\n}\n\nexport interface FacilitatorBinding {\n readonly kind: 'local' | 'remote';\n /** Human-readable, never a credential. */\n readonly describe: string;\n open(): FacilitatorSession;\n /** What the facilitator says it can settle. Used by health(), not by the payment path. */\n supported(): Promise<readonly SupportedKind[]>;\n}\n\n/** Bounds every receipt wait the in-process facilitator performs. */\nexport const SETTLEMENT_CONFIRMATION_TIMEOUT_MS = 60_000;\n\n/**\n * An in-process `x402Facilitator` with the `exact`/EVM scheme registered\n * against exactly one network.\n *\n * One network, not the `eip155:*` wildcard the SDK would otherwise derive: a\n * payload naming some other chain must find no facilitator at all rather than\n * reaching a scheme that would then have to reject it.\n */\nexport function createLocalFacilitatorBinding(\n client: LocalFacilitatorClient,\n network: string,\n isTransportError: (err: unknown) => boolean,\n): FacilitatorBinding {\n const build = (): { facilitator: x402Facilitator; failed: () => boolean } => {\n let failed = false;\n const watch = <T>(promise: Promise<T>): Promise<T> =>\n promise.catch((err: unknown) => {\n if (isTransportError(err)) failed = true;\n throw err;\n });\n\n // Exactly the `FacilitatorEvmSigner` surface, so the wrapper covers every\n // call the SDK can make. `toFacilitatorEvmSigner` wants a flat `address`,\n // which viem carries on `client.account` instead.\n const signer = {\n address: client.account.address,\n readContract: (args: Parameters<LocalFacilitatorClient['readContract']>[0]) =>\n watch(client.readContract(args)),\n verifyTypedData: (args: Parameters<LocalFacilitatorClient['verifyTypedData']>[0]) =>\n watch(client.verifyTypedData(args)),\n writeContract: (args: Parameters<LocalFacilitatorClient['writeContract']>[0]) =>\n watch(client.writeContract(args)),\n sendTransaction: (args: Parameters<LocalFacilitatorClient['sendTransaction']>[0]) =>\n watch(client.sendTransaction(args)),\n waitForTransactionReceipt: (\n args: Parameters<LocalFacilitatorClient['waitForTransactionReceipt']>[0],\n ) => watch(client.waitForTransactionReceipt(args)),\n getCode: (args: Parameters<LocalFacilitatorClient['getCode']>[0]) =>\n watch(client.getCode(args)),\n } as unknown as Parameters<typeof toFacilitatorEvmSigner>[0];\n\n // `confirmationTimeoutMs` is what turns a lost receipt wait into\n // `settlement_pending` + the broadcast hash instead of a discarded broadcast.\n const facilitator = registerExactEvmScheme(new x402Facilitator(), {\n signer: toFacilitatorEvmSigner(signer, {\n confirmationTimeoutMs: SETTLEMENT_CONFIRMATION_TIMEOUT_MS,\n }),\n networks: network as Network,\n });\n\n return { facilitator, failed: () => failed };\n };\n\n return {\n kind: 'local',\n describe: 'local (in-process)',\n open(): FacilitatorSession {\n const { facilitator, failed } = build();\n return {\n verify: (payload, requirements) => facilitator.verify(payload, requirements),\n settle: (payload, requirements) => facilitator.settle(payload, requirements),\n transportFailed: failed,\n };\n },\n async supported(): Promise<readonly SupportedKind[]> {\n return build().facilitator.getSupported().kinds;\n },\n };\n}\n\nexport interface RemoteFacilitatorOptions {\n readonly url: string;\n readonly auth: FacilitatorAuth;\n readonly timeoutMs?: number;\n}\n\n/** The SDK's path-keyed auth-header shape. A flat object throws inside it. */\ntype AuthHeaderFactory = () => Promise<Record<string, Record<string, string>>>;\n\n/**\n * CDP signs a fresh JWT per request over method + host + path, so a static\n * header cannot express it. `@coinbase/x402` does that signing, and is\n * imported dynamically: a static import would drag the whole CDP SDK — and its\n * Solana, axios and JOSE dependencies — into the `/x402` subpath for everyone,\n * including the majority who use a facilitator that needs no credential at all.\n *\n * The import is started at construction rather than on the first payment. A\n * missing peer must surface as an unhealthy provider before a buyer signs\n * anything, not as a failure inside verify() with their authorisation already\n * spent.\n */\nfunction cdpAuthHeaders(apiKeyId: string, apiKeySecret: string): AuthHeaderFactory {\n const loading = import('@coinbase/x402').then(\n (mod) => mod.createCdpAuthHeaders(apiKeyId, apiKeySecret),\n (cause: unknown) => {\n throw new CommerceError(\n 'CONFIG_INVALID',\n 'x402 provider: facilitator.auth.type is \"cdp\", which needs the optional peer ' +\n '\"@coinbase/x402\". Install it (npm install @coinbase/x402), or use a facilitator ' +\n 'that accepts a static token with auth.type \"bearer\".',\n { cause },\n );\n },\n );\n // Nothing awaits this until the first call; without a handler the rejection\n // above would be an unhandled promise rejection at startup.\n loading.catch(() => {});\n\n return async () => {\n const create = await loading;\n if (!create) {\n throw new CommerceError(\n 'PAYMENT_PROVIDER_UNAVAILABLE',\n 'x402 provider: @coinbase/x402 returned no auth-header factory',\n );\n }\n return (await create()) as Record<string, Record<string, string>>;\n };\n}\n\n/**\n * An HTTP facilitator.\n *\n * Auth headers are produced per request by the SDK client and never logged,\n * never echoed into `/.well-known`, and never included in `describe`.\n */\nexport function createRemoteFacilitatorBinding(\n options: RemoteFacilitatorOptions,\n): FacilitatorBinding {\n const auth = options.auth;\n let createAuthHeaders: AuthHeaderFactory | undefined;\n if (auth.type === 'bearer') {\n createAuthHeaders = async () => {\n // The SDK requires a path-keyed object; a flat headers object throws\n // rather than silently dropping auth on every request.\n const headers = { Authorization: `Bearer ${auth.token}` };\n return { verify: headers, settle: headers, supported: headers };\n };\n } else if (auth.type === 'cdp') {\n createAuthHeaders = cdpAuthHeaders(auth.apiKeyId, auth.apiKeySecret);\n }\n\n const client = new HTTPFacilitatorClient({\n url: options.url,\n timeoutMs: options.timeoutMs ?? SETTLEMENT_CONFIRMATION_TIMEOUT_MS,\n ...(createAuthHeaders ? { createAuthHeaders } : {}),\n });\n\n return {\n kind: 'remote',\n describe: `remote ${new URL(options.url).origin} (auth=${auth.type})`,\n open(): FacilitatorSession {\n let failed = false;\n const watch = async <T>(call: () => Promise<T>): Promise<T> => {\n try {\n return await call();\n } catch (err) {\n // *Any* throw out of the SDK client means no verdict was obtained.\n // A verdict arrives as a returned `VerifyResponse`/`SettleResponse`,\n // including a negative one; the client only throws when it could not\n // reach the facilitator, could not authenticate to it, got a non-2xx,\n // or could not parse what came back. None of those are facts about\n // the payment, and recording them against the payer would blame the\n // buyer for our credential or the facilitator's outage.\n //\n // Deliberately not a predicate over error shapes: the SDK throws a\n // bare `Error` for an HTTP status (`Facilitator verify failed (401)`)\n // and a `FacilitatorResponseError` for a bad body, so matching on\n // type or message would have missed exactly the credential case that\n // matters most. For settle() this also preserves the indeterminate\n // reading — a timeout may have settled after we stopped waiting.\n failed = true;\n throw err;\n }\n };\n return {\n verify: (payload, requirements) => watch(() => client.verify(payload, requirements)),\n settle: (payload, requirements) => watch(() => client.settle(payload, requirements)),\n transportFailed: () => failed,\n };\n },\n async supported(): Promise<readonly SupportedKind[]> {\n const response = await client.getSupported();\n return response.kinds as readonly SupportedKind[];\n },\n };\n}\n","/**\n * Decoding and validation for the base64 `PAYMENT-SIGNATURE` submission.\n *\n * A malformed payload (not base64, valid base64 but not JSON, valid JSON but\n * the wrong shape) must yield a `rejected` verification result, never a\n * thrown/crashed request — this module returns `undefined` on any failure so\n * callers can turn that into a typed rejection. That is why it parses the\n * schema itself rather than calling the SDK's `decodePaymentSignatureHeader`,\n * which throws.\n */\nimport { PaymentPayloadV2Schema } from '@x402/core/schemas';\nimport type { PaymentPayload } from '@x402/core/types';\nimport { type ExactEIP3009Payload, isEIP3009Payload } from '@x402/evm';\n\nexport function decodePaymentSubmission(payloadBase64: string): PaymentPayload | undefined {\n let json: unknown;\n try {\n const decoded = Buffer.from(payloadBase64, 'base64').toString('utf8');\n json = JSON.parse(decoded);\n } catch {\n return undefined;\n }\n\n const result = PaymentPayloadV2Schema.safeParse(json);\n return result.success ? (result.data as PaymentPayload) : undefined;\n}\n\n/**\n * Narrows a decoded payload to the EIP-3009 `exact`/EVM shape this provider\n * settles.\n *\n * x402 v2's `exact` scheme on EVM has two asset-transfer methods — EIP-3009\n * `transferWithAuthorization` and Permit2. Only the first is supported here,\n * and the challenge says so (`extra.assetTransferMethod`), so a Permit2\n * payload arriving anyway is rejected rather than handed to the SDK: the\n * Permit2 proxy is not deployed on the local chain and a failure there would\n * surface as an opaque settlement revert instead of a clear rejection.\n */\nexport function isExactEvmPayload(\n payload: PaymentPayload,\n): payload is PaymentPayload & { payload: ExactEIP3009Payload } {\n return (\n payload.accepted.scheme === 'exact' &&\n typeof payload.payload === 'object' &&\n payload.payload !== null &&\n isEIP3009Payload(payload.payload as ExactEIP3009Payload) &&\n typeof (payload.payload as ExactEIP3009Payload).signature === 'string'\n );\n}\n","/**\n * Replay-key derivation.\n *\n *Per docs/contracts.md, `PaymentResult.replayKey` MUST be\n * derived only from the payment authorisation (chain id, asset, payer,\n * nonce) — never from the request id — so that the same authorisation\n * replayed against a *different* request still collides in the gateway's\n * receipt-store reservation.\n */\nimport { encodeAbiParameters, keccak256 } from 'viem';\n\nexport interface ReplayKeyInput {\n readonly chainId: number;\n readonly asset: `0x${string}`;\n readonly from: `0x${string}`;\n readonly nonce: `0x${string}`;\n}\n\nexport function computeReplayKey(input: ReplayKeyInput): string {\n const encoded = encodeAbiParameters(\n [{ type: 'uint256' }, { type: 'address' }, { type: 'address' }, { type: 'bytes32' }],\n [BigInt(input.chainId), input.asset, input.from, input.nonce],\n );\n return keccak256(encoded);\n}\n","/**\n * x402 payment provider — protocol version 2, `exact` scheme, EVM,\n * EIP-3009 `transferWithAuthorization`.\n *\n * Implements the frozen `PaymentProvider` interface (src/core/domain/payment.ts).\n * `verify()` never moves funds; only `settle()` does, and only after a\n * successful `verify()` (enforced by the gateway's execution pipeline, not by\n * this file, but this file never calls settle-like RPCs from verify()).\n *\n * Verification and settlement run through the SDK's own `x402Facilitator`\n * with the `exact`/EVM scheme registered against a single CAIP-2 network. The\n * facilitator is in-process — it is the same code a hosted facilitator runs,\n * pointed at the local dev chain — so there is no network hop and no third\n * party in the settlement path.\n *\n * The SDK behaviour relied on here is verified, not assumed: see the notes\n * beside each call site below.\n */\n\nimport type {\n Network,\n PaymentRequired,\n PaymentRequirements,\n SettleResponse,\n VerifyResponse,\n} from '@x402/core/types';\nimport {\n ContractFunctionExecutionError,\n ContractFunctionRevertedError,\n getAddress,\n HttpRequestError,\n isAddress,\n TimeoutError,\n WaitForTransactionReceiptTimeoutError,\n} from 'viem';\nimport {\n type AdapterDescriptor,\n type AdapterHealth,\n type Clock,\n CommerceError,\n type IdGenerator,\n type Logger,\n NOOP_LOGGER,\n type PaymentContext,\n type PaymentProvider,\n type PaymentRequirement,\n type PaymentResult,\n type PaymentSettlementContext,\n type PaymentVerificationContext,\n systemClock,\n} from '../../core/index.js';\nimport { PACKAGE_VERSION } from '../../version.js';\nimport { formatCanonicalAmount, parseCanonicalAmount } from './amount.js';\nimport {\n chainIdFromCaip2,\n createLocalFacilitatorClient,\n createLocalPublicClient,\n type LocalFacilitatorClient,\n} from './chain.js';\nimport { assertDevKeyIsLocalOnly, assertPayToIsNotDevAddress } from './dev-key-guard.js';\nimport {\n createLocalFacilitatorBinding,\n createRemoteFacilitatorBinding,\n type FacilitatorBinding,\n} from './facilitator.js';\nimport { resolveX402Deployment, type X402FacilitatorConfig } from './guardrails.js';\nimport { describeDeploymentMode } from './networks.js';\nimport { decodePaymentSubmission, isExactEvmPayload } from './payload.js';\nimport { computeReplayKey } from './replay-key.js';\n\nconst X402_VERSION = 2;\nconst X402_PROTOCOL_VERSION = String(X402_VERSION);\nconst DEFAULT_MAX_TIMEOUT_SECONDS = 60;\nconst DEFAULT_MIME_TYPE = 'application/json';\nconst HEALTH_TIMEOUT_MS = 4_000;\n/** `SettleResponse.errorReason` the SDK uses for \"broadcast, not confirmed\". */\nconst SETTLEMENT_PENDING_REASON = 'settlement_pending';\n/**\n * `invalidReason`/`errorReason` are `z.string()` in the SDK schema — no length\n * or charset bound. They become the message a buyer is told about their own\n * payment, a persisted and SSE-streamed event field, and a column in the\n * merchant's ledger. A remote facilitator is a counterparty this design\n * explicitly contemplates having no account or terms with, so treat its\n * strings as untrusted input rather than as diagnostics.\n */\nconst MAX_REASON_LENGTH = 64;\nconst REASON_SHAPE = /^[a-z0-9_.-]+$/i;\n\nfunction sanitiseReason(reason: string | undefined, fallback: string): string {\n if (reason === undefined) return fallback;\n const trimmed = reason.trim();\n if (trimmed.length === 0 || trimmed.length > MAX_REASON_LENGTH) return fallback;\n return REASON_SHAPE.test(trimmed) ? trimmed : fallback;\n}\n\nexport interface X402ProviderOptions {\n /**\n * CAIP-2 network identifier, e.g. `eip155:84532`. The chain id it carries is\n * part of the EIP-712 domain the buyer signs, so it is read from this value\n * rather than defaulted.\n */\n readonly network: string;\n /** RPC endpoint. Local chain: http://127.0.0.1:8545 */\n readonly rpcUrl: string;\n /** ERC-20 (EIP-3009) asset address used for settlement. */\n readonly asset: `0x${string}`;\n /** EIP-712 domain name of the asset, e.g. 'MockUSDC'. */\n readonly assetName: string;\n /** EIP-712 domain version of the asset, e.g. '2'. */\n readonly assetVersion: string;\n readonly assetDecimals: number;\n /** Merchant-controlled settlement destination. Never a gateway-owned wallet. */\n readonly payTo: `0x${string}`;\n readonly maxTimeoutSeconds?: number;\n /**\n * Which facilitator verifies and broadcasts.\n *\n * `local` runs the facilitator in this process against the dev chain, and\n * its `signerPrivateKey` must be an Anvil well-known key — LOCAL DEVELOPMENT\n * ONLY — DO NOT FUND. `remote` calls an HTTP facilitator, and this gateway\n * then holds no signing key at all.\n */\n readonly facilitator: X402FacilitatorConfig;\n /**\n * Required to be `true` before anything settles on a mainnet. Never a\n * default — see `guardrails.ts`.\n */\n readonly allowMainnet?: boolean;\n /**\n * Required to be `true` to settle on a mainnet through a facilitator that\n * takes no credential. Never a default.\n */\n readonly allowUnauthenticatedFacilitator?: boolean;\n readonly logger?: Logger;\n readonly clock?: Clock;\n readonly ids?: IdGenerator;\n}\n\nconst DEFAULT_IDS: IdGenerator = {\n next: (prefix?: string) => `${prefix ? `${prefix}_` : ''}${crypto.randomUUID()}`,\n};\n\nexport function createX402PaymentProvider(options: X402ProviderOptions): PaymentProvider {\n if (!isAddress(options.asset)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `x402 provider: \"asset\" is not a valid EVM address: ${options.asset}`,\n );\n }\n if (!isAddress(options.payTo)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `x402 provider: \"payTo\" is not a valid EVM address: ${options.payTo}`,\n );\n }\n // Applies regardless of facilitator.mode — which account signs settlement\n // has no bearing on whether the destination address's private key is\n // public knowledge. `resolveX402Deployment` below covers the other half of\n // the same question: a dev payTo on any non-local *deployment*, where the\n // RPC host says nothing about where the money lands.\n assertPayToIsNotDevAddress(options.rpcUrl, options.payTo);\n if (!Number.isInteger(options.assetDecimals) || options.assetDecimals < 0) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `x402 provider: \"assetDecimals\" must be a non-negative integer`,\n );\n }\n // The chain id is not a display detail: it is signed into the buyer's\n // EIP-712 domain, so a network identifier we cannot resolve one from is a\n // startup failure, never a request-time default. `resolveX402Deployment`\n // also decides what this deployment *is* — local, testnet or mainnet — and\n // refuses every combination that could move real money by accident.\n const { profile, mode } = resolveX402Deployment({\n network: options.network,\n payTo: options.payTo,\n asset: options.asset,\n assetName: options.assetName,\n assetVersion: options.assetVersion,\n facilitator: options.facilitator,\n ...(options.allowMainnet !== undefined ? { allowMainnet: options.allowMainnet } : {}),\n ...(options.allowUnauthenticatedFacilitator !== undefined\n ? { allowUnauthenticatedFacilitator: options.allowUnauthenticatedFacilitator }\n : {}),\n });\n const network = options.network as Network;\n // Constructed once, here, rather than inside settle(): assertDevKeyIsLocalOnly\n // above already proves the key is well-formed, so privateKeyToAccount is not\n // expected to throw — but if it somehow does (or the key/RPC combination is\n // otherwise unusable), that is a *configuration* problem, and a bad key\n // should fail the provider at startup, not on the first paying customer's\n // request, after their replayKey is already reserved. This mirrors the other\n // CONFIG_INVALID checks above, which are all one-time, construction-time\n // validation rather than per-request checks.\n let binding: FacilitatorBinding;\n if (options.facilitator.mode === 'local') {\n assertDevKeyIsLocalOnly(options.rpcUrl, options.facilitator.signerPrivateKey);\n let client: LocalFacilitatorClient;\n try {\n client = createLocalFacilitatorClient(\n options.rpcUrl,\n options.facilitator.signerPrivateKey as `0x${string}`,\n );\n } catch (cause) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n 'x402 provider: could not construct a local facilitator signer from ' +\n 'facilitator.signerPrivateKey — it must be a valid 32-byte hex private key',\n { cause },\n );\n }\n binding = createLocalFacilitatorBinding(client, network, isProviderUnavailableError);\n } else {\n binding = createRemoteFacilitatorBinding({\n url: options.facilitator.url,\n auth: options.facilitator.auth,\n });\n }\n\n // health()'s own read-only client, with a real transport-level timeout (see\n // createLocalPublicClient's doc comment). Verification and settlement read\n // the chain through the facilitator signer instead, so this is the only\n // public client the provider builds.\n const healthPublicClient = createLocalPublicClient(\n options.rpcUrl,\n HEALTH_TIMEOUT_MS,\n profile.chainId,\n );\n\n const clock = options.clock ?? systemClock;\n const ids = options.ids ?? DEFAULT_IDS;\n const logger = options.logger ?? NOOP_LOGGER;\n const maxTimeoutSeconds = options.maxTimeoutSeconds ?? DEFAULT_MAX_TIMEOUT_SECONDS;\n\n const descriptor: AdapterDescriptor = {\n name: 'x402',\n kind: 'payment',\n implementationVersion: PACKAGE_VERSION,\n supportedSpec: `x402/v${X402_VERSION} scheme=exact family=eip155`,\n capabilities: [\n 'exact-evm',\n `${binding.kind}-facilitator`,\n 'eip-3009',\n 'caip-2',\n `mode=${mode}`,\n ],\n status: 'stable',\n unsupported: [\n 'svm',\n 'permit2',\n 'upto scheme',\n 'per-request signed facilitator credentials (e.g. CDP JWT)',\n ],\n };\n\n async function createRequirement(context: PaymentContext): Promise<PaymentRequirement> {\n const amount = parseCanonicalAmount(context.amount, options.assetDecimals).toString();\n\n const requirements: PaymentRequirements = {\n scheme: 'exact',\n network,\n asset: options.asset,\n amount,\n payTo: options.payTo,\n maxTimeoutSeconds,\n // `name`/`version` are what let a buyer and the facilitator build the\n // same EIP-712 domain without an on-chain `version()` call, so\n // verification stays deterministic against a token that has none.\n //\n // `assetTransferMethod` is stated rather than left to default: x402 v2's\n // `exact`/EVM scheme also has a Permit2 path, and a client that picked it\n // would produce a payload this provider cannot settle. Declaring the one\n // supported method turns that into a client-side non-choice instead of a\n // server-side rejection.\n extra: {\n name: options.assetName,\n version: options.assetVersion,\n assetTransferMethod: 'eip3009',\n },\n };\n\n // The v2 challenge document, verbatim on the wire: the HTTP adapter\n // base64-encodes this into `PAYMENT-REQUIRED`, and MCP passes it through\n // in the payment-required envelope. Built once, here, so both surfaces\n // describe the same challenge rather than each assembling their own.\n //\n // `resource.url` is descriptive metadata: nothing in the EIP-3009\n // authorisation (`from`/`to`/`value`/`validAfter`/`validBefore`/`nonce`)\n // covers it, nothing verifies against it, and the replay key is keyed on\n // the authorisation instead. It still carries `network` and `payTo` —\n // both already public in this same challenge — because the\n // `agent-commerce` authority is not reserved to us across the wider x402\n // ecosystem, so the pair is what keeps it unambiguous.\n const envelope: PaymentRequired = {\n x402Version: X402_VERSION,\n resource: {\n url: `resource://agent-commerce/${encodeURIComponent(options.network)}/${options.payTo}/resources/${encodeURIComponent(context.resource.id)}`,\n description: context.resource.description ?? context.resource.name,\n mimeType: DEFAULT_MIME_TYPE,\n },\n accepts: [requirements],\n };\n\n const expiresAt = new Date(clock.now().getTime() + maxTimeoutSeconds * 1000).toISOString();\n\n return {\n id: ids.next('payreq'),\n requestId: context.requestId,\n resourceId: context.resource.id,\n provider: 'x402',\n amount: context.amount,\n currency: context.currency,\n destination: options.payTo,\n network: options.network,\n asset: options.asset,\n expiresAt,\n challenge: {\n provider: 'x402',\n version: X402_PROTOCOL_VERSION,\n accepts: [requirements as unknown as Record<string, unknown>],\n envelope: envelope as unknown as Record<string, unknown>,\n },\n };\n }\n\n /**\n * Verifies a payment submission against a payment requirement.\n *\n * Every check below runs against *our* requirement — the one this provider\n * built and the pipeline held onto — never against `payload.accepted`, the\n * copy of the requirements the client echoes back. That echo is attacker\n * data; the SDK's scheme facilitator likewise takes the requirements as an\n * explicit argument rather than reading them off the payload.\n *\n * The amount must match **exactly**. This once accepted overpayment on the\n * reading that `amount` names a floor — but the pinned `@x402/evm@2.23.0`\n * exact/EVM scheme compares with `!==` and rejects anything else as\n * `invalid_exact_evm_payload_authorization_value_mismatch`, in both verify\n * and settle, and hosted facilitators run that same code. Accepting more\n * here only moved the rejection downstream and turned a clean\n * `wrong_amount` into an opaque SDK reason.\n */\n async function verify(context: PaymentVerificationContext): Promise<PaymentResult> {\n const { requirement, submission } = context;\n\n const rejected = (reason: string): PaymentResult => ({\n status: 'rejected',\n provider: 'x402',\n amount: requirement.amount,\n currency: requirement.currency,\n ...(requirement.network !== undefined ? { network: requirement.network } : {}),\n ...(requirement.asset !== undefined ? { asset: requirement.asset } : {}),\n rejectionReason: reason,\n });\n\n if (requirement.provider !== 'x402' || requirement.challenge.provider !== 'x402') {\n return rejected('wrong_provider');\n }\n\n const requirements = requirement.challenge.accepts[0] as PaymentRequirements | undefined;\n if (!requirements) {\n return rejected('missing_payment_requirements');\n }\n\n // Defence in depth, not the real expiry: the pipeline calls\n // createRequirement() fresh on every request, so by the time verify()\n // runs this requirement is only ever seconds old — this check will\n // essentially never fire in the current flow. The actual expiry\n // enforcement is EIP-3009's validBefore, checked inside the SDK's scheme\n // facilitator. Kept because it is cheap and correct, not because it is\n // load-bearing.\n if (\n requirement.expiresAt !== undefined &&\n Date.parse(requirement.expiresAt) < clock.now().getTime()\n ) {\n return rejected('requirement_expired');\n }\n\n // Defensive invariant: the requirement we're verifying against must still\n // describe *this* provider's configured asset. It always will in normal\n // operation (we generated it), but a corrupted/mismatched requirement\n // must never be allowed to authorise a transfer for a different asset.\n if (\n !isAddress(requirements.asset) ||\n getAddress(requirements.asset) !== getAddress(options.asset)\n ) {\n return rejected('wrong_asset');\n }\n\n const payload = decodePaymentSubmission(submission.payload);\n if (!payload) {\n return rejected('malformed_payment_payload');\n }\n if (payload.x402Version !== X402_VERSION) {\n return rejected('unsupported_x402_version');\n }\n if (!isExactEvmPayload(payload)) {\n return rejected('unsupported_scheme');\n }\n\n const { authorization } = payload.payload;\n\n if (!isAddress(authorization.from) || !isAddress(authorization.to)) {\n return rejected('malformed_payment_payload');\n }\n // The network the buyer signed for is `accepted.network` — it is what the\n // scheme derives the EIP-712 chain id from — so a mismatch here means the\n // signature is bound to a different chain than the one we settle on.\n if (payload.accepted.network !== options.network) {\n return rejected('wrong_network');\n }\n if (getAddress(authorization.to) !== getAddress(options.payTo)) {\n return rejected('wrong_recipient');\n }\n let authorizedValue: bigint;\n let required: bigint;\n try {\n authorizedValue = BigInt(authorization.value);\n required = BigInt(requirements.amount);\n } catch {\n return rejected('malformed_payment_payload');\n }\n if (authorizedValue !== required) {\n // Both directions: the scheme enforces equality, so an overpayment is\n // rejected here with a reason the buyer can act on rather than by the\n // facilitator with one they cannot.\n return rejected('wrong_amount');\n }\n\n const scope = binding.open();\n let sdkResult: VerifyResponse;\n try {\n sdkResult = await scope.verify(payload, requirements);\n } catch (err) {\n if (isProviderUnavailableError(err) || scope.transportFailed()) {\n throw new CommerceError(\n 'PAYMENT_PROVIDER_UNAVAILABLE',\n `x402 provider: ${binding.kind} facilitator unreachable during verify()`,\n {\n cause: err,\n },\n );\n }\n logger.warn({ err: describeError(err) }, 'x402 verify(): unexpected SDK error');\n return rejected('unexpected_verify_error');\n }\n\n if (!sdkResult.isValid) {\n // An RPC that never answered is not a payment that failed a check.\n if (scope.transportFailed()) {\n throw new CommerceError(\n 'PAYMENT_PROVIDER_UNAVAILABLE',\n `x402 provider: ${binding.kind} facilitator unreachable during verify()`,\n { details: { reportedReason: sdkResult.invalidReason ?? 'invalid_payment' } },\n );\n }\n // The raw string still reaches the operator's logs below; only what is\n // shown to the buyer and written to the ledger is constrained.\n if (sdkResult.invalidReason !== undefined) {\n logger.debug(\n { reportedReason: sdkResult.invalidReason },\n 'x402 verify(): facilitator rejection reason',\n );\n }\n return rejected(sanitiseReason(sdkResult.invalidReason, 'invalid_payment'));\n }\n\n // Derived from the chain id the authorisation is actually bound to, never\n // from a provider-instance constant, so the key stays correct the moment\n // there is more than one chain id in play.\n const payloadChainId = chainIdFromCaip2(payload.accepted.network);\n if (payloadChainId === undefined) {\n return rejected('wrong_network');\n }\n const replayKey = computeReplayKey({\n chainId: payloadChainId,\n asset: getAddress(requirements.asset),\n from: getAddress(authorization.from),\n nonce: authorization.nonce,\n });\n\n return {\n status: 'verified',\n provider: 'x402',\n payer: getAddress(authorization.from),\n payee: getAddress(authorization.to),\n amount: formatCanonicalAmount(authorizedValue, options.assetDecimals),\n currency: requirement.currency,\n network: payload.accepted.network,\n asset: getAddress(requirements.asset),\n replayKey,\n };\n }\n\n async function settle(context: PaymentSettlementContext): Promise<PaymentResult> {\n const { requirement, submission, verification } = context;\n\n if (verification.status !== 'verified') {\n throw new CommerceError(\n 'PAYMENT_INVALID',\n 'x402 provider: settle() called without a successful verify()',\n );\n }\n\n const requirements = requirement.challenge.accepts[0] as PaymentRequirements | undefined;\n if (!requirements) {\n throw new CommerceError(\n 'PAYMENT_INVALID',\n 'x402 provider: settle() found no payment requirements to settle against',\n );\n }\n\n const payload = decodePaymentSubmission(submission.payload);\n if (!payload || !isExactEvmPayload(payload)) {\n throw new CommerceError(\n 'PAYMENT_INVALID',\n 'x402 provider: settle() received an undecodable payment payload',\n );\n }\n\n const rejectedSettlement = (rejectionReason: string): PaymentResult => ({\n status: 'rejected',\n provider: 'x402',\n amount: verification.amount,\n currency: requirement.currency,\n ...(verification.network !== undefined ? { network: verification.network } : {}),\n ...(verification.asset !== undefined ? { asset: verification.asset } : {}),\n ...(verification.replayKey !== undefined ? { replayKey: verification.replayKey } : {}),\n rejectionReason,\n });\n\n const scope = binding.open();\n let sdkResult: SettleResponse;\n try {\n sdkResult = await scope.settle(payload, requirements);\n } catch (err) {\n if (isProviderUnavailableError(err) || scope.transportFailed()) {\n throw new CommerceError(\n 'PAYMENT_PROVIDER_UNAVAILABLE',\n `x402 provider: ${binding.kind} facilitator unreachable during settle()`,\n { cause: err },\n );\n }\n const rejectionReason = isOnChainRevertError(err)\n ? 'transaction_reverted'\n : 'unexpected_settle_error';\n logger.warn(\n { err: describeError(err), rejectionReason },\n 'x402 settle(): settlement transaction failed',\n );\n return rejectedSettlement(rejectionReason);\n }\n\n if (!sdkResult.success) {\n // \"Broadcast, never confirmed\" is not \"did not happen\": the transfer may\n // already be on-chain, so it surfaces as an *unavailable* provider\n // carrying the hash, letting the pipeline record\n // the attempt `settlement-uncertain` rather than `failed` and the payer\n // is told which transaction to check. Everything else is a real\n // rejection.\n if (sdkResult.errorReason === SETTLEMENT_PENDING_REASON || scope.transportFailed()) {\n throw new CommerceError(\n 'PAYMENT_PROVIDER_UNAVAILABLE',\n 'x402 provider: settlement was broadcast but could not be confirmed',\n {\n ...(sdkResult.transaction\n ? { details: { transactionHash: sdkResult.transaction } }\n : {}),\n },\n );\n }\n if (sdkResult.errorReason !== undefined) {\n logger.debug(\n { reportedReason: sdkResult.errorReason },\n 'x402 settle(): facilitator failure reason',\n );\n }\n return {\n ...rejectedSettlement(sanitiseReason(sdkResult.errorReason, 'settlement_failed')),\n network: sdkResult.network,\n ...(sdkResult.payer !== undefined ? { payer: sdkResult.payer } : {}),\n };\n }\n\n return {\n status: 'settled',\n provider: 'x402',\n externalReference: sdkResult.transaction,\n ...(sdkResult.payer !== undefined ? { payer: sdkResult.payer } : {}),\n payee: requirements.payTo,\n amount: verification.amount,\n currency: requirement.currency,\n network: sdkResult.network,\n ...(verification.asset !== undefined ? { asset: verification.asset } : {}),\n ...(verification.replayKey !== undefined ? { replayKey: verification.replayKey } : {}),\n settledAt: clock.nowIso(),\n };\n }\n\n async function computeHealth(): Promise<AdapterHealth> {\n const startedAt = clock.monotonicMs();\n const checkedAt = clock.nowIso();\n\n try {\n const chainId = await healthPublicClient.getChainId();\n if (chainId !== profile.chainId) {\n return {\n status: 'fail',\n detail: `RPC at ${options.rpcUrl} reports chain id ${chainId}, expected ${profile.chainId} (${profile.displayName})`,\n checkedAt,\n durationMs: clock.monotonicMs() - startedAt,\n };\n }\n\n const code = await healthPublicClient.getCode({ address: options.asset });\n if (!code || code === '0x') {\n return {\n status: 'fail',\n detail: `No contract code found at configured asset address ${options.asset}`,\n checkedAt,\n durationMs: clock.monotonicMs() - startedAt,\n };\n }\n\n if (binding.kind === 'remote') {\n // \"Reachable\" is not the question — \"will it settle *this*\" is. A\n // facilitator that is up but does not carry our scheme on our network\n // fails every payment, and does it after the buyer has signed.\n const kinds = await binding.supported();\n const supportsUs = kinds.some(\n (kind) =>\n kind.x402Version === X402_VERSION &&\n kind.scheme === 'exact' &&\n kind.network === options.network,\n );\n if (!supportsUs) {\n return {\n status: 'fail',\n detail:\n `Facilitator ${binding.describe} does not advertise x402 v${X402_VERSION} scheme=exact ` +\n `on ${options.network} (${profile.displayName}); no payment on this deployment can settle`,\n checkedAt,\n durationMs: clock.monotonicMs() - startedAt,\n };\n }\n return {\n status: 'pass',\n detail:\n `${describeDeploymentMode(mode)} — RPC ${options.rpcUrl} reachable, chain id ` +\n `${profile.chainId} (${profile.displayName}), asset ${options.asset} has code, ` +\n `facilitator ${binding.describe} supports exact/${options.network}`,\n checkedAt,\n durationMs: clock.monotonicMs() - startedAt,\n };\n }\n\n // Chain id alone cannot prove this is a dev chain: real Base Sepolia\n // reports the same id (84532) as this project's local chain, by design.\n // Probe an Anvil-only RPC method — present only on a real Anvil node —\n // before trusting a well-known dev key against it.\n const isAnvil = await probeIsAnvilNode(healthPublicClient);\n if (!isAnvil) {\n return {\n status: 'fail',\n detail:\n `RPC at ${options.rpcUrl} reports chain id ${profile.chainId} but does not answer ` +\n '\"anvil_nodeInfo\" — it does not look like a local Anvil dev node. Refusing to treat it ' +\n 'as safe for a local-facilitator dev key.',\n checkedAt,\n durationMs: clock.monotonicMs() - startedAt,\n };\n }\n\n return {\n status: 'pass',\n detail:\n `${describeDeploymentMode(mode)} — RPC ${options.rpcUrl} reachable, chain id ` +\n `${profile.chainId}, asset ${options.asset} has code, confirmed Anvil dev node`,\n checkedAt,\n durationMs: clock.monotonicMs() - startedAt,\n };\n } catch (err) {\n return {\n status: 'fail',\n detail: `x402 health check failed: ${describeError(err)}`,\n checkedAt,\n durationMs: clock.monotonicMs() - startedAt,\n };\n }\n }\n\n // /ready has no auth, no cache and no\n // rate limit, and called computeHealth() — 3 live RPC calls — on every\n // single request; measured 3x amplification of billed upstream calls\n // under an unauthenticated flood. Memoise behind a short TTL and collapse\n // concurrent callers onto one in-flight probe, so N requests within the\n // window produce at most one round-trip instead of N.\n //\n // 5s: short enough that a readiness probe (Kubernetes' own default\n // `periodSeconds` is 10s) never observes data older than its own poll\n // interval, long enough to fully decouple RPC call volume from HTTP\n // request volume — which is the property that closes the amplification,\n // not the exact number of seconds.\n //\n // pass and fail are cached for the same TTL, deliberately: a shorter TTL\n // for fail would re-introduce the amplification exactly when an upstream\n // outage makes every call expensive/slow, which is the worst possible time\n // to remove the cache's protection. 5s of recovery latency after the RPC\n // comes back is an acceptable trade — it is already within the noise of a\n // single health probe's own round-trip time, and well inside a normal\n // probe's own poll interval.\n //\n // This only memoises this provider's own RPC probe. `core` separately\n // memoises the whole /ready aggregation (src/gateway/readiness.ts)\n // — a second, independent layer at a different scope; the two compose\n // without conflict since neither assumes anything about the other's TTL.\n //\n // Does not affect `doctor`'s deployment-mismatch cross-check: that reads\n // asset/network/payTo straight from `/.well-known/agent-commerce` (static\n // provider config, echoed live, never cached), not from health().\n const HEALTH_CACHE_MS = 5_000;\n let cachedHealth: { at: number; value: AdapterHealth } | undefined;\n let inFlightHealth: Promise<AdapterHealth> | undefined;\n\n async function health(): Promise<AdapterHealth> {\n const now = clock.monotonicMs();\n if (cachedHealth && now - cachedHealth.at < HEALTH_CACHE_MS) {\n return cachedHealth.value;\n }\n if (inFlightHealth) return inFlightHealth;\n\n inFlightHealth = computeHealth()\n .then((value) => {\n cachedHealth = { at: clock.monotonicMs(), value };\n return value;\n })\n .finally(() => {\n inFlightHealth = undefined;\n });\n return inFlightHealth;\n }\n\n return {\n name: 'x402',\n descriptor,\n createRequirement,\n verify,\n settle,\n health,\n };\n}\n\nfunction isOnChainRevertError(err: unknown): boolean {\n return (\n err instanceof ContractFunctionRevertedError || err instanceof ContractFunctionExecutionError\n );\n}\n\n/**\n * `instanceof` checks first — these are the real error classes the pinned\n * viem@2.55.18 HTTP transport throws (see viem's `utils/rpc/http.js`, which\n * wraps every fetch failure, including connection-refused, in\n * `HttpRequestError` unless it is already a `TimeoutError`), plus the error\n * `waitForTransactionReceipt` itself throws when it gives up polling for a\n * receipt — precisely the \"broadcast succeeded, confirmation didn't\" case\n * this classification exists to catch. Substring matching\n * is kept only as a fallback for shapes not covered by a typed viem class\n * (e.g. a raw Node/undici error surfacing through some other path) — pinning\n * behaviour to message text is brittle across viem/undici upgrades, so the\n * instanceof checks should be preferred and grown over time as more real\n * failure shapes are seen.\n */\nfunction isProviderUnavailableError(err: unknown): boolean {\n if (\n err instanceof HttpRequestError ||\n err instanceof TimeoutError ||\n err instanceof WaitForTransactionReceiptTimeoutError\n ) {\n return true;\n }\n const message = describeError(err).toLowerCase();\n return (\n message.includes('econnrefused') ||\n message.includes('fetch failed') ||\n message.includes('enotfound') ||\n message.includes('etimedout') ||\n message.includes('timed out') ||\n message.includes('network error')\n );\n}\n\n/** Never includes secrets: only error class name + message, never raw payloads or keys. */\nfunction describeError(err: unknown): string {\n if (err instanceof Error) return `${err.name}: ${err.message}`;\n return String(err);\n}\n\n/**\n * True only when the RPC answers Anvil's own `anvil_nodeInfo` method — a\n * real network (including real Base Sepolia, which shares chain id 84532\n * with this project's local chain by design) returns a JSON-RPC \"method\n * not found\" error instead. Never throws.\n */\nasync function probeIsAnvilNode(\n client: ReturnType<typeof createLocalPublicClient>,\n): Promise<boolean> {\n // Anvil-only method: not part of viem's typed PublicRpcSchema, hence the cast.\n const request = client.request as unknown as (args: {\n method: string;\n params: unknown[];\n }) => Promise<unknown>;\n try {\n await request({ method: 'anvil_nodeInfo', params: [] });\n return true;\n } catch {\n return false;\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devlab.group/agent-commerce",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Open-source, self-hosted, non-custodial commerce and payment orchestration gateway for AI agents.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
"test:coverage": "vitest run --coverage",
|
|
67
67
|
"test:e2e": "vitest run --config vitest.e2e.config.ts",
|
|
68
68
|
"test:testnet": "vitest run --config vitest.testnet.config.ts",
|
|
69
|
+
"test:mainnet": "vitest run --config vitest.mainnet.config.ts",
|
|
69
70
|
"check:contract": "node scripts/contract-surface.mjs",
|
|
70
71
|
"check:metadata": "node scripts/check-package-metadata.mjs",
|
|
71
72
|
"verify": "npm run check:contract && npm run lint && npm run typecheck && npm test",
|
|
@@ -96,12 +97,16 @@
|
|
|
96
97
|
"zod": "3.25.76"
|
|
97
98
|
},
|
|
98
99
|
"peerDependencies": {
|
|
100
|
+
"@coinbase/x402": "2.1.0",
|
|
99
101
|
"@modelcontextprotocol/sdk": "1.30.0",
|
|
100
102
|
"@x402/core": "2.23.0",
|
|
101
103
|
"@x402/evm": "2.23.0",
|
|
102
104
|
"viem": "2.55.18"
|
|
103
105
|
},
|
|
104
106
|
"peerDependenciesMeta": {
|
|
107
|
+
"@coinbase/x402": {
|
|
108
|
+
"optional": true
|
|
109
|
+
},
|
|
105
110
|
"@modelcontextprotocol/sdk": {
|
|
106
111
|
"optional": true
|
|
107
112
|
},
|
|
@@ -116,7 +121,9 @@
|
|
|
116
121
|
}
|
|
117
122
|
},
|
|
118
123
|
"devDependencies": {
|
|
124
|
+
"@a2a-js/sdk": "1.1.0",
|
|
119
125
|
"@biomejs/biome": "2.5.9",
|
|
126
|
+
"@coinbase/x402": "2.1.0",
|
|
120
127
|
"@modelcontextprotocol/sdk": "1.30.0",
|
|
121
128
|
"@types/better-sqlite3": "9.6.0",
|
|
122
129
|
"@types/node": "24.13.3",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/payments/x402/networks.ts","../src/payments/x402/local-chain/accounts.ts","../src/payments/x402/dev-key-guard.ts","../src/payments/x402/guardrails.ts"],"names":[],"mappings":"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","file":"chunk-MQMKQGAB.js","sourcesContent":["/**\n * The networks this gateway will settle on, as data.\n *\n * x402 v2 identifies a network by its CAIP-2 id, so the only thing an\n * operator has to change to move between environments is that string. What\n * the code needs on top of it — the chain id to sign against, a name a human\n * recognises, and whether real money is involved — lives here rather than\n * being derived at each call site.\n *\n * A registry rather than \"parse any `eip155:*`\" on purpose. The chain id is\n * parseable from any such string, but `mainnet` is not, and every guardrail in\n * `guardrails.ts` keys off it. An unknown id is refused at startup instead of\n * being quietly treated as a testnet.\n *\n * Base Sepolia and the local dev chain share the id `eip155:84532`: the local\n * chain deliberately reuses Base Sepolia's chain id so the unmodified x402 SDK\n * can talk to it. Nothing may infer \"public network\" from the network id alone\n * — that is what `resolveDeploymentMode` and the Anvil probe in `provider.ts`\n * are for.\n */\nimport { CommerceError } from '../../core/index.js';\n\nexport interface NetworkProfile {\n /** CAIP-2 identifier, e.g. `eip155:84532`. */\n readonly id: string;\n /** Signed into the buyer's EIP-712 domain. */\n readonly chainId: number;\n readonly displayName: string;\n readonly kind: 'testnet' | 'mainnet';\n /**\n * The USDC deployment this network is expected to settle in. Enforced only\n * on mainnet (see `guardrails.ts`) — a testnet is where a mock token is a\n * legitimate thing to point at.\n */\n readonly canonicalAsset?: { readonly symbol: string; readonly address: string };\n}\n\nconst PROFILES: readonly NetworkProfile[] = [\n {\n id: 'eip155:84532',\n chainId: 84532,\n displayName: 'Base Sepolia',\n kind: 'testnet',\n canonicalAsset: { symbol: 'USDC', address: '0x036CbD53842c5426634e7929541eC2318f3dCF7e' },\n },\n {\n id: 'eip155:8453',\n chainId: 8453,\n displayName: 'Base',\n kind: 'mainnet',\n canonicalAsset: { symbol: 'USDC', address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' },\n },\n];\n\nconst BY_ID = new Map(PROFILES.map((profile) => [profile.id, profile]));\n\nexport const SUPPORTED_NETWORK_IDS: readonly string[] = PROFILES.map((p) => p.id);\n\nexport function findNetworkProfile(id: string): NetworkProfile | undefined {\n return BY_ID.get(id);\n}\n\nexport function requireNetworkProfile(id: string, path: string): NetworkProfile {\n const profile = BY_ID.get(id);\n if (!profile) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `${path}: \"${id}\" is not a supported network. Supported CAIP-2 identifiers: ${SUPPORTED_NETWORK_IDS.join(', ')}`,\n { details: { path, network: id } },\n );\n }\n return profile;\n}\n\n/**\n * What this deployment actually is, as opposed to what it is called.\n *\n * `local` is a property of the *facilitator*, not the network: settling\n * through the in-process facilitator against a dev node is local regardless of\n * the CAIP-2 id that node answers to. This distinction is the whole reason\n * diagnostics can say `eip155:84532` without claiming to be on public Base\n * Sepolia.\n */\nexport type DeploymentMode = 'local' | 'testnet' | 'mainnet';\n\nexport function resolveDeploymentMode(\n profile: NetworkProfile,\n facilitatorMode: 'local' | 'remote',\n): DeploymentMode {\n if (facilitatorMode === 'local') return 'local';\n return profile.kind;\n}\n\n/** The banner an operator must not be able to miss. Never printed for anything else. */\nexport const LIVE_MAINNET_BANNER = 'LIVE MAINNET MODE — REAL FUNDS';\n\nexport function describeDeploymentMode(mode: DeploymentMode): string {\n return mode === 'mainnet' ? LIVE_MAINNET_BANNER : mode.toUpperCase();\n}\n","/**\n * Anvil's well-known development accounts.\n *\n * LOCAL DEVELOPMENT ONLY — DO NOT FUND. These addresses and private keys are\n * derived from Foundry's public, well-documented default test mnemonic\n * (\"test test test test test test test test test test test junk\") and are\n * known to everyone who has ever run `anvil`. Anyone who sends real value to\n * one of these addresses on a real network will lose it.\n *\n * Index layout used by the local demo chain (see docs/contracts.md):\n * 0 — deployer / local facilitator signer (pays gas, broadcasts settlement)\n * 1 — merchant settlement destination (`payTo`)\n * 2 — buyer (signs EIP-3009 authorisations; never held by the gateway)\n */\nexport interface AnvilWellKnownAccount {\n readonly address: `0x${string}`;\n readonly privateKey: `0x${string}`;\n}\n\n/** Fixed-length tuple (not a bare array) so indexing by the documented layout above is fully typed. */\nexport const ANVIL_WELL_KNOWN_ACCOUNTS: readonly [\n AnvilWellKnownAccount,\n AnvilWellKnownAccount,\n AnvilWellKnownAccount,\n] = [\n {\n address: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',\n privateKey: '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80',\n },\n {\n address: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',\n privateKey: '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d',\n },\n {\n address: '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC',\n privateKey: '0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a',\n },\n];\n\nexport const LOCAL_FACILITATOR_ACCOUNT = ANVIL_WELL_KNOWN_ACCOUNTS[0];\nexport const LOCAL_MERCHANT_ACCOUNT = ANVIL_WELL_KNOWN_ACCOUNTS[1];\nexport const LOCAL_BUYER_ACCOUNT = ANVIL_WELL_KNOWN_ACCOUNTS[2];\n\n/** Safe label used everywhere a dev key appears in output, logs or manifests. */\nexport const DEV_KEY_LABEL = 'LOCAL DEVELOPMENT ONLY - DO NOT FUND';\n","/**\n * Prevents a well-known Anvil development private key — or a well-known\n * Anvil development *address* — from ever being used against anything other\n * than a loopback/private/dev RPC. Two symmetric mistakes, both covered:\n * signing settlement with a dev key (`assertDevKeyIsLocalOnly`), and routing\n * settlement revenue to a dev address (`assertPayToIsNotDevAddress`). The\n * second is the more consequential of the two — a wrong key merely fails to\n * sign, a wrong payTo silently succeeds and gives the money away, since the\n * private key behind every well-known Anvil address is public knowledge.\n *\n * Chain id alone cannot tell a real network from this project's local dev\n * chain: Base Sepolia's own chain id is 84532, the same id this project\n * deliberately reuses for the local chain so the unmodified x402 SDK can talk\n * to it. A dev key or dev payTo pointed at a real RPC by a config mistake is\n * instantly drainable — this is checked once at provider construction, not per\n * payment.\n */\nimport { CommerceError } from '../../core/index.js';\nimport { ANVIL_WELL_KNOWN_ACCOUNTS } from './local-chain/accounts.js';\n\nconst WELL_KNOWN_DEV_KEYS: ReadonlySet<string> = new Set(\n ANVIL_WELL_KNOWN_ACCOUNTS.map((a) => a.privateKey.toLowerCase()),\n);\n\nconst WELL_KNOWN_DEV_ADDRESSES: ReadonlySet<string> = new Set(\n ANVIL_WELL_KNOWN_ACCOUNTS.map((a) => a.address.toLowerCase()),\n);\n\n/** `0x` + 64 hex chars — the only shape `privateKeyToAccount` accepts. */\nconst PRIVATE_KEY_SHAPE = /^0x[0-9a-fA-F]{64}$/;\n\nexport function isWellKnownDevKey(privateKey: string): boolean {\n return WELL_KNOWN_DEV_KEYS.has(privateKey.toLowerCase());\n}\n\nexport function isWellKnownDevAddress(address: string): boolean {\n return WELL_KNOWN_DEV_ADDRESSES.has(address.toLowerCase());\n}\n\n/**\n * True for loopback addresses, RFC1918 private ranges, and bare (dot-free)\n * hostnames — the shape of a docker-compose/k8s service name (e.g.\n * \"anvil\"), which a real public DNS name essentially never has.\n *\n * ASSUMPTION, and the loosest edge of this guard: every dot-free, colon-free\n * hostname is treated as private, with no exceptions. A single-label *public* hostname (no dots) is\n * essentially nonexistent in practice — ICANN does not delegate bare\n * gTLDs/TLDs as public A/AAAA records — but this function cannot tell \"no\n * dots because it's a compose service name\" from \"no dots because it's an\n * unusual real host\" if one somehow existed. If that assumption ever stops\n * holding, this is the line to revisit.\n */\nexport function isLikelyLocalOrPrivateHost(hostname: string): boolean {\n const h = hostname.toLowerCase().replace(/^\\[|\\]$/g, '');\n if (h === 'localhost' || h === '127.0.0.1' || h === '::1') return true;\n if (/^127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(h)) return true;\n if (/^10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(h)) return true;\n if (/^192\\.168\\.\\d{1,3}\\.\\d{1,3}$/.test(h)) return true;\n if (/^172\\.(1[6-9]|2\\d|3[01])\\.\\d{1,3}\\.\\d{1,3}$/.test(h)) return true;\n if (!h.includes('.') && !h.includes(':')) return true; // bare hostname\n return false;\n}\n\nfunction parseHostnameOrThrow(rpcUrl: string): string {\n try {\n return new URL(rpcUrl).hostname;\n } catch (cause) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `x402 provider: rpcUrl \"${rpcUrl}\" is not a valid URL`,\n { cause },\n );\n }\n}\n\n/**\n * Throws CONFIG_INVALID if a well-known dev key would sign against a non-local\n * RPC — or if `signerPrivateKey` isn't shaped like a private key at all.\n *\n * The shape check runs first and unconditionally. \"Not a key I recognise\"\n * (falls through `isWellKnownDevKey`, silently treated as someone's own real\n * facilitator key) and \"not a key at all\" (e.g. a truncated 63-char string)\n * must never share a code path: a malformed key that slips past this guard\n * only fails later, inside `settle()`, after the buyer's replayKey is already\n * reserved.\n */\nexport function assertDevKeyIsLocalOnly(rpcUrl: string, signerPrivateKey: string): void {\n if (!PRIVATE_KEY_SHAPE.test(signerPrivateKey)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n 'x402 provider: facilitator.signerPrivateKey is not a well-formed private key ' +\n '(expected \"0x\" followed by exactly 64 hex characters).',\n );\n }\n\n if (!isWellKnownDevKey(signerPrivateKey)) return; // a real facilitator key: not our business\n\n const hostname = parseHostnameOrThrow(rpcUrl);\n\n if (!isLikelyLocalOrPrivateHost(hostname)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n 'x402 provider: facilitator.signerPrivateKey is a well-known Anvil development key, but rpcUrl ' +\n `\"${rpcUrl}\" does not look like a local/private chain. A public dev key must never sign against ` +\n 'a public network — it is instantly drainable and can grief real settlements via nonce exhaustion. ' +\n 'Use a real facilitator key for any non-local RPC, or point rpcUrl at your local/dev chain.',\n );\n }\n}\n\n/**\n * Throws CONFIG_INVALID if `payTo` (the settlement destination) is a\n * well-known Anvil development address and `rpcUrl` doesn't look\n * local/private.\n *\n * Mirrors `assertDevKeyIsLocalOnly`, but guards the *receiving* side of the\n * payment instead of the signing side, and — unlike the key guard — applies\n * regardless of facilitator mode: which account signs the settlement\n * transaction has no bearing on whether the destination address is one whose\n * private key is public knowledge. `agent-commerce init` defaults `payTo` to\n * a well-known Anvil address as a local-demo convenience; on a real network\n * that default routes every payment to an address anyone on earth can sweep.\n */\nexport function assertPayToIsNotDevAddress(rpcUrl: string, payTo: string): void {\n if (!isWellKnownDevAddress(payTo)) return; // not a dev address: not our business\n\n const hostname = parseHostnameOrThrow(rpcUrl);\n\n if (!isLikelyLocalOrPrivateHost(hostname)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `x402 provider: \"payTo\" (${payTo}) is a well-known Anvil development address, but rpcUrl ` +\n `\"${rpcUrl}\" does not look like a local/private chain. The private key behind that address ` +\n 'is public knowledge, so any revenue settled to it is immediately spendable by anyone. Set ' +\n '\"payTo\" to your own merchant wallet for any non-local RPC, or point rpcUrl at your ' +\n 'local/dev chain.',\n );\n }\n}\n","/**\n * Everything that must be true before this gateway is allowed to settle a\n * payment on the configured network.\n *\n * One definition, two callers: the provider runs it at construction so a\n * library consumer who never touches our config loader still gets the checks,\n * and `doctor` runs it against the parsed config so an operator sees the same\n * verdict without starting the gateway. Sharing a *call* is not sharing a\n * definition — the checks live here, and nothing re-implements them.\n *\n * Every failure is a startup failure. None of these are request-time\n * decisions: a deployment that is unsafe is unsafe before the first buyer\n * arrives, and finding out during `settle()` means the buyer's authorisation\n * is already burned.\n *\n * Peer-free by construction (no viem, no `@x402/*`) so the CLI can import it.\n */\nimport { CommerceError } from '../../core/index.js';\nimport { isLikelyLocalOrPrivateHost, isWellKnownDevAddress } from './dev-key-guard.js';\nimport {\n type DeploymentMode,\n type NetworkProfile,\n requireNetworkProfile,\n resolveDeploymentMode,\n} from './networks.js';\n\n/**\n * How the gateway authenticates to a remote facilitator.\n *\n * Deliberately generic: x402 facilitators are not a Coinbase-only category,\n * and a scheme that only fits one vendor's credentials would make the\n * abstraction a fiction. `bearer` covers every facilitator that takes a static\n * token; a facilitator needing per-request signed credentials (CDP's JWT among\n * them) is not supported yet and is refused rather than silently sent nothing.\n */\nexport type FacilitatorAuth =\n | { readonly type: 'none' }\n | { readonly type: 'bearer'; readonly token: string };\n\nexport type X402FacilitatorConfig =\n | { readonly mode: 'local'; readonly signerPrivateKey: string }\n | { readonly mode: 'remote'; readonly url: string; readonly auth: FacilitatorAuth };\n\nexport interface X402DeploymentInput {\n readonly network: string;\n readonly payTo: string;\n readonly asset: string;\n readonly facilitator: X402FacilitatorConfig;\n /** Required, and required to be `true`, before anything settles on a mainnet. */\n readonly allowMainnet?: boolean;\n}\n\nexport interface X402Deployment {\n readonly profile: NetworkProfile;\n readonly mode: DeploymentMode;\n}\n\nfunction invalid(message: string, path: string): CommerceError {\n return new CommerceError('CONFIG_INVALID', message, { details: { path } });\n}\n\n/**\n * Resolves the deployment and refuses every combination that could move real\n * money by accident. Order matters only in that the network must resolve\n * first; the rest are independent.\n */\nexport function resolveX402Deployment(input: X402DeploymentInput): X402Deployment {\n const profile = requireNetworkProfile(input.network, 'payments.x402.network');\n const mode = resolveDeploymentMode(profile, input.facilitator.mode);\n\n // The in-process facilitator signs with a key this process holds. On a\n // mainnet that is a hot wallet inside the resource server — the arrangement\n // this project exists to avoid — so it is not a warning, it is refused.\n if (profile.kind === 'mainnet' && input.facilitator.mode === 'local') {\n throw invalid(\n `payments.x402: network \"${profile.id}\" (${profile.displayName}) is a mainnet and cannot be served by facilitator.mode \"local\". A mainnet deployment must settle through a remote facilitator.`,\n 'payments.x402.facilitator.mode',\n );\n }\n\n if (mode === 'mainnet' && input.allowMainnet !== true) {\n throw invalid(\n `payments.x402: network \"${profile.id}\" (${profile.displayName}) settles real funds. Set payments.x402.allowMainnet: true to acknowledge this explicitly — it is never the default.`,\n 'payments.x402.allowMainnet',\n );\n }\n\n if (input.facilitator.mode === 'remote') {\n assertFacilitatorUrlIsSafe(input.facilitator.url, mode);\n if (mode === 'mainnet' && input.facilitator.auth.type === 'none') {\n throw invalid(\n 'payments.x402: a mainnet facilitator must be authenticated. Set payments.x402.facilitator.auth to a supported type — an unauthenticated production facilitator is refused.',\n 'payments.x402.facilitator.auth',\n );\n }\n if (input.facilitator.auth.type === 'bearer' && input.facilitator.auth.token.trim() === '') {\n throw invalid(\n 'payments.x402: facilitator.auth.type is \"bearer\" but the token is empty. An empty credential is refused rather than sent.',\n 'payments.x402.facilitator.auth.token',\n );\n }\n }\n\n // The private key behind every well-known Anvil address is public knowledge.\n // `dev-key-guard` already refuses one against a public *RPC*; this refuses\n // one on any non-local *deployment*, which is the case a remote facilitator\n // creates — there the RPC host says nothing about where settlement lands.\n if (mode !== 'local' && isWellKnownDevAddress(input.payTo)) {\n throw invalid(\n `payments.x402: \"payTo\" (${input.payTo}) is a well-known Anvil development address and this is a ${mode} deployment. Anyone can spend what settles there. Set payTo to your own merchant wallet.`,\n 'payments.x402.payTo',\n );\n }\n\n // Mainnet only. A testnet is exactly where pointing at a mock token is the\n // right thing to do, so the same check there would block the normal case.\n const canonical = profile.canonicalAsset;\n if (mode === 'mainnet' && canonical && !sameAddress(input.asset, canonical.address)) {\n throw invalid(\n `payments.x402: asset ${input.asset} is not ${canonical.symbol} on ${profile.displayName} (expected ${canonical.address}). Settling a mainnet payment in an unintended token is refused.`,\n 'payments.x402.asset',\n );\n }\n\n return { profile, mode };\n}\n\n/**\n * A facilitator sees every payment authorisation this gateway handles. Plain\n * HTTP to one on a public network puts those on the wire in the clear and\n * lets anyone in the path rewrite a settlement result, so it is allowed only\n * where the endpoint cannot leave the host — a local or private address.\n */\nfunction assertFacilitatorUrlIsSafe(url: string, mode: DeploymentMode): void {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch (cause) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `payments.x402: facilitator.url \"${url}\" is not a valid URL`,\n { cause, details: { path: 'payments.x402.facilitator.url' } },\n );\n }\n\n if (parsed.protocol === 'https:') return;\n if (parsed.protocol !== 'http:') {\n throw invalid(\n `payments.x402: facilitator.url must be https (or http on a local/private host); got \"${parsed.protocol}//\"`,\n 'payments.x402.facilitator.url',\n );\n }\n if (mode !== 'mainnet' && isLikelyLocalOrPrivateHost(parsed.hostname)) return;\n\n throw invalid(\n `payments.x402: facilitator.url \"${url}\" uses plain HTTP. Payment authorisations and settlement results would travel unencrypted. Use https, or point at a local/private host on a non-mainnet deployment.`,\n 'payments.x402.facilitator.url',\n );\n}\n\nfunction sameAddress(a: string, b: string): boolean {\n return a.toLowerCase() === b.toLowerCase();\n}\n"]}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* How the gateway authenticates to a remote facilitator.
|
|
3
|
-
*
|
|
4
|
-
* Deliberately generic: x402 facilitators are not a Coinbase-only category,
|
|
5
|
-
* and a scheme that only fits one vendor's credentials would make the
|
|
6
|
-
* abstraction a fiction. `bearer` covers every facilitator that takes a static
|
|
7
|
-
* token; a facilitator needing per-request signed credentials (CDP's JWT among
|
|
8
|
-
* them) is not supported yet and is refused rather than silently sent nothing.
|
|
9
|
-
*/
|
|
10
|
-
type FacilitatorAuth = {
|
|
11
|
-
readonly type: 'none';
|
|
12
|
-
} | {
|
|
13
|
-
readonly type: 'bearer';
|
|
14
|
-
readonly token: string;
|
|
15
|
-
};
|
|
16
|
-
type X402FacilitatorConfig = {
|
|
17
|
-
readonly mode: 'local';
|
|
18
|
-
readonly signerPrivateKey: string;
|
|
19
|
-
} | {
|
|
20
|
-
readonly mode: 'remote';
|
|
21
|
-
readonly url: string;
|
|
22
|
-
readonly auth: FacilitatorAuth;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export type { FacilitatorAuth as F, X402FacilitatorConfig as X };
|