@bosonprotocol/x402-server 0.1.0-alpha-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/LICENSE +201 -0
- package/README.md +65 -0
- package/dist/cjs/challenge/index.d.ts +64 -0
- package/dist/cjs/challenge/index.js +96 -0
- package/dist/cjs/challenge/index.js.map +1 -0
- package/dist/cjs/client-tnrpqVMW.d.ts +36 -0
- package/dist/cjs/config-CBr9qMps.d.ts +419 -0
- package/dist/cjs/facilitator/index.d.ts +26 -0
- package/dist/cjs/facilitator/index.js +136 -0
- package/dist/cjs/facilitator/index.js.map +1 -0
- package/dist/cjs/handlers/index.d.ts +267 -0
- package/dist/cjs/handlers/index.js +1182 -0
- package/dist/cjs/handlers/index.js.map +1 -0
- package/dist/cjs/index.d.ts +72 -0
- package/dist/cjs/index.js +1643 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/onchain/index.d.ts +73 -0
- package/dist/cjs/onchain/index.js +87 -0
- package/dist/cjs/onchain/index.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/validate/index.d.ts +67 -0
- package/dist/cjs/validate/index.js +429 -0
- package/dist/cjs/validate/index.js.map +1 -0
- package/dist/esm/challenge/index.js +3 -0
- package/dist/esm/challenge/index.js.map +1 -0
- package/dist/esm/chunk-4NQ3VKC3.js +84 -0
- package/dist/esm/chunk-4NQ3VKC3.js.map +1 -0
- package/dist/esm/chunk-CGVXQX5V.js +426 -0
- package/dist/esm/chunk-CGVXQX5V.js.map +1 -0
- package/dist/esm/chunk-DJMCSCBE.js +3 -0
- package/dist/esm/chunk-DJMCSCBE.js.map +1 -0
- package/dist/esm/chunk-EAKQ4EFZ.js +124 -0
- package/dist/esm/chunk-EAKQ4EFZ.js.map +1 -0
- package/dist/esm/chunk-GBPU373M.js +93 -0
- package/dist/esm/chunk-GBPU373M.js.map +1 -0
- package/dist/esm/chunk-PU5Y7FZG.js +14 -0
- package/dist/esm/chunk-PU5Y7FZG.js.map +1 -0
- package/dist/esm/chunk-WU7QJ7YP.js +3 -0
- package/dist/esm/chunk-WU7QJ7YP.js.map +1 -0
- package/dist/esm/chunk-Y5HFLCAT.js +657 -0
- package/dist/esm/chunk-Y5HFLCAT.js.map +1 -0
- package/dist/esm/facilitator/index.js +4 -0
- package/dist/esm/facilitator/index.js.map +1 -0
- package/dist/esm/handlers/index.js +6 -0
- package/dist/esm/handlers/index.js.map +1 -0
- package/dist/esm/index.js +261 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/onchain/index.js +4 -0
- package/dist/esm/onchain/index.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/validate/index.js +4 -0
- package/dist/esm/validate/index.js.map +1 -0
- package/package.json +88 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/onchain/web3lib-read-stub.ts","../../src/challenge/build-requirements.ts","../../src/challenge/sign-full-offer.ts","../../src/config.ts","../../src/facilitator/errors.ts","../../src/facilitator/client.ts","../../src/internal/facilitator-endpoints.ts","../../src/handlers/next-actions.ts","../../src/handlers/types.ts","../../src/validate/decode.ts","../../src/validate/payment-payload.ts","../../src/onchain/verify-exchange.ts","../../src/handlers/commit-and-redeem.ts","../../src/handlers/perform-action.ts","../../src/handlers/entity-input-validators.ts","../../src/handlers/resolve-entity.ts","../../src/handlers/withdraw-funds.ts","../../src/handlers/available-funds.ts","../../src/onchain/core-sdk-read.ts","../../src/server.ts","../../src/internal/x-payment-response.ts"],"names":["escrow","deriveInitialNextActions","escrowPaymentRequirementsSchema","exchanges","unreachable","z","addressSchema","hexSchema","evmNetworkSchema","channelRegistryZodSchema","ExchangeState","deriveNextActions","parseEscrowPaymentPayload","recoverMetaTransactionSigner","buildCreateOfferAndCommitCalldata","buildCreateOfferCommitAndRedeemCalldata","ACTION_POST_STATE","decodeSignedPayload","DECIMAL_UINT","ADDRESS","CoreSDK"],"mappings":"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","file":"index.js","sourcesContent":["// Minimal throwing `Web3LibAdapter` for the server's read-only\n// `CoreSDK` instance. The funds-subgraph and accounts-subgraph helpers\n// (`getFunds`, `getSellersByAddress`, `getBuyers`) never touch the\n// adapter at runtime, but `new CoreSDK({...})` requires one in its\n// constructor. Each method throws so any future leak into a non-read\n// path is loud rather than silent.\n\nimport type { Web3LibAdapter } from \"@bosonprotocol/common\";\n\nconst TAG = \"x402-server:read\";\n\nfunction unreachable(method: string): Error {\n return new Error(\n `${TAG}: stub Web3LibAdapter.${method}() should never be called from the read-only ` +\n `CoreSDK instance. If you see this, a non-subgraph code path leaked through.`,\n );\n}\n\nexport function createReadOnlyWeb3LibStub(): Web3LibAdapter {\n return {\n uuid: `${TAG}:stub`,\n getSignerAddress: () => Promise.reject(unreachable(\"getSignerAddress\")),\n isSignerContract: () => Promise.reject(unreachable(\"isSignerContract\")),\n getChainId: () => Promise.reject(unreachable(\"getChainId\")),\n getBalance: () => Promise.reject(unreachable(\"getBalance\")),\n estimateGas: () => Promise.reject(unreachable(\"estimateGas\")),\n sendTransaction: () => Promise.reject(unreachable(\"sendTransaction\")),\n call: () => Promise.reject(unreachable(\"call\")),\n send: () => Promise.reject(unreachable(\"send\")),\n getTransactionReceipt: () => Promise.reject(unreachable(\"getTransactionReceipt\")),\n getCurrentTimeMs: () => Promise.reject(unreachable(\"getCurrentTimeMs\")),\n };\n}\n","// 402 challenge builder — assembles an `EscrowPaymentRequirements`\n// from per-offer inputs (asset, amount, fulfillment, etc.) plus the\n// signed `BosonOfferRef` and the server's channel registry. The\n// initial `nextActions` envelope is filled via\n// `deriveInitialNextActions(registry)` so the legal transitions out\n// of `PRE_COMMIT` are always populated consistently.\n//\n// Source of truth: docs/boson-impl-01-escrow-scheme.md §2.\n\nimport { deriveInitialNextActions, type ChannelRegistry } from \"@bosonprotocol/x402-actions\";\nimport {\n escrowPaymentRequirementsSchema,\n type Address,\n type BosonOfferRef,\n type EscrowPaymentRequirements,\n type EvmNetwork,\n type FulfillmentRequirements,\n type TokenAuthStrategy,\n} from \"@bosonprotocol/x402-core/schemes/escrow\";\n\nexport interface BuildPaymentRequirementsArgs {\n /** Signed offer reference — usually from `signFullOffer`. */\n offer: BosonOfferRef;\n /** ERC-20 token address the buyer pays in. */\n asset: Address;\n /** Atomic amount as a decimal string (e.g. wei). */\n amount: string;\n /** Token-auth strategies the server is willing to accept. */\n tokenAuthStrategies: readonly TokenAuthStrategy[];\n /** Routing-only seller identifier — numeric sellerId, `did:boson:seller:N`, or wallet address. */\n recipientId: string;\n /** Upper bound for `validBefore` / `deadline` in token-auth payloads. */\n maxTimeoutSeconds: number;\n /** Optional fulfillment channel options. Absent or `{required: false}` means the server treats payment as fully atomic. */\n fulfillment?: FulfillmentRequirements;\n /** CAIP-2 network identifier (e.g. `eip155:8453`). */\n network: EvmNetwork;\n /** Boson Diamond address — same as `config.escrow`. */\n escrow: Address;\n /** Per-seller channel registry consumed by `deriveInitialNextActions`. */\n channelRegistry: ChannelRegistry;\n}\n\n/**\n * Build an `EscrowPaymentRequirements` body (the entry that lives\n * inside the 402 response's `accepts[]` array). The result is\n * round-tripped through `escrowPaymentRequirementsSchema` to fail\n * loudly if any caller-provided field violates the wire format.\n */\nexport function buildPaymentRequirements(\n args: BuildPaymentRequirementsArgs,\n): EscrowPaymentRequirements {\n const {\n offer,\n asset,\n amount,\n tokenAuthStrategies,\n recipientId,\n maxTimeoutSeconds,\n fulfillment,\n network,\n escrow,\n channelRegistry,\n } = args;\n\n const actions = deriveInitialNextActions(channelRegistry);\n\n const requirements: EscrowPaymentRequirements = {\n scheme: \"escrow\",\n network,\n asset,\n amount,\n escrowAddress: escrow,\n recipientId,\n maxTimeoutSeconds,\n offer,\n tokenAuthStrategies: [...tokenAuthStrategies],\n ...(fulfillment !== undefined ? { fulfillment } : {}),\n actions,\n };\n\n return escrowPaymentRequirementsSchema.parse(requirements) as EscrowPaymentRequirements;\n}\n","// FullOffer signer hook — produces the seller's `BosonOfferRef` from\n// an unsigned FullOffer. Delegates directly to\n// `@bosonprotocol/core-sdk`'s `exchanges.handler.signFullOffer`,\n// supplying a forwarding `Web3LibAdapter` that routes the inner\n// `eth_signTypedData_v4` RPC call to the configured `SellerSigner`.\n//\n// Routing through core-sdk keeps the typed-data shape, EIP-712 domain\n// (salt-based `Boson Protocol` / `V2`), and offer-struct\n// canonicalisation in lock-step with the deployed protocol — we don't\n// re-derive the FullOffer EIP-712 type-list on our side.\n\nimport { exchanges } from \"@bosonprotocol/core-sdk\";\nimport type { Web3LibAdapter } from \"@bosonprotocol/common\";\nimport type { UnsignedFullOffer } from \"@bosonprotocol/x402-core/eip712\";\nimport type {\n Address,\n BosonOfferRef,\n FullOffer,\n Hex,\n} from \"@bosonprotocol/x402-core/schemes/escrow\";\n\nimport type { SellerSigner } from \"../config.js\";\n\nconst STUB_CALLER_TAG = \"@bosonprotocol/x402-server:sign-full-offer\";\n\nexport interface SignFullOfferArgs {\n fullOffer: UnsignedFullOffer;\n signer: SellerSigner;\n /** Boson Diamond address — the EIP-712 `verifyingContract`. */\n escrow: Address;\n chainId: number;\n}\n\n/**\n * Sign a FullOffer via `@bosonprotocol/core-sdk`'s `signFullOffer`\n * and return a `BosonOfferRef` ready to embed in\n * `EscrowPaymentRequirements.offer`. The seller signer is plugged\n * into core-sdk via a forwarding `Web3LibAdapter` so any viem\n * `LocalAccount` / HSM / KMS signer drops in without exposing\n * core-sdk's adapter shape in this package's public API.\n *\n * ERC-1271 contract-wallet sellers: pass the wallet's address as\n * `signer.address` and route `signer.signTypedData` to whatever\n * surface the wallet exposes — the protocol's on-chain `verifyOffer`\n * runs via `EIP712Lib.verify` which already handles both ECDSA and\n * ERC-1271 recovery.\n */\nexport async function signFullOffer({\n fullOffer,\n signer,\n escrow,\n chainId,\n}: SignFullOfferArgs): Promise<BosonOfferRef> {\n const web3Lib = buildForwardingAdapter(signer, chainId);\n const result = await exchanges.handler.signFullOffer({\n fullOfferArgsUnsigned: fullOffer as unknown as Parameters<\n typeof exchanges.handler.signFullOffer\n >[0][\"fullOfferArgsUnsigned\"],\n contractAddress: escrow,\n chainId,\n web3Lib,\n });\n return {\n fullOffer: fullOffer as unknown as FullOffer,\n sellerSig: result.signature as Hex,\n creator: signer.address,\n };\n}\n\n/**\n * Build a `Web3LibAdapter` whose `send(\"eth_signTypedData_v4\", [from, json])`\n * routes to `signer.signTypedData(...)`. core-sdk's `signFullOffer`\n * path only touches `getSignerAddress`, `getChainId`, and that one\n * `send` invocation — every other adapter method rejects so a future\n * leak into a non-signing-only path is loud rather than silent.\n */\nfunction buildForwardingAdapter(signer: SellerSigner, chainId: number): Web3LibAdapter {\n const unreachable = (method: string): Promise<never> =>\n Promise.reject(\n new Error(\n `${STUB_CALLER_TAG}: Web3LibAdapter.${method}() called unexpectedly — sign-full-offer is a signing-only path.`,\n ),\n );\n\n return {\n uuid: `${STUB_CALLER_TAG}:forward`,\n getSignerAddress: () => Promise.resolve(signer.address),\n isSignerContract: () => Promise.resolve(false),\n getChainId: () => Promise.resolve(chainId),\n send: async (method, params) => {\n if (method !== \"eth_signTypedData_v4\") {\n throw new Error(`${STUB_CALLER_TAG}: unexpected RPC method: ${method}`);\n }\n const [, json] = params as [unknown, string];\n if (typeof json !== \"string\") {\n throw new Error(`${STUB_CALLER_TAG}: eth_signTypedData_v4 payload is not a JSON string`);\n }\n const td = JSON.parse(json) as {\n domain: Record<string, unknown>;\n types: Record<string, readonly { name: string; type: string }[]>;\n primaryType: string;\n message: Record<string, unknown>;\n };\n return signer.signTypedData({\n domain: td.domain,\n types: td.types,\n primaryType: td.primaryType,\n message: td.message,\n });\n },\n getBalance: () => unreachable(\"getBalance\"),\n estimateGas: () => unreachable(\"estimateGas\"),\n sendTransaction: () => unreachable(\"sendTransaction\"),\n call: () => unreachable(\"call\"),\n getTransactionReceipt: () => unreachable(\"getTransactionReceipt\"),\n getCurrentTimeMs: () => unreachable(\"getCurrentTimeMs\"),\n };\n}\n","// X402bServerConfig — the per-server context passed to\n// `createX402bServer`. The config holds everything that doesn't vary\n// per request: the network + escrow address, the seller's signer, the\n// facilitator URL (for both the future HTTP client and the public\n// advertisement embedded in `nextActions[].endpoints.facilitator`),\n// and the channel registry consumed by `deriveNextActions`.\n//\n// Per-offer values (price, asset, fulfillment, etc.) come in through\n// the per-request `buildPaymentRequirements` call instead — see\n// `./challenge/build-requirements.ts`.\n\nimport { channelRegistryZodSchema, type ChannelRegistry } from \"@bosonprotocol/x402-actions\";\nimport {\n addressSchema,\n evmNetworkSchema,\n hexSchema,\n type Address,\n type EvmNetwork,\n} from \"@bosonprotocol/x402-core/schemes/escrow\";\nimport type { Hex } from \"viem\";\nimport { z } from \"zod\";\n\nimport type { CoreSdkReadAdapter } from \"./onchain/core-sdk-read.js\";\nimport type { ExchangeReader } from \"./onchain/verify-exchange.js\";\n\n/**\n * Minimal signing surface needed by `signFullOffer`. Structurally\n * compatible with viem's `Account` (in particular `LocalAccount` from\n * `privateKeyToAccount`), but kept narrow so consumers can plug in\n * HSM- / KMS- / ERC-1271-backed signers without depending on viem's\n * internal account types.\n */\nexport interface SellerSigner {\n /** Address that the EIP-712 signature must recover to (`creator` in `BosonOfferRef`). */\n readonly address: Address;\n /** EIP-712 typed-data signer. Accepts the same shape viem's `signTypedData` does. */\n signTypedData: (params: {\n domain: Record<string, unknown>;\n types: Record<string, readonly { name: string; type: string }[]>;\n primaryType: string;\n message: Record<string, unknown>;\n }) => Promise<Hex>;\n}\n\n/**\n * Per-server configuration. Validated by `x402bServerConfigSchema` at\n * `createX402bServer` time so bad config fails fast at boot rather than\n * later inside a 402 response.\n */\nexport interface X402bServerConfig {\n /** CAIP-2 EVM network the server advertises (e.g. `eip155:8453`). */\n network: EvmNetwork;\n /** EVM chain id matching `network` — passed straight to the EIP-712 builder's salt. */\n chainId: number;\n /** Address of the Boson Diamond — the EIP-712 `verifyingContract` and the wire-level `escrowAddress`. */\n escrow: Address;\n /** Seller signer (signs the FullOffer EIP-712 typed-data). */\n signer: SellerSigner;\n /** Facilitator service the server forwards meta-tx envelopes to. The URL is also advertised in `nextActions[].endpoints.facilitator`. */\n facilitator: { url: string };\n /** Per-seller channel + endpoint registry consumed by `deriveNextActions`. */\n channelRegistry: ChannelRegistry;\n /**\n * Reader the convenience handlers use to verify the post-settle /\n * post-perform-action exchange state. Required at runtime when any\n * write handler is invoked; the `signOffer` / `buildPaymentRequirements`\n * read-only paths don't touch it. See `./onchain/verify-exchange.ts`\n * for the interface.\n */\n exchangeReader?: ExchangeReader;\n /**\n * URL of the Boson Protocol subgraph for this network. Used by the\n * read-only `available-funds` handler and the address→entityId\n * resolver shared with `withdraw-funds`. Optional at config time\n * (legacy commit/redeem handlers don't need it); required at runtime\n * by `handlers.withdrawFunds` / `handlers.getAvailableFunds`.\n */\n subgraphUrl?: string;\n /**\n * Pre-built read-only core-sdk client. If omitted, the server\n * constructs one internally from `subgraphUrl` + `escrow` + `chainId`\n * with a throwing `Web3LibAdapter` stub. Provide your own for tests\n * or when you want to share a single core-sdk instance with the\n * rest of your service.\n */\n coreSdkRead?: CoreSdkReadAdapter;\n /**\n * Server-side store of the fulfillment option ids advertised for\n * each Flow A exchange (keyed by `exchangeId`). Populated from the\n * original `PaymentRequirements` after commit verification and read\n * at redeem time so the buyer's redeem-time fulfillment choice\n * cannot switch to a channel the offer never advertised.\n *\n * Optional in the config: when omitted, `createX402bServer` wires up\n * an in-memory `Map`. Hosts running multiple instances should plug\n * in their own cross-process `Map`-shaped backing store.\n */\n exchangeFulfillmentOptionStore?: Map<string, readonly string[]>;\n /**\n * Pending fulfillment updates that reached REDEEMED on-chain but\n * failed the server-side `channel.onCommit(...)` upsert. The commit\n * handler records Flow B updates here before attempting the channel\n * write; the redeem handler does the same for Flow A. Both delete the\n * record on success and leave it behind with the error message on\n * failure so the host can replay/reconcile out of band.\n */\n fulfillmentRecoveryStore?: Map<string, FulfillmentRecoveryEntry>;\n /**\n * Fulfillment channels the server accepts at redeem time when the\n * client re-submits delivery data. Structurally a subset of\n * `@bosonprotocol/x402-fulfillment`'s `FulfillmentChannel` — only\n * `id`, `validate`, and `onCommit` are read here, so existing\n * channel instances pass through directly. Required iff a host\n * wants to accept redeem-time fulfillment updates; absent means\n * redeem requests carrying `fulfillment` are rejected with\n * `FULFILLMENT_CHANNELS_NOT_CONFIGURED`.\n */\n fulfillmentChannels?: readonly RedeemFulfillmentChannel[];\n}\n\n/**\n * Minimal structural slice of `FulfillmentChannel` the redeem\n * handler needs. Kept inline so `@bosonprotocol/x402-server` does\n * not depend on `@bosonprotocol/x402-fulfillment` (avoids a hard\n * coupling between the resource-server SDK and a specific channel\n * package); any real channel implementation is type-compatible.\n */\nexport interface RedeemFulfillmentChannel {\n readonly id: string;\n validate(data: Record<string, unknown> | null): { ok: true } | { ok: false; reason: string };\n onCommit(exchangeId: string, data: Record<string, unknown> | null): Promise<void>;\n}\n\nexport interface FulfillmentRecoveryEntry {\n exchangeId: string;\n option: string;\n data: Record<string, unknown> | null;\n redeemer: Address;\n recordedAt: number;\n error?: string;\n}\n\nconst httpUrlSchema = z\n .string()\n .url()\n .refine((url) => url.startsWith(\"http://\") || url.startsWith(\"https://\"), {\n message: \"must be an http(s) URL\",\n });\n\nconst sellerSignerSchema = z\n .object({\n address: addressSchema,\n // `SellerSigner.signTypedData` is typed `Promise<Hex>` in the TS\n // interface — tighten the zod return wrapper to match so a signer\n // that resolves to a non-hex string fails loudly at call time\n // rather than silently producing a bad `BosonOfferRef.sellerSig`.\n signTypedData: z.function().args(z.unknown()).returns(z.promise(hexSchema)),\n })\n .passthrough();\n\nconst exchangeReaderShallowSchema = z\n .object({\n read: z.function().args(z.string()).returns(z.unknown()),\n })\n .passthrough();\n\nconst coreSdkReadShallowSchema = z\n .object({\n getFunds: z.function().args(z.unknown()).returns(z.unknown()),\n getSellersByAddress: z.function().args(z.unknown()).returns(z.unknown()),\n getBuyers: z.function().args(z.unknown()).returns(z.unknown()),\n })\n .passthrough();\n\nconst fulfillmentChannelShallowSchema = z\n .object({\n id: z.string().min(1),\n validate: z.function(),\n onCommit: z.function(),\n })\n .passthrough();\n\n/**\n * zod validator for `X402bServerConfig`. Shallow on the signer +\n * exchange reader (viem account types bring their own structural\n * validators; the user-supplied reader impl is structurally typed);\n * strict on the scalar fields we own here, and on the channel\n * registry via `@bosonprotocol/x402-actions`.\n */\nexport const x402bServerConfigSchema = z\n .object({\n network: evmNetworkSchema,\n chainId: z.number().int().positive(),\n escrow: addressSchema,\n signer: sellerSignerSchema,\n facilitator: z\n .object({\n url: httpUrlSchema,\n })\n .strict(),\n channelRegistry: channelRegistryZodSchema,\n exchangeReader: exchangeReaderShallowSchema.optional(),\n subgraphUrl: httpUrlSchema.optional(),\n coreSdkRead: coreSdkReadShallowSchema.optional(),\n exchangeFulfillmentOptionStore: z.instanceof(Map).optional(),\n fulfillmentRecoveryStore: z.instanceof(Map).optional(),\n fulfillmentChannels: z\n .array(fulfillmentChannelShallowSchema)\n .superRefine((channels, ctx) => {\n // Duplicate ids would let one channel silently shadow another\n // (the redeem handler picks via `find(c => c.id === option)`).\n const seen = new Set<string>();\n const duplicates = new Set<string>();\n for (const c of channels) {\n if (seen.has(c.id)) duplicates.add(c.id);\n seen.add(c.id);\n }\n if (duplicates.size > 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `fulfillmentChannels has duplicate id(s): ${[...duplicates].join(\", \")}`,\n });\n }\n })\n .optional(),\n })\n .strict()\n .superRefine((cfg, ctx) => {\n // CAIP-2 `eip155:<chainId>` carries the chainId; assert it matches\n // the explicit `chainId` field so the EIP-712 salt and the\n // wire-level network advertisement agree. Catches the easy\n // copy-paste mistake of pairing `eip155:8453` with `chainId: 1`.\n const networkChainId = Number(cfg.network.split(\":\")[1]);\n if (networkChainId !== cfg.chainId) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"chainId\"],\n message: `chainId (${cfg.chainId}) must match network (${cfg.network})`,\n });\n }\n });\n\n/**\n * Cross-field invariant: `config.escrow` and\n * `config.channelRegistry.escrow` must agree — the Diamond address is\n * the same on both sides. Run this after `x402bServerConfigSchema.parse`.\n */\nexport function assertChannelRegistryEscrowMatch(config: X402bServerConfig): void {\n if (config.escrow.toLowerCase() !== config.channelRegistry.escrow.toLowerCase()) {\n throw new Error(\n `x402-server config: escrow (${config.escrow}) does not match channelRegistry.escrow (${config.channelRegistry.escrow})`,\n );\n }\n}\n","// Typed error class for HTTP-level facilitator failures. Distinct from\n// the `{ ok: false, code }` shape the facilitator itself returns —\n// those are domain errors and surface in the typed result. This class\n// is thrown only when the HTTP transport fails (network error,\n// non-2xx response with an unparseable body, etc.).\n\nimport type { FacilitatorErrorCode } from \"@bosonprotocol/x402-facilitator\";\n\n/**\n * Stable, x402-server-side codes for HTTP-transport failures.\n * Distinct from the facilitator-side `FacilitatorErrorCode` enum so\n * callers can branch on \"the facilitator answered with X\" vs \"we\n * never reached the facilitator\".\n */\nexport type FacilitatorHttpErrorCode =\n | \"NETWORK_ERROR\"\n | \"BAD_HTTP_STATUS\"\n | \"BAD_RESPONSE_BODY\"\n | \"TIMEOUT\";\n\n/** Network- or transport-layer failure when calling the facilitator. */\nexport class FacilitatorHttpError extends Error {\n readonly code: FacilitatorHttpErrorCode;\n readonly status?: number;\n /** Original facilitator-side error code, if the body parsed cleanly. */\n readonly facilitatorCode?: FacilitatorErrorCode;\n\n constructor(\n message: string,\n init: {\n code: FacilitatorHttpErrorCode;\n status?: number;\n facilitatorCode?: FacilitatorErrorCode;\n cause?: unknown;\n },\n ) {\n super(message, init.cause !== undefined ? { cause: init.cause } : undefined);\n this.name = \"FacilitatorHttpError\";\n this.code = init.code;\n if (init.status !== undefined) this.status = init.status;\n if (init.facilitatorCode !== undefined) this.facilitatorCode = init.facilitatorCode;\n }\n}\n","// HTTP client for the Boson facilitator service. The facilitator runs\n// as a remote process implementing the three endpoints in\n// docs/boson-impl-07-facilitator.md (`/verify`, `/settle`,\n// `/perform-action?action=<action>`); this module wraps `fetch` with the typed\n// request/response shapes exported by `@bosonprotocol/x402-facilitator`.\n//\n// Domain results (`{ ok: true, ... }` or `{ ok: false, code, reason }`)\n// are returned verbatim — both shapes are answers the caller branches\n// on. The facilitator-express adapter emits domain failures over HTTP\n// 400 (so curl users still see a 4xx), but the wire body is still a\n// well-formed result; we recognise that shape on HTTP 400 responses and\n// hand it back rather than throwing. HTTP-transport failures (network\n// down, non-JSON body, schema-mismatched body) throw\n// `FacilitatorHttpError` so the composition layer can distinguish\n// \"facilitator said no\" from \"we couldn't reach the facilitator\".\n\nimport type {\n FacilitatorErrorCode,\n FacilitatorPerformActionInput,\n FacilitatorPerformActionResult,\n FacilitatorSettleInput,\n FacilitatorSettleResult,\n FacilitatorVerifyInput,\n FacilitatorVerifyResult,\n} from \"@bosonprotocol/x402-facilitator\";\n\nimport { FacilitatorHttpError } from \"./errors.js\";\n\nexport type FetchLike = (\n input: string,\n init?: { method?: string; headers?: Record<string, string>; body?: string },\n) => Promise<{\n ok: boolean;\n status: number;\n text: () => Promise<string>;\n json?: () => Promise<unknown>;\n}>;\n\nexport interface CreateFacilitatorClientOptions {\n /** Base URL of the facilitator service (no trailing slash needed). */\n url: string;\n /** Optional `fetch` override — defaults to the global `fetch`. Useful for tests + non-`fetch` runtimes. */\n fetch?: FetchLike;\n /** Optional headers attached to every request — e.g. an `Authorization` for hosted facilitators. */\n headers?: Record<string, string>;\n}\n\nexport interface FacilitatorClient {\n verify(input: FacilitatorVerifyInput): Promise<FacilitatorVerifyResult>;\n settle(input: FacilitatorSettleInput): Promise<FacilitatorSettleResult>;\n performAction(input: FacilitatorPerformActionInput): Promise<FacilitatorPerformActionResult>;\n}\n\n/**\n * Construct a typed HTTP client for the facilitator. The returned\n * methods stringify the input as JSON and POST to the matching path\n * on the configured URL. Bodies matching the well-formed result shape\n * (whether HTTP 2xx success or HTTP 400 domain rejection) are returned\n * verbatim; transport failures (network, non-JSON body,\n * schema-mismatched body) raise `FacilitatorHttpError`.\n */\nexport function createFacilitatorClient(opts: CreateFacilitatorClientOptions): FacilitatorClient {\n const fetchImpl = opts.fetch ?? (globalThis.fetch as FetchLike | undefined);\n if (fetchImpl === undefined) {\n throw new Error(\n \"createFacilitatorClient: no `fetch` implementation available. Pass `opts.fetch` explicitly.\",\n );\n }\n const baseUrl = opts.url.replace(/\\/+$/, \"\");\n const baseHeaders = { \"content-type\": \"application/json\", ...(opts.headers ?? {}) };\n\n const post = async <Req, Res>(\n path: string,\n body: Req,\n validate: (parsed: unknown) => parsed is Res,\n ): Promise<Res> => {\n let res: Awaited<ReturnType<FetchLike>>;\n try {\n res = await fetchImpl(`${baseUrl}${path}`, {\n method: \"POST\",\n headers: baseHeaders,\n body: JSON.stringify(body),\n });\n } catch (cause) {\n throw new FacilitatorHttpError(`facilitator network error (${path})`, {\n code: \"NETWORK_ERROR\",\n cause,\n });\n }\n\n let text: string;\n try {\n text = await res.text();\n } catch (cause) {\n throw new FacilitatorHttpError(`facilitator response body could not be read (${path})`, {\n code: \"BAD_RESPONSE_BODY\",\n status: res.status,\n cause,\n });\n }\n\n let parsed: unknown;\n try {\n parsed = text.length === 0 ? null : JSON.parse(text);\n } catch (cause) {\n throw new FacilitatorHttpError(`facilitator returned non-JSON body (${path})`, {\n code: \"BAD_RESPONSE_BODY\",\n status: res.status,\n cause,\n });\n }\n\n if (!res.ok) {\n // The facilitator-express adapter returns domain failures as\n // HTTP 400 with the `{ok:false, code, reason}` body. Detect that\n // shape and surface it as the typed result — every endpoint's\n // `Res` union includes the same `{ok:false, code, reason}`\n // variant, so the cast through `validate` (which also accepts\n // that shape) preserves type-safety. Any other non-2xx status is\n // a genuine transport failure even if its body happens to look\n // like a facilitator result.\n if (res.status === 400 && isFailureBranch(parsed) && validate(parsed)) {\n return parsed;\n }\n const facilitatorCode = extractFacilitatorCode(parsed);\n throw new FacilitatorHttpError(\n `facilitator HTTP ${res.status} (${path}): ${reasonString(parsed) ?? text}`,\n {\n code: \"BAD_HTTP_STATUS\",\n status: res.status,\n ...(facilitatorCode !== undefined ? { facilitatorCode } : {}),\n },\n );\n }\n\n if (!validate(parsed)) {\n throw new FacilitatorHttpError(`facilitator returned unexpected body shape (${path})`, {\n code: \"BAD_RESPONSE_BODY\",\n status: res.status,\n });\n }\n return parsed;\n };\n\n return {\n verify: (input) =>\n post<FacilitatorVerifyInput, FacilitatorVerifyResult>(\"/verify\", input, isVerifyResult),\n settle: (input) =>\n post<FacilitatorSettleInput, FacilitatorSettleResult>(\"/settle\", input, isSettleResult),\n performAction: (input) =>\n post<FacilitatorPerformActionInput, FacilitatorPerformActionResult>(\n `/perform-action?action=${encodeURIComponent(input.action)}`,\n input,\n isPerformActionResult,\n ),\n };\n}\n\n// --- Response-shape type guards ----------------------------------------\n//\n// A buggy or malicious facilitator could return any 2xx JSON; without a\n// runtime check, `parsed as Res` would silently slip an unexpected shape\n// past the type system and the convenience handlers (PR 4) would\n// dereference fields that aren't there. These guards mirror the\n// discriminated unions in `@bosonprotocol/x402-facilitator`'s types and\n// fail any response that doesn't fit — surfaced as\n// `BAD_RESPONSE_BODY` so the caller treats it as a transport-layer\n// failure rather than a domain answer.\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return v !== null && typeof v === \"object\";\n}\n\n/**\n * Failure branch is identical across all three endpoints. Accepts\n * `unknown` so the non-2xx path can pre-check the parsed body without\n * narrowing first.\n */\nfunction isFailureBranch(v: unknown): v is { ok: false; code: string; reason: string } {\n return (\n isObject(v) && v.ok === false && typeof v.code === \"string\" && typeof v.reason === \"string\"\n );\n}\n\nfunction isVerifyResult(parsed: unknown): parsed is FacilitatorVerifyResult {\n if (!isObject(parsed)) return false;\n if (parsed.ok === true) return true; // `{ ok: true }` carries no further fields\n return isFailureBranch(parsed);\n}\n\nfunction isSettleResult(parsed: unknown): parsed is FacilitatorSettleResult {\n if (!isObject(parsed)) return false;\n if (parsed.ok === true) {\n return typeof parsed.exchangeId === \"string\" && typeof parsed.txHash === \"string\";\n }\n return isFailureBranch(parsed);\n}\n\nfunction isPerformActionResult(parsed: unknown): parsed is FacilitatorPerformActionResult {\n if (!isObject(parsed)) return false;\n if (parsed.ok === true) {\n if (typeof parsed.txHash !== \"string\") return false;\n // Entity-keyed actions (e.g. `boson-withdrawFunds`) return just\n // `{ ok: true, txHash }` — no exchange state transition. Accept\n // that shape; only require `newExchangeState` when present.\n if (parsed.newExchangeState !== undefined && typeof parsed.newExchangeState !== \"string\") {\n return false;\n }\n if (parsed.newDisputeState !== undefined && typeof parsed.newDisputeState !== \"string\") {\n return false;\n }\n return true;\n }\n return isFailureBranch(parsed);\n}\n\nfunction extractFacilitatorCode(body: unknown): FacilitatorErrorCode | undefined {\n if (body === null || typeof body !== \"object\") return undefined;\n const code = (body as { code?: unknown }).code;\n return typeof code === \"string\" ? (code as FacilitatorErrorCode) : undefined;\n}\n\nfunction reasonString(body: unknown): string | undefined {\n if (body === null || typeof body !== \"object\") return undefined;\n const reason = (body as { reason?: unknown }).reason;\n return typeof reason === \"string\" ? reason : undefined;\n}\n","// Helpers for stamping `endpoints.facilitator` on every `NextAction`\n// entry that advertises the `facilitator` channel. Used both at the\n// 402 challenge (pre-commit `EscrowPaymentRequirements.actions.next`)\n// and on every post-commit `EscrowNextActions` envelope a handler\n// returns — keeping the URL-shape logic in one place so the two\n// surfaces can't drift.\n\nimport type { NextAction } from \"@bosonprotocol/x402-core/schemes/escrow\";\n\nconst COMMIT_ACTION_IDS = new Set([\n \"boson-createOfferAndCommit\",\n \"boson-createOfferCommitAndRedeem\",\n]);\n\n/**\n * Pick the facilitator endpoint URL for a given action id. Commit-time\n * actions route to `/settle`; every other action routes to\n * `/perform-action?action=<id>` so the facilitator can dispatch per\n * action without re-parsing the meta-tx calldata.\n */\nexport function facilitatorEndpointFor(actionId: string, facilitatorUrl: string): string {\n const base = facilitatorUrl.replace(/\\/+$/, \"\");\n if (COMMIT_ACTION_IDS.has(actionId)) {\n return `${base}/settle`;\n }\n return `${base}/perform-action?action=${encodeURIComponent(actionId)}`;\n}\n\n/**\n * Return a new `NextAction[]` with `endpoints.facilitator` stamped on\n * every entry that advertises the `facilitator` channel. Entries that\n * already carry an explicit `endpoints.facilitator` are left as-is\n * (the caller wins) — same for entries whose `channels` don't include\n * `\"facilitator\"`.\n */\nexport function stampFacilitatorEndpoints(\n next: readonly NextAction[],\n facilitatorUrl: string,\n): NextAction[] {\n return next.map((entry) => {\n if (!entry.channels.includes(\"facilitator\")) {\n return entry;\n }\n if (entry.endpoints?.facilitator !== undefined) {\n return entry;\n }\n return {\n ...entry,\n endpoints: {\n ...entry.endpoints,\n facilitator: facilitatorEndpointFor(entry.id, facilitatorUrl),\n },\n };\n });\n}\n","// `emitNextActions` — thin wrapper over `deriveNextActions` from\n// `@bosonprotocol/x402-actions`. Stamps the seller's per-action\n// `endpoints` / `channels` from the configured `ChannelRegistry`,\n// returns the discriminated `EscrowNextActions` shape (post-commit)\n// every convenience handler attaches to its response body.\n//\n// When the caller passes `facilitatorUrl`, the wrapper additionally\n// stamps `endpoints.facilitator` on every entry whose `channels`\n// include `\"facilitator\"` — matching the pre-commit behaviour in\n// `server.buildPaymentRequirements`. Without that stamp the buyer\n// sees `facilitator` advertised in `channels` but no URL to hit; the\n// channel is effectively dead.\n\nimport {\n deriveNextActions,\n DisputeState,\n ExchangeState,\n type ChannelRegistry,\n type EscrowNextActions,\n} from \"@bosonprotocol/x402-actions\";\n\nimport { stampFacilitatorEndpoints } from \"../internal/facilitator-endpoints.js\";\n\nexport type EmitNextActionsInput = {\n exchangeId: string;\n} & (\n | { exchangeState: Exclude<ExchangeState, typeof ExchangeState.DISPUTED>; disputeState?: never }\n | { exchangeState: typeof ExchangeState.DISPUTED; disputeState: DisputeState }\n);\n\n/**\n * Build the `nextActions` envelope a handler attaches to its 200 body.\n * Pure wrapper; the logic beyond `deriveNextActions` is the\n * `DISPUTED → disputeState required` narrowing and the optional\n * facilitator-endpoint stamp.\n */\nexport function emitNextActions(\n input: EmitNextActionsInput,\n registry: ChannelRegistry,\n facilitatorUrl?: string,\n): EscrowNextActions {\n const derived =\n input.exchangeState === ExchangeState.DISPUTED\n ? deriveNextActions(\n {\n exchangeId: input.exchangeId,\n exchangeState: ExchangeState.DISPUTED,\n disputeState: input.disputeState,\n },\n registry,\n )\n : deriveNextActions(\n { exchangeId: input.exchangeId, exchangeState: input.exchangeState },\n registry,\n );\n\n if (facilitatorUrl === undefined) {\n return derived;\n }\n\n return {\n ...derived,\n next: stampFacilitatorEndpoints(derived.next, facilitatorUrl),\n };\n}\n","// Shared result + error shapes for every convenience handler.\n//\n// Each handler returns a `HandlerResult<TBody>` whose `ok: true`\n// variant carries an HTTP-200 body augmented with the `nextActions`\n// envelope, and whose `ok: false` variant carries the suggested HTTP\n// status + a structured error body the framework adapter (PR 5) can\n// serialise into the response.\n\nimport type { EscrowNextActions } from \"@bosonprotocol/x402-actions\";\n\nexport type HandlerStatus = 200 | 400 | 402 | 404 | 409 | 500 | 502;\n\nexport type HandlerResult<TBody> =\n | { ok: true; status: 200; body: TBody & { nextActions: EscrowNextActions } }\n | { ok: false; status: Exclude<HandlerStatus, 200>; body: HandlerErrorBody };\n\n/**\n * Result shape for handlers whose success body does NOT carry a\n * `nextActions` envelope — used by entity-keyed actions\n * (`boson-withdrawFunds`) and the read-only `available-funds`\n * endpoint, neither of which advance the exchange state machine.\n */\nexport type PlainHandlerResult<TBody> =\n | { ok: true; status: 200; body: TBody }\n | { ok: false; status: Exclude<HandlerStatus, 200>; body: HandlerErrorBody };\n\nexport interface HandlerErrorBody {\n /** Stable identifier — caller branches on this rather than the human-readable `reason`. */\n code: string;\n reason: string;\n /** Optional rich detail — validator field/expected/got, facilitator code, etc. */\n details?: unknown;\n}\n\nexport interface HandlerWarning {\n /** Stable identifier — caller branches on this rather than the human-readable `reason`. */\n code: string;\n reason: string;\n /** Optional rich detail — tx hash, exchange id, deferred operation, etc. */\n details?: unknown;\n}\n\nexport function handlerOk<TBody>(\n body: TBody & { nextActions: EscrowNextActions },\n): HandlerResult<TBody> {\n return { ok: true, status: 200, body };\n}\n\nexport function plainHandlerOk<TBody>(body: TBody): PlainHandlerResult<TBody> {\n return { ok: true, status: 200, body };\n}\n\nexport function handlerErr(\n status: Exclude<HandlerStatus, 200>,\n code: string,\n reason: string,\n details?: unknown,\n): HandlerResult<never> & PlainHandlerResult<never> {\n const body: HandlerErrorBody = { code, reason };\n if (details !== undefined) body.details = details;\n return { ok: false, status, body };\n}\n","// Decode the `X-PAYMENT` header — base64 → JSON → zod-parse.\n//\n// `parseEscrowPaymentPayload` from `@bosonprotocol/x402-core` handles\n// the wire-format zod validation; this module's job is the base64 +\n// JSON layer plus the obvious \"not a string\" / \"bad base64\" / \"bad\n// JSON\" failure cases, each mapped to a structured error code so the\n// caller can surface a useful 400 to the buyer.\n\nimport {\n parseEscrowPaymentPayload,\n type EscrowPaymentPayload,\n} from \"@bosonprotocol/x402-core/schemes/escrow\";\n\nexport type DecodeXPaymentResult =\n | { ok: true; payload: EscrowPaymentPayload }\n | { ok: false; code: DecodeErrorCode; reason: string };\n\nexport type DecodeErrorCode =\n | \"MISSING_HEADER\"\n | \"INVALID_BASE64\"\n | \"INVALID_JSON\"\n | \"INVALID_PAYLOAD\";\n\n/**\n * Decode the raw `X-PAYMENT` header value. Returns the parsed\n * `EscrowPaymentPayload` on success or a `{ ok: false }` discriminated\n * error on failure. Accepts both base64 and base64url variants (RFC\n * 4648 §5) — buyers in the wild use both.\n */\nexport function decodeXPaymentHeader(header: string | undefined | null): DecodeXPaymentResult {\n if (header === undefined || header === null || header.length === 0) {\n return { ok: false, code: \"MISSING_HEADER\", reason: \"X-PAYMENT header is missing\" };\n }\n\n // base64url → base64 (RFC 4648 §5) then decode. We prefer `atob` so\n // the validator stays edge-runtime compatible; `atob` returns a\n // Latin-1 binary string though, so we re-encode through `TextDecoder`\n // to recover the original UTF-8 (atomic Flow B's `fulfillment.data`\n // can carry non-ASCII bytes — names, addresses, free-form notes —\n // and so can other buyer-supplied inner fields).\n const padded = base64UrlToBase64(header);\n let decoded: string;\n try {\n if (typeof atob === \"function\") {\n const binary = atob(padded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i += 1) bytes[i] = binary.charCodeAt(i);\n decoded = new TextDecoder().decode(bytes);\n } else {\n decoded = Buffer.from(padded, \"base64\").toString(\"utf8\");\n }\n } catch (e) {\n return { ok: false, code: \"INVALID_BASE64\", reason: (e as Error).message };\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(decoded);\n } catch (e) {\n return { ok: false, code: \"INVALID_JSON\", reason: (e as Error).message };\n }\n\n try {\n const payload = parseEscrowPaymentPayload(parsed);\n return { ok: true, payload };\n } catch (e) {\n return { ok: false, code: \"INVALID_PAYLOAD\", reason: (e as Error).message };\n }\n}\n\nfunction base64UrlToBase64(input: string): string {\n const normalized = input.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padding = normalized.length % 4 === 0 ? \"\" : \"=\".repeat(4 - (normalized.length % 4));\n return normalized + padding;\n}\n","// `validatePaymentPayload` — the 13-rule X-PAYMENT validator from\n// docs/boson-impl-01-escrow-scheme.md §5. Pure function; no I/O.\n//\n// The validator returns a discriminated `{ ok: true } | { ok: false, … }`\n// result. On failure, the result carries the spec's rule number, a\n// stable string code, and the field/expected/got triple from the spec\n// (so callers can serialise it directly into a 400 body).\n//\n// Rule 12 (`none` strategy → server SHOULD pre-flight allowance check)\n// is RPC-dependent and intentionally NOT enforced here — the\n// composition layer (PR 4) runs it as part of `verifyExchange`.\n//\n// Rule 7 byte-compares `payload.metaTx.functionSignature` against\n// calldata reconstructed from `payload.offerRef`. Both commit-time\n// actions are supported: `boson-createOfferAndCommit` (Flow A) and\n// `boson-createOfferCommitAndRedeem` (Flow B).\n\nimport { recoverMetaTransactionSigner } from \"@bosonprotocol/x402-core/eip712\";\nimport type {\n EscrowPaymentPayload,\n EscrowPaymentRequirements,\n FulfillmentOption,\n} from \"@bosonprotocol/x402-core/schemes/escrow\";\nimport {\n buildCreateOfferAndCommitCalldata,\n buildCreateOfferCommitAndRedeemCalldata,\n} from \"@bosonprotocol/x402-evm\";\nimport type { Address as ViemAddress, Hex as ViemHex } from \"viem\";\n\ntype BuilderFullOffer = Parameters<typeof buildCreateOfferAndCommitCalldata>[0][\"fullOffer\"];\n\nexport type ValidatePaymentPayloadResult =\n | { ok: true; warnings?: ValidationWarning[] }\n | {\n ok: false;\n rule: number;\n code: ValidationErrorCode;\n field?: string;\n expected?: unknown;\n got?: unknown;\n reason?: string;\n };\n\nexport type ValidationErrorCode =\n | \"SCHEME_MISMATCH\"\n | \"NETWORK_MISMATCH\"\n | \"FULL_OFFER_MISMATCH\"\n | \"SELLER_SIG_MISMATCH\"\n | \"ACTION_NOT_IN_REQUIREMENTS\"\n | \"TOKEN_AUTH_NOT_IN_REQUIREMENTS\"\n | \"CALLDATA_MISMATCH\"\n | \"BAD_META_TX_SIGNATURE\"\n | \"TOKEN_AUTH_AMOUNT_MISMATCH\"\n | \"TOKEN_AUTH_RECIPIENT_MISMATCH\"\n | \"TOKEN_AUTH_SPENDER_MISMATCH\"\n | \"TOKEN_AUTH_TOKEN_MISMATCH\"\n | \"TOKEN_AUTH_DEADLINE_EXCEEDED\"\n | \"TOKEN_AUTH_MISSING\"\n | \"TOKEN_AUTH_UNEXPECTED\"\n | \"TOKEN_AUTH_UNKNOWN_STRATEGY\"\n | \"FULFILLMENT_REQUIRED\"\n | \"FULFILLMENT_OPTION_NOT_ADVERTISED\"\n | \"FULFILLMENT_DATA_REQUIRED\"\n | \"FULFILLMENT_DATA_UNEXPECTED\"\n | \"FULFILLMENT_DATA_INVALID\";\n\nexport interface ValidationWarning {\n rule: number;\n code: \"RULE_SKIPPED\";\n reason: string;\n}\n\nexport interface ValidatePaymentPayloadArgs {\n payload: EscrowPaymentPayload;\n requirements: EscrowPaymentRequirements;\n /** EVM chain id matching `requirements.network` — drives meta-tx EIP-712 signer recovery (rule 8). */\n chainId: number;\n /** Reference time in seconds since epoch for rules 9–11. Defaults to `Math.floor(Date.now() / 1000)`. */\n now?: number;\n /**\n * Per-fulfillment-option data validator (typically the\n * `FulfillmentRegistry`'s per-channel `validate`). Only consulted for\n * atomic Flow B (`boson-createOfferCommitAndRedeem`) where the buyer\n * must carry `fulfillment.data` in the commit-time payload — Flow A\n * defers data to the redeem POST body and rule 13 rejects any\n * commit-time `data` there outright. Without this validator, Flow B\n * still rejects missing data but does not deep-validate the data\n * against the option's schema.\n */\n validateFulfillmentData?: (\n option: string,\n data: Record<string, unknown> | null,\n ) => { ok: true } | { ok: false; reason: string };\n}\n\n/**\n * Run all 13 rules. Short-circuits at the first failure.\n */\nexport async function validatePaymentPayload(\n args: ValidatePaymentPayloadArgs,\n): Promise<ValidatePaymentPayloadResult> {\n const { payload, requirements } = args;\n // Rule 1 — scheme equality on both sides.\n if (payload.scheme !== \"escrow\" || requirements.scheme !== \"escrow\") {\n return failure(1, \"SCHEME_MISMATCH\", \"scheme\", \"escrow\", payload.scheme);\n }\n\n // Rule 2 — network equality.\n if (payload.network !== requirements.network) {\n return failure(2, \"NETWORK_MISMATCH\", \"network\", requirements.network, payload.network);\n }\n\n // Rule 3 — fullOffer deep equality (byte-equals in canonical form).\n if (!deepEqual(payload.payload.offerRef.fullOffer, requirements.offer.fullOffer)) {\n return failure(\n 3,\n \"FULL_OFFER_MISMATCH\",\n \"payload.offerRef.fullOffer\",\n \"<requirements.offer.fullOffer>\",\n \"<payload.offerRef.fullOffer>\",\n );\n }\n\n // Rule 4 — sellerSig equality.\n if (payload.payload.offerRef.sellerSig !== requirements.offer.sellerSig) {\n return failure(\n 4,\n \"SELLER_SIG_MISMATCH\",\n \"payload.offerRef.sellerSig\",\n requirements.offer.sellerSig,\n payload.payload.offerRef.sellerSig,\n );\n }\n\n // Rule 5 — action advertised in requirements.actions.next.\n const advertisedActions = requirements.actions.next.map((entry) => entry.id);\n if (!advertisedActions.includes(payload.payload.action)) {\n return failure(\n 5,\n \"ACTION_NOT_IN_REQUIREMENTS\",\n \"payload.action\",\n advertisedActions,\n payload.payload.action,\n );\n }\n\n // Rule 6 — tokenAuthStrategy advertised in requirements.tokenAuthStrategies.\n if (!requirements.tokenAuthStrategies.includes(payload.payload.tokenAuthStrategy)) {\n return failure(\n 6,\n \"TOKEN_AUTH_NOT_IN_REQUIREMENTS\",\n \"payload.tokenAuthStrategy\",\n requirements.tokenAuthStrategies,\n payload.payload.tokenAuthStrategy,\n );\n }\n\n // Rule 7 — functionSignature byte-equals the calldata reconstructed\n // from offerRef. Both commit-time actions are validated.\n const calldataResult = await checkFunctionSignatureAndCalldataEquality(payload);\n if (calldataResult !== null) return calldataResult;\n\n // Rule 8 — meta-tx signer recovers to payload.buyer === metaTx.from.\n if (payload.payload.buyer.toLowerCase() !== payload.payload.metaTx.from.toLowerCase()) {\n return failure(\n 8,\n \"BAD_META_TX_SIGNATURE\",\n \"payload.metaTx.from\",\n payload.payload.buyer,\n payload.payload.metaTx.from,\n );\n }\n let recovered: ViemAddress;\n try {\n recovered = await recoverMetaTransactionSigner({\n chainId: args.chainId,\n verifyingContract: requirements.escrowAddress as ViemAddress,\n message: {\n nonce: BigInt(payload.payload.metaTx.nonce),\n from: payload.payload.metaTx.from as ViemAddress,\n contractAddress: requirements.escrowAddress as ViemAddress,\n functionName: payload.payload.metaTx.functionName,\n functionSignature: payload.payload.metaTx.functionSignature as ViemHex,\n },\n signature: encodeRsv(payload.payload.metaTx.sig) as ViemHex,\n });\n } catch (e) {\n return failure(\n 8,\n \"BAD_META_TX_SIGNATURE\",\n \"payload.metaTx.sig\",\n \"recoverable ECDSA signature\",\n payload.payload.metaTx.sig,\n (e as Error).message,\n );\n }\n if (recovered.toLowerCase() !== payload.payload.buyer.toLowerCase()) {\n return failure(\n 8,\n \"BAD_META_TX_SIGNATURE\",\n \"payload.metaTx.sig\",\n payload.payload.buyer,\n recovered,\n );\n }\n\n // Rules 9–11 — strategy-specific token-auth structural checks.\n const strategyResult = checkTokenAuthRules(payload, requirements, args.now);\n if (strategyResult !== null) return strategyResult;\n\n // Rule 12 — `none` strategy SHOULD pre-flight `IERC20.allowance` on\n // chain. Intentionally not enforced here; runs as part of\n // `verifyExchange` in PR 4 (RPC dependency).\n\n // Rule 13 — fulfillment option + action-conditional data presence.\n // Flow A (`boson-createOfferAndCommit`) defers buyer-supplied data\n // to the redeem POST body; `fulfillment.data` must NOT appear in the\n // commit-time payload. Flow B (`boson-createOfferCommitAndRedeem`)\n // has only one round trip, so `fulfillment.data` MUST be present\n // (validated against the option's JSON Schema when a per-channel\n // validator is configured).\n const fulfillmentResult = checkFulfillment(payload, requirements, args.validateFulfillmentData);\n if (fulfillmentResult !== null) return fulfillmentResult;\n\n return { ok: true };\n}\n\n/**\n * Validate that `payload.metaTx.functionName` + `functionSignature`\n * byte-equal the calldata reconstructed from the payload's\n * `offerRef.fullOffer` + `sellerSig`. Tracks spec rule 7 today;\n * named for what it checks rather than its rule number so the\n * function survives any future renumbering of the spec.\n */\nasync function checkFunctionSignatureAndCalldataEquality(\n payload: EscrowPaymentPayload,\n): Promise<ValidatePaymentPayloadResult | null> {\n const action = payload.payload.action;\n const buildCalldata =\n action === \"boson-createOfferAndCommit\"\n ? buildCreateOfferAndCommitCalldata\n : action === \"boson-createOfferCommitAndRedeem\"\n ? buildCreateOfferCommitAndRedeemCalldata\n : undefined;\n\n if (!buildCalldata) {\n // Other actions (boson-redeem, dispute/*, etc.) aren't commit-time;\n // they have their own meta-tx encodings outside this scheme's\n // payment-payload validator. If we ever see one here it's a config\n // bug — the action wouldn't have been listed in\n // requirements.actions.next at commit time.\n return failure(\n 7,\n \"CALLDATA_MISMATCH\",\n \"payload.action\",\n \"boson-createOfferAndCommit | boson-createOfferCommitAndRedeem\",\n action,\n \"rule-7 calldata reconstruction is only defined for commit-time actions\",\n );\n }\n\n // `committer` is an outer argument of `createOfferAndCommit(...)`,\n // not a field in the seller's FullOffer EIP-712 typed-data (see\n // `signFullOffer` in `@bosonprotocol/core-sdk`'s\n // `exchanges/handler.js`). The seller's signature is valid for any\n // committer value, so the buyer's client splices `committer = buyer`\n // into the meta-tx calldata before signing (see\n // `@bosonprotocol/x402-client`'s `pre-commit.ts:94`). Rule 3 already\n // enforces that `offerRef.fullOffer` matches\n // `requirements.offer.fullOffer` byte-for-byte, so the offerRef\n // carries whatever seed value the application chose at challenge\n // time. Here we mirror the buyer-side splice when rebuilding the\n // expected calldata — without it every valid payment trips rule 7\n // on the committer slot. Regression: x402B#73.\n const fullOfferWithSig = {\n ...payload.payload.offerRef.fullOffer,\n committer: payload.payload.buyer,\n signature: payload.payload.offerRef.sellerSig,\n } as unknown as BuilderFullOffer;\n\n let expected: { functionName: string; functionSignature: string };\n try {\n expected = await buildCalldata({ fullOffer: fullOfferWithSig });\n } catch (e) {\n return failure(\n 7,\n \"CALLDATA_MISMATCH\",\n \"payload.metaTx.functionSignature\",\n undefined,\n undefined,\n (e as Error).message,\n );\n }\n\n if (expected.functionName !== payload.payload.metaTx.functionName) {\n return failure(\n 7,\n \"CALLDATA_MISMATCH\",\n \"payload.metaTx.functionName\",\n expected.functionName,\n payload.payload.metaTx.functionName,\n );\n }\n if (\n expected.functionSignature.toLowerCase() !==\n payload.payload.metaTx.functionSignature.toLowerCase()\n ) {\n return failure(\n 7,\n \"CALLDATA_MISMATCH\",\n \"payload.metaTx.functionSignature\",\n expected.functionSignature,\n payload.payload.metaTx.functionSignature,\n );\n }\n return null;\n}\n\nfunction checkTokenAuthRules(\n payload: EscrowPaymentPayload,\n requirements: EscrowPaymentRequirements,\n nowSec?: number,\n): ValidatePaymentPayloadResult | null {\n const strategy = payload.payload.tokenAuthStrategy;\n const tokenAuth = payload.payload.tokenAuth;\n const now = nowSec ?? Math.floor(Date.now() / 1000);\n const horizon = now + requirements.maxTimeoutSeconds;\n\n if (strategy === \"none\") {\n if (tokenAuth !== undefined) {\n return failure(\n 9,\n \"TOKEN_AUTH_UNEXPECTED\",\n \"payload.tokenAuth\",\n \"undefined (strategy=none)\",\n tokenAuth.kind,\n );\n }\n return null;\n }\n\n // strategy is one of erc3009 / permit / permit2 — token-auth required.\n if (tokenAuth === undefined) {\n return failure(\n 9,\n \"TOKEN_AUTH_MISSING\",\n \"payload.tokenAuth\",\n `<${strategy} authorization>`,\n \"undefined\",\n );\n }\n if (tokenAuth.kind !== strategy) {\n return failure(9, \"TOKEN_AUTH_MISSING\", \"payload.tokenAuth.kind\", strategy, tokenAuth.kind);\n }\n\n switch (tokenAuth.kind) {\n case \"erc3009\": {\n if (tokenAuth.data.value !== requirements.amount) {\n return failure(\n 9,\n \"TOKEN_AUTH_AMOUNT_MISMATCH\",\n \"payload.tokenAuth.data.value\",\n requirements.amount,\n tokenAuth.data.value,\n );\n }\n if (tokenAuth.data.to.toLowerCase() !== requirements.escrowAddress.toLowerCase()) {\n return failure(\n 9,\n \"TOKEN_AUTH_RECIPIENT_MISMATCH\",\n \"payload.tokenAuth.data.to\",\n requirements.escrowAddress,\n tokenAuth.data.to,\n );\n }\n if (tokenAuth.data.validBefore > horizon) {\n return failure(\n 9,\n \"TOKEN_AUTH_DEADLINE_EXCEEDED\",\n \"payload.tokenAuth.data.validBefore\",\n `<= ${horizon}`,\n tokenAuth.data.validBefore,\n );\n }\n return null;\n }\n case \"permit\": {\n if (tokenAuth.data.value !== requirements.amount) {\n return failure(\n 10,\n \"TOKEN_AUTH_AMOUNT_MISMATCH\",\n \"payload.tokenAuth.data.value\",\n requirements.amount,\n tokenAuth.data.value,\n );\n }\n if (tokenAuth.data.spender.toLowerCase() !== requirements.escrowAddress.toLowerCase()) {\n return failure(\n 10,\n \"TOKEN_AUTH_SPENDER_MISMATCH\",\n \"payload.tokenAuth.data.spender\",\n requirements.escrowAddress,\n tokenAuth.data.spender,\n );\n }\n if (tokenAuth.data.deadline > horizon) {\n return failure(\n 10,\n \"TOKEN_AUTH_DEADLINE_EXCEEDED\",\n \"payload.tokenAuth.data.deadline\",\n `<= ${horizon}`,\n tokenAuth.data.deadline,\n );\n }\n return null;\n }\n case \"permit2\": {\n if (tokenAuth.data.permitted.amount !== requirements.amount) {\n return failure(\n 11,\n \"TOKEN_AUTH_AMOUNT_MISMATCH\",\n \"payload.tokenAuth.data.permitted.amount\",\n requirements.amount,\n tokenAuth.data.permitted.amount,\n );\n }\n if (tokenAuth.data.permitted.token.toLowerCase() !== requirements.asset.toLowerCase()) {\n return failure(\n 11,\n \"TOKEN_AUTH_TOKEN_MISMATCH\",\n \"payload.tokenAuth.data.permitted.token\",\n requirements.asset,\n tokenAuth.data.permitted.token,\n );\n }\n if (tokenAuth.data.spender.toLowerCase() !== requirements.escrowAddress.toLowerCase()) {\n return failure(\n 11,\n \"TOKEN_AUTH_SPENDER_MISMATCH\",\n \"payload.tokenAuth.data.spender\",\n requirements.escrowAddress,\n tokenAuth.data.spender,\n );\n }\n if (tokenAuth.data.deadline > horizon) {\n return failure(\n 11,\n \"TOKEN_AUTH_DEADLINE_EXCEEDED\",\n \"payload.tokenAuth.data.deadline\",\n `<= ${horizon}`,\n tokenAuth.data.deadline,\n );\n }\n return null;\n }\n default:\n // Defensive: zod narrows `tokenAuth.kind` to the discriminated\n // union above, so the runtime should never reach this branch.\n // Fail closed if a malformed payload bypasses the parser rather\n // than implicitly returning `undefined` (which the caller treats\n // as `=== null` and would silently pass through to rule 13).\n return failure(\n 9,\n \"TOKEN_AUTH_UNKNOWN_STRATEGY\",\n \"payload.tokenAuth.kind\",\n \"erc3009 | permit | permit2\",\n (tokenAuth as { kind: string }).kind,\n );\n }\n}\n\nfunction checkFulfillment(\n payload: EscrowPaymentPayload,\n requirements: EscrowPaymentRequirements,\n validator?: ValidatePaymentPayloadArgs[\"validateFulfillmentData\"],\n): ValidatePaymentPayloadResult | null {\n const required = requirements.fulfillment?.required === true;\n const carried = payload.fulfillment;\n\n if (carried === undefined) {\n return required\n ? failure(13, \"FULFILLMENT_REQUIRED\", \"payload.fulfillment\", \"<option>\", \"undefined\")\n : null;\n }\n\n const advertised: FulfillmentOption[] = requirements.fulfillment?.options ?? [];\n const matched = advertised.find((option) => option.id === carried.option);\n if (!matched) {\n return failure(\n 13,\n \"FULFILLMENT_OPTION_NOT_ADVERTISED\",\n \"payload.fulfillment.option\",\n advertised.map((o) => o.id),\n carried.option,\n );\n }\n\n // Atomic Flow B carries buyer-supplied delivery data in the\n // commit-time payload; Flow A defers it to the redeem POST body.\n const action = payload.payload.action;\n if (action === \"boson-createOfferCommitAndRedeem\") {\n if (carried.data === undefined) {\n return failure(\n 13,\n \"FULFILLMENT_DATA_REQUIRED\",\n \"payload.fulfillment.data\",\n matched.schema ?? \"null\",\n \"undefined\",\n \"atomic createOfferCommitAndRedeem requires fulfillment.data at commit time\",\n );\n }\n if (validator !== undefined) {\n const result = validator(matched.id, carried.data);\n if (!result.ok) {\n return failure(\n 13,\n \"FULFILLMENT_DATA_INVALID\",\n \"payload.fulfillment.data\",\n matched.schema,\n carried.data,\n result.reason,\n );\n }\n }\n return null;\n }\n\n // Flow A and any other commit-time action: data is forbidden here.\n if (carried.data !== undefined) {\n return failure(\n 13,\n \"FULFILLMENT_DATA_UNEXPECTED\",\n \"payload.fulfillment.data\",\n \"undefined\",\n carried.data,\n \"two-step boson-createOfferAndCommit defers fulfillment.data to the redeem POST body\",\n );\n }\n return null;\n}\n\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (a === null || b === null || typeof a !== \"object\" || typeof b !== \"object\") return false;\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i += 1) {\n if (!deepEqual(a[i], b[i])) return false;\n }\n return true;\n }\n const ao = a as Record<string, unknown>;\n const bo = b as Record<string, unknown>;\n const aKeys = Object.keys(ao);\n const bKeys = Object.keys(bo);\n if (aKeys.length !== bKeys.length) return false;\n for (const k of aKeys) {\n if (!Object.prototype.hasOwnProperty.call(bo, k)) return false;\n if (!deepEqual(ao[k], bo[k])) return false;\n }\n return true;\n}\n\n/**\n * Concatenate the buyer's split-form `(v, r, s)` triple into the\n * 65-byte signature shape viem's `recoverTypedDataAddress` accepts.\n * `v` is normalised to the high byte; `r` and `s` are zero-padded to\n * 32 bytes (they're already that in the wire-format schema, but we\n * defend in depth).\n */\nfunction encodeRsv(sig: { v: number; r: string; s: string }): string {\n if (sig.v !== 0 && sig.v !== 1 && sig.v !== 27 && sig.v !== 28) {\n throw new Error(\"signature v must be 0, 1, 27, or 28\");\n }\n const r = sig.r.replace(/^0x/, \"\").padStart(64, \"0\");\n const s = sig.s.replace(/^0x/, \"\").padStart(64, \"0\");\n const normalizedV = sig.v === 0 || sig.v === 1 ? sig.v + 27 : sig.v;\n const v = normalizedV.toString(16).padStart(2, \"0\");\n return `0x${r}${s}${v}`;\n}\n\nfunction failure(\n rule: number,\n code: ValidationErrorCode,\n field?: string,\n expected?: unknown,\n got?: unknown,\n reason?: string,\n): ValidatePaymentPayloadResult {\n const out: ValidatePaymentPayloadResult = { ok: false, rule, code };\n if (field !== undefined) (out as { field?: string }).field = field;\n if (expected !== undefined) (out as { expected?: unknown }).expected = expected;\n if (got !== undefined) (out as { got?: unknown }).got = got;\n if (reason !== undefined) (out as { reason?: string }).reason = reason;\n return out;\n}\n","// On-chain (or off-chain — subgraph) verification of an exchange's\n// state after a facilitator settle / perform-action. The reader is\n// pluggable so callers can wire up a subgraph query, a viem RPC\n// read, or core-sdk's `exchanges.handler.getExchange` without\n// x402-server taking a hard dependency on any one mechanism.\n//\n// The verifier itself is pure: given a snapshot + the four-field\n// expectation from boson-impl-02-flows.md Flow A/B \"Verify\" step\n// (state, seller, exchangeToken, price), it returns a structured\n// pass / fail result.\n\nimport { DisputeState, ExchangeState } from \"@bosonprotocol/x402-actions\";\nimport type { Address } from \"@bosonprotocol/x402-core/schemes/escrow\";\n\n/**\n * Minimal protocol-level snapshot of an exchange the verifier needs.\n *\n * Sourced by `ExchangeReader.read` — typical implementations:\n *\n * - `@bosonprotocol/core-sdk`'s `coreSDK.getExchangeById` (subgraph\n * round-trip; tolerant of indexer lag).\n * - A viem `publicClient.readContract` against\n * `IBosonExchangeHandler.getExchange(exchangeId)` plus a follow-up\n * `getOffer(offerId)` for `exchangeToken` + `price` (no indexer\n * lag, costs an extra RPC call).\n */\nexport interface ExchangeSnapshot {\n state: ExchangeState;\n /** Present when `state === ExchangeState.DISPUTED`. */\n disputeState?: DisputeState;\n seller: Address;\n exchangeToken: Address;\n /** Atomic units, decimal string. */\n price: string;\n}\n\n/**\n * Pluggable reader for the post-settle / post-perform-action state\n * verification step. The reader returns `null` iff the exchange id\n * doesn't yet exist in the data source (subgraph not yet indexed,\n * `getExchange` reverts on a non-existent id, etc.). `verifyExchange`\n * retries transient not-found / stale-state results with a bounded wait.\n */\nexport interface ExchangeReader {\n read(exchangeId: string): Promise<ExchangeSnapshot | null>;\n}\n\nexport interface VerifyExchangeExpected {\n state: ExchangeState;\n /** Present iff `state === ExchangeState.DISPUTED`. */\n disputeState?: DisputeState;\n seller: Address;\n exchangeToken: Address;\n price: string;\n}\n\nexport type VerifyExchangeResult =\n | { ok: true }\n | { ok: false; code: VerifyExchangeErrorCode; field?: string; expected?: unknown; got?: unknown };\n\nexport type VerifyExchangeErrorCode =\n | \"EXCHANGE_NOT_FOUND\"\n | \"STATE_MISMATCH\"\n | \"DISPUTE_STATE_MISMATCH\"\n | \"SELLER_MISMATCH\"\n | \"TOKEN_MISMATCH\"\n | \"PRICE_MISMATCH\";\n\nexport interface VerifyExchangeOptions {\n /** Maximum read/compare attempts. Defaults to 3. */\n attempts?: number;\n /** Delay between retryable attempts in milliseconds. Defaults to 50. */\n delayMs?: number;\n}\n\n/**\n * Compare a snapshot against the expected post-state. Short-circuits\n * at the first mismatch. Pure; the reader does the I/O.\n */\nexport function verifyExchangeSnapshot(\n snapshot: ExchangeSnapshot | null,\n expected: VerifyExchangeExpected,\n): VerifyExchangeResult {\n if (snapshot === null) {\n return { ok: false, code: \"EXCHANGE_NOT_FOUND\" };\n }\n if (snapshot.state !== expected.state) {\n return {\n ok: false,\n code: \"STATE_MISMATCH\",\n field: \"state\",\n expected: expected.state,\n got: snapshot.state,\n };\n }\n if (expected.state === ExchangeState.DISPUTED) {\n if (snapshot.disputeState !== expected.disputeState) {\n return {\n ok: false,\n code: \"DISPUTE_STATE_MISMATCH\",\n field: \"disputeState\",\n expected: expected.disputeState,\n got: snapshot.disputeState,\n };\n }\n }\n if (snapshot.seller.toLowerCase() !== expected.seller.toLowerCase()) {\n return {\n ok: false,\n code: \"SELLER_MISMATCH\",\n field: \"seller\",\n expected: expected.seller,\n got: snapshot.seller,\n };\n }\n if (snapshot.exchangeToken.toLowerCase() !== expected.exchangeToken.toLowerCase()) {\n return {\n ok: false,\n code: \"TOKEN_MISMATCH\",\n field: \"exchangeToken\",\n expected: expected.exchangeToken,\n got: snapshot.exchangeToken,\n };\n }\n if (snapshot.price !== expected.price) {\n return {\n ok: false,\n code: \"PRICE_MISMATCH\",\n field: \"price\",\n expected: expected.price,\n got: snapshot.price,\n };\n }\n return { ok: true };\n}\n\n/**\n * High-level convenience — read via the configured `ExchangeReader`\n * and apply `verifyExchangeSnapshot`. Retries boundedly when a reader\n * may be behind the just-mined transaction (`EXCHANGE_NOT_FOUND`,\n * `STATE_MISMATCH`, or `DISPUTE_STATE_MISMATCH`), then returns the\n * last comparison result.\n */\nexport async function verifyExchange(\n reader: ExchangeReader,\n exchangeId: string,\n expected: VerifyExchangeExpected,\n options: VerifyExchangeOptions = {},\n): Promise<VerifyExchangeResult> {\n const attempts = Math.max(1, Math.floor(options.attempts ?? 3));\n const delayMs = Math.max(0, Math.floor(options.delayMs ?? 50));\n let result: VerifyExchangeResult = { ok: false, code: \"EXCHANGE_NOT_FOUND\" };\n\n for (let attempt = 1; attempt <= attempts; attempt += 1) {\n const snapshot = await reader.read(exchangeId);\n result = verifyExchangeSnapshot(snapshot, expected);\n if (result.ok || !isRetryableVerifyResult(result) || attempt === attempts) {\n return result;\n }\n if (delayMs > 0) {\n await delay(delayMs);\n }\n }\n\n return result;\n}\n\nfunction isRetryableVerifyResult(result: VerifyExchangeResult): boolean {\n return (\n !result.ok &&\n (result.code === \"EXCHANGE_NOT_FOUND\" ||\n result.code === \"STATE_MISMATCH\" ||\n result.code === \"DISPUTE_STATE_MISMATCH\")\n );\n}\n\nasync function delay(ms: number): Promise<void> {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n","// Commit-time handlers — `handleCommit` (Flow A, post-state\n// COMMITTED) and `handleCommitAndRedeem` (Flow B, post-state\n// REDEEMED). Both decode `X-PAYMENT`, run the 13-rule validator,\n// forward the signed payload to the facilitator's `/settle`, verify\n// the resulting exchange snapshot, and emit a fresh `nextActions`\n// envelope.\n\nimport { ExchangeState } from \"@bosonprotocol/x402-actions\";\nimport type { EscrowPaymentRequirements } from \"@bosonprotocol/x402-core/schemes/escrow\";\nimport type { ActionId } from \"@bosonprotocol/x402-core/state-machine\";\n\nimport { emitNextActions } from \"./next-actions.js\";\nimport { handlerErr, handlerOk, type HandlerResult, type HandlerWarning } from \"./types.js\";\nimport { decodeXPaymentHeader } from \"../validate/decode.js\";\nimport { validatePaymentPayload } from \"../validate/payment-payload.js\";\nimport {\n verifyExchange,\n type ExchangeReader,\n type VerifyExchangeExpected,\n} from \"../onchain/verify-exchange.js\";\nimport type { FacilitatorClient } from \"../facilitator/client.js\";\nimport { FacilitatorHttpError } from \"../facilitator/errors.js\";\nimport type { FulfillmentRecoveryEntry, X402bServerConfig } from \"../config.js\";\n\nexport interface CommitHandlerInput {\n /** Raw `X-PAYMENT` header value (base64'd JSON). */\n paymentHeader: string | undefined | null;\n /** The 402 `PaymentRequirements` the buyer is responding to. */\n requirements: EscrowPaymentRequirements;\n}\n\nexport interface CommitHandlerContext {\n config: X402bServerConfig;\n facilitator: FacilitatorClient;\n exchangeReader: ExchangeReader;\n fulfillmentRecoveryStore: Map<string, FulfillmentRecoveryEntry>;\n /**\n * Per-exchange fulfillment option policy. Flow A writes the ids\n * advertised by the original requirements so the redeem-time choice\n * is constrained to the offer's own channel set.\n */\n exchangeFulfillmentOptionStore: Map<string, readonly string[]>;\n}\n\nexport interface CommitOk {\n exchangeId: string;\n txHash: string;\n /**\n * Non-fatal post-settle conditions. Today only Flow B uses this slot —\n * the on-chain redeem may have succeeded while the configured channel\n * adapter's `onCommit(...)` failed (the buyer's funds and voucher are\n * already gone; the seller's host needs to recover the delivery target\n * out-of-band). The exchange state is the wire-format source of truth;\n * warnings are advisory.\n */\n warnings?: HandlerWarning[];\n}\n\n/**\n * Flow A — `boson-createOfferAndCommit`. Settles via facilitator,\n * expects the resulting exchange in `COMMITTED`, returns 200 with\n * `nextActions` advertising the legal post-COMMITTED transitions.\n */\nexport async function handleCommit(\n input: CommitHandlerInput,\n ctx: CommitHandlerContext,\n): Promise<HandlerResult<CommitOk>> {\n return await handleCommitImpl(input, ctx, {\n expectedAction: \"boson-createOfferAndCommit\",\n expectedState: ExchangeState.COMMITTED,\n });\n}\n\n/**\n * Flow B — `boson-createOfferCommitAndRedeem`. Same pipeline as\n * `handleCommit` but verifies the exchange reached `REDEEMED`.\n */\nexport async function handleCommitAndRedeem(\n input: CommitHandlerInput,\n ctx: CommitHandlerContext,\n): Promise<HandlerResult<CommitOk>> {\n return await handleCommitImpl(input, ctx, {\n expectedAction: \"boson-createOfferCommitAndRedeem\",\n expectedState: ExchangeState.REDEEMED,\n });\n}\n\nasync function handleCommitImpl(\n input: CommitHandlerInput,\n ctx: CommitHandlerContext,\n expected: { expectedAction: ActionId; expectedState: ExchangeState },\n): Promise<HandlerResult<CommitOk>> {\n const decoded = decodeXPaymentHeader(input.paymentHeader);\n if (!decoded.ok) {\n const status = decoded.code === \"MISSING_HEADER\" ? 402 : 400;\n return handlerErr(status, decoded.code, decoded.reason);\n }\n if (decoded.payload.payload.action !== expected.expectedAction) {\n return handlerErr(\n 400,\n \"ACTION_ROUTE_MISMATCH\",\n `handler expected action ${expected.expectedAction}, got ${decoded.payload.payload.action}`,\n {\n expected: expected.expectedAction,\n got: decoded.payload.payload.action,\n },\n );\n }\n\n // For atomic Flow B the validator needs a per-channel data validator\n // so it can reject malformed buyer data before the on-chain redeem\n // happens. Flow A doesn't carry `fulfillment.data` at commit time so\n // the validator never invokes this callback; pass it anyway and let\n // rule 13 dispatch on `payload.action`.\n const channels = ctx.config.fulfillmentChannels ?? [];\n const channelById = new Map(channels.map((c) => [c.id, c]));\n const validation = await validatePaymentPayload({\n payload: decoded.payload,\n requirements: input.requirements,\n chainId: ctx.config.chainId,\n validateFulfillmentData: (option, data) => {\n const channel = channelById.get(option);\n if (channel === undefined) {\n return {\n ok: false,\n reason: `fulfillment.option '${option}' has no registered channel adapter on this server`,\n };\n }\n try {\n return channel.validate(data);\n } catch (e) {\n return { ok: false, reason: e instanceof Error ? e.message : String(e) };\n }\n },\n });\n if (!validation.ok) {\n return handlerErr(400, validation.code, validation.reason ?? `rule ${validation.rule} failed`, {\n rule: validation.rule,\n field: validation.field,\n expected: validation.expected,\n got: validation.got,\n });\n }\n\n let settleResult: Awaited<ReturnType<FacilitatorClient[\"settle\"]>>;\n try {\n settleResult = await ctx.facilitator.settle({\n scheme: \"escrow\",\n network: input.requirements.network,\n payload: decoded.payload,\n requirements: input.requirements,\n });\n } catch (e) {\n if (e instanceof FacilitatorHttpError) {\n return handlerErr(502, \"FACILITATOR_UNREACHABLE\", e.message, {\n code: e.code,\n status: e.status,\n facilitatorCode: e.facilitatorCode,\n });\n }\n throw e;\n }\n\n if (!settleResult.ok) {\n return handlerErr(502, \"FACILITATOR_REJECTED\", settleResult.reason, {\n facilitatorCode: settleResult.code,\n });\n }\n\n const verifyResult = await verifyExchange(\n ctx.exchangeReader,\n settleResult.exchangeId,\n buildExpectedFromRequirements(input.requirements, expected.expectedState),\n );\n if (!verifyResult.ok) {\n return handlerErr(\n 502,\n `STATE_VERIFY_${verifyResult.code}`,\n \"post-settle state verification failed\",\n {\n exchangeId: settleResult.exchangeId,\n txHash: settleResult.txHash,\n field: verifyResult.field,\n expected: verifyResult.expected,\n got: verifyResult.got,\n },\n );\n }\n\n // Flow A only: persist the *advertised* option ids from the original\n // 402 so the redeem handler can constrain the buyer's redeem-time\n // fulfillment choice to the offer's own channel set. Flow B is\n // already in REDEEMED — there is no later redeem step to gate.\n if (expected.expectedState === ExchangeState.COMMITTED) {\n ctx.exchangeFulfillmentOptionStore.set(\n settleResult.exchangeId,\n input.requirements.fulfillment?.options.map((option) => option.id) ?? [],\n );\n }\n\n // Flow B only: the buyer's delivery data rides along with the\n // commit-time payload because atomic redeem leaves no later round\n // trip for it. The on-chain redeem has already settled at this\n // point; channel persistence is best-effort and surfaces as a\n // warning on failure (the buyer's funds + voucher are irreversibly\n // committed regardless). Record a pending update before the channel\n // write so the host can recover if the write fails after redeem.\n const warnings: HandlerWarning[] = [];\n if (\n expected.expectedState === ExchangeState.REDEEMED &&\n decoded.payload.fulfillment !== undefined &&\n decoded.payload.fulfillment.data !== undefined\n ) {\n const pending: FulfillmentRecoveryEntry = {\n exchangeId: settleResult.exchangeId,\n option: decoded.payload.fulfillment.option,\n data: decoded.payload.fulfillment.data,\n redeemer: decoded.payload.payload.buyer,\n recordedAt: Date.now(),\n };\n ctx.fulfillmentRecoveryStore.set(settleResult.exchangeId, pending);\n\n const channel = channelById.get(decoded.payload.fulfillment.option);\n if (channel === undefined) {\n const reason = \"no channel adapter is registered\";\n ctx.fulfillmentRecoveryStore.set(settleResult.exchangeId, {\n ...pending,\n error: reason,\n });\n // Validation should have caught this (rule 13 rejects an option\n // with no registered adapter). Surface a warning rather than\n // silently dropping the data if it slips past.\n warnings.push({\n code: \"FULFILLMENT_COMMIT_DEFERRED\",\n reason: \"atomic redeem succeeded on-chain, but no channel adapter is registered\",\n details: {\n exchangeId: settleResult.exchangeId,\n option: decoded.payload.fulfillment.option,\n error: reason,\n },\n });\n } else {\n try {\n await channel.onCommit(settleResult.exchangeId, decoded.payload.fulfillment.data);\n ctx.fulfillmentRecoveryStore.delete(settleResult.exchangeId);\n } catch (e) {\n const reason = e instanceof Error ? e.message : String(e);\n ctx.fulfillmentRecoveryStore.set(settleResult.exchangeId, {\n ...pending,\n error: reason,\n });\n warnings.push({\n code: \"FULFILLMENT_COMMIT_DEFERRED\",\n reason: \"atomic redeem succeeded on-chain, but the channel adapter rejected the data\",\n details: {\n exchangeId: settleResult.exchangeId,\n option: decoded.payload.fulfillment.option,\n error: reason,\n },\n });\n }\n }\n }\n\n // Both commit-side actions transition to non-DISPUTED states\n // (COMMITTED for Flow A, REDEEMED for Flow B), so the cast to\n // `Exclude<ExchangeState, DISPUTED>` is sound — the function only\n // narrows `expected.expectedState` itself which is typed loosely as\n // `ExchangeState` for shared use by both wrappers.\n const nextActions = emitNextActions(\n {\n exchangeId: settleResult.exchangeId,\n exchangeState: expected.expectedState as Exclude<\n ExchangeState,\n typeof ExchangeState.DISPUTED\n >,\n },\n ctx.config.channelRegistry,\n ctx.config.facilitator.url,\n );\n return handlerOk({\n exchangeId: settleResult.exchangeId,\n txHash: settleResult.txHash,\n nextActions,\n ...(warnings.length > 0 ? { warnings } : {}),\n });\n}\n\nfunction buildExpectedFromRequirements(\n requirements: EscrowPaymentRequirements,\n state: ExchangeState,\n): VerifyExchangeExpected {\n return {\n state,\n seller: requirements.offer.creator,\n exchangeToken: requirements.asset,\n price: requirements.amount,\n };\n}\n","// Convenience handlers for the post-commit actions — `redeem`,\n// `complete`, and the four dispute transitions. Each is a thin\n// wrapper over the facilitator's `/perform-action` endpoint:\n// forward the buyer- or seller-signed payload, verify the resulting\n// exchange snapshot reaches the action's `ACTION_POST_STATE`, emit\n// fresh `nextActions`.\n\nimport { ExchangeState } from \"@bosonprotocol/x402-actions\";\nimport type { Address } from \"@bosonprotocol/x402-core/schemes/escrow\";\nimport { ACTION_POST_STATE, type ExchangeActionId } from \"@bosonprotocol/x402-core/state-machine\";\nimport { decodeSignedPayload } from \"@bosonprotocol/x402-evm\";\nimport type { Hex } from \"viem\";\n\nimport { emitNextActions } from \"./next-actions.js\";\nimport { handlerErr, handlerOk, type HandlerResult, type HandlerWarning } from \"./types.js\";\nimport type { FacilitatorClient } from \"../facilitator/client.js\";\nimport { FacilitatorHttpError } from \"../facilitator/errors.js\";\nimport type {\n FulfillmentRecoveryEntry,\n RedeemFulfillmentChannel,\n X402bServerConfig,\n} from \"../config.js\";\nimport {\n verifyExchange,\n type ExchangeReader,\n type VerifyExchangeExpected,\n} from \"../onchain/verify-exchange.js\";\n\n/** Per-action inputs accepted by every post-commit convenience handler. */\nexport interface PerformActionInput {\n exchangeId: string;\n /** ABI-encoded `BosonMetaTx` tuple — see `encodeSignedPayload` in `@bosonprotocol/x402-facilitator`. */\n signedPayload: Hex;\n}\n\n/**\n * Redeem-time variant of `PerformActionInput`. Carries the buyer's\n * `fulfillment` selection for Flow A — `data` is the delivery target\n * the redeem-time channel adapter persists. Required when the\n * original 402 advertised `fulfillment.required = true`; omitted\n * otherwise.\n */\nexport interface RedeemHandlerInput extends PerformActionInput {\n fulfillment?: { option: string; data: Record<string, unknown> | null };\n}\n\nexport interface PerformActionContext {\n config: X402bServerConfig;\n facilitator: FacilitatorClient;\n exchangeReader: ExchangeReader;\n}\n\nexport interface RedeemHandlerContext extends PerformActionContext {\n exchangeFulfillmentOptionStore: Map<string, readonly string[]>;\n fulfillmentRecoveryStore: Map<string, FulfillmentRecoveryEntry>;\n}\n\nexport interface PerformActionOk {\n txHash: string;\n warnings?: HandlerWarning[];\n}\n\n/**\n * Generic exchange-keyed post-commit handler — wired from each of the\n * per-action wrappers below. Entity-keyed actions (e.g. `withdrawFunds`)\n * have their own handler in `./withdraw-funds.ts`.\n */\nexport async function handlePerformAction(\n action: ExchangeActionId,\n input: PerformActionInput,\n ctx: PerformActionContext,\n): Promise<HandlerResult<PerformActionOk>> {\n const reference = await ctx.exchangeReader.read(input.exchangeId);\n if (reference === null) {\n return handlerErr(\n 502,\n \"STATE_VERIFY_EXCHANGE_NOT_FOUND\",\n \"pre-action exchange reference could not be read\",\n { action, exchangeId: input.exchangeId },\n );\n }\n\n let result: Awaited<ReturnType<FacilitatorClient[\"performAction\"]>>;\n try {\n result = await ctx.facilitator.performAction({\n network: ctx.config.network,\n escrowAddress: ctx.config.escrow,\n exchangeId: input.exchangeId,\n action,\n signedPayload: input.signedPayload,\n });\n } catch (e) {\n if (e instanceof FacilitatorHttpError) {\n return handlerErr(502, \"FACILITATOR_UNREACHABLE\", e.message, {\n code: e.code,\n status: e.status,\n facilitatorCode: e.facilitatorCode,\n });\n }\n throw e;\n }\n\n if (!result.ok) {\n return handlerErr(502, \"FACILITATOR_REJECTED\", result.reason, {\n facilitatorCode: result.code,\n });\n }\n\n const postState = ACTION_POST_STATE[action];\n const expected: VerifyExchangeExpected = {\n state: postState.exchange,\n ...(postState.dispute !== undefined ? { disputeState: postState.dispute } : {}),\n seller: reference.seller,\n exchangeToken: reference.exchangeToken,\n price: reference.price,\n };\n const verifyResult = await verifyExchange(ctx.exchangeReader, input.exchangeId, expected);\n if (!verifyResult.ok) {\n return handlerErr(\n 502,\n `STATE_VERIFY_${verifyResult.code}`,\n \"post-action state verification failed\",\n {\n action,\n exchangeId: input.exchangeId,\n txHash: result.txHash,\n field: verifyResult.field,\n expected: verifyResult.expected,\n got: verifyResult.got,\n },\n );\n }\n\n const nextActions =\n postState.exchange === ExchangeState.DISPUTED && postState.dispute !== undefined\n ? emitNextActions(\n {\n exchangeId: input.exchangeId,\n exchangeState: ExchangeState.DISPUTED,\n disputeState: postState.dispute,\n },\n ctx.config.channelRegistry,\n ctx.config.facilitator.url,\n )\n : emitNextActions(\n {\n exchangeId: input.exchangeId,\n exchangeState: postState.exchange as Exclude<\n ExchangeState,\n typeof ExchangeState.DISPUTED\n >,\n },\n ctx.config.channelRegistry,\n ctx.config.facilitator.url,\n );\n\n return handlerOk({ txHash: result.txHash, nextActions });\n}\n\n/**\n * Redeem handler. Validates the buyer's `fulfillment` selection (if\n * present) against the offer's advertised option set and the host's\n * channel registry, runs the channel's `validate` up-front, then\n * forwards to the facilitator. The corresponding\n * `onCommit(exchangeId, data)` upsert is deferred until *after* the\n * facilitator + state verification confirm the exchange reached\n * `REDEEMED`, so a failed redeem leaves the stored delivery target\n * unchanged. The voucher NFT is transferable; whichever wallet signs\n * `boson-redeem` supplies the delivery data — it's the redeemer's\n * choice end-to-end.\n */\nexport async function handleRedeem(\n input: RedeemHandlerInput,\n ctx: RedeemHandlerContext,\n): Promise<HandlerResult<PerformActionOk>> {\n let redeemer: Address;\n try {\n redeemer = decodeSignedPayload(input.signedPayload).from as Address;\n } catch (e) {\n return handlerErr(\n 400,\n \"SIGNED_PAYLOAD_DECODE_FAILED\",\n e instanceof Error ? e.message : \"signedPayload could not be decoded\",\n );\n }\n\n let resolvedChannel: RedeemFulfillmentChannel | undefined;\n if (input.fulfillment !== undefined) {\n const advertisedOptions = ctx.exchangeFulfillmentOptionStore.get(input.exchangeId);\n if (advertisedOptions !== undefined && !advertisedOptions.includes(input.fulfillment.option)) {\n return handlerErr(\n 400,\n \"FULFILLMENT_OPTION_NOT_ADVERTISED\",\n `fulfillment.option '${input.fulfillment.option}' was not advertised for this exchange`,\n { option: input.fulfillment.option, advertised: advertisedOptions },\n );\n }\n\n const channels = ctx.config.fulfillmentChannels;\n if (channels === undefined) {\n return handlerErr(\n 400,\n \"FULFILLMENT_CHANNELS_NOT_CONFIGURED\",\n \"server received redeem-time fulfillment data but has no fulfillmentChannels registered\",\n );\n }\n const channel = channels.find((c) => c.id === input.fulfillment!.option);\n if (channel === undefined) {\n return handlerErr(\n 400,\n \"FULFILLMENT_OPTION_UNKNOWN\",\n `fulfillment.option '${input.fulfillment.option}' is not registered with the server`,\n { option: input.fulfillment.option, registered: channels.map((c) => c.id) },\n );\n }\n // Host-supplied `validate` callbacks are arbitrary code — treat a\n // thrown error the same as `{ ok: false }` so a buggy / strict\n // adapter surfaces as a 400 the buyer can correct, not a 500.\n let validation: ReturnType<RedeemFulfillmentChannel[\"validate\"]>;\n try {\n validation = channel.validate(input.fulfillment.data);\n } catch (e) {\n return handlerErr(400, \"FULFILLMENT_DATA_INVALID\", errorMessage(e), {\n option: input.fulfillment.option,\n });\n }\n if (!validation.ok) {\n return handlerErr(400, \"FULFILLMENT_DATA_INVALID\", validation.reason, {\n option: input.fulfillment.option,\n });\n }\n resolvedChannel = channel;\n }\n\n const result = await handlePerformAction(\"boson-redeem\", input, ctx);\n if (!result.ok) return result;\n\n // Redeem confirmed REDEEMED on-chain — only now is it safe to\n // upsert the channel's delivery-target store. Record a pending\n // update first so a failing channel write leaves the host with an\n // explicit recovery item instead of losing the buyer's target.\n let warning: HandlerWarning | undefined;\n if (resolvedChannel !== undefined && input.fulfillment !== undefined) {\n const pending: FulfillmentRecoveryEntry = {\n exchangeId: input.exchangeId,\n option: input.fulfillment.option,\n data: input.fulfillment.data,\n redeemer,\n recordedAt: Date.now(),\n };\n ctx.fulfillmentRecoveryStore.set(input.exchangeId, pending);\n try {\n await resolvedChannel.onCommit(input.exchangeId, input.fulfillment.data);\n ctx.fulfillmentRecoveryStore.delete(input.exchangeId);\n } catch (e) {\n const reason = errorMessage(e);\n ctx.fulfillmentRecoveryStore.set(input.exchangeId, { ...pending, error: reason });\n warning = {\n code: \"FULFILLMENT_UPDATE_DEFERRED\",\n reason:\n \"redeem succeeded on-chain, but the server could not persist the fulfillment update\",\n details: {\n exchangeId: input.exchangeId,\n option: input.fulfillment.option,\n error: reason,\n },\n };\n }\n }\n\n // The exchange is REDEEMED even if the fulfillment write is deferred;\n // the per-exchange option-policy entry is no longer consulted.\n ctx.exchangeFulfillmentOptionStore.delete(input.exchangeId);\n\n if (warning !== undefined) {\n return {\n ...result,\n body: {\n ...result.body,\n warnings: [...(result.body.warnings ?? []), warning],\n },\n };\n }\n\n return result;\n}\n\nfunction errorMessage(e: unknown): string {\n return e instanceof Error ? e.message : String(e);\n}\n\n/** Per-action sugar — preserves the action id at the type level. */\nexport const handleComplete = (input: PerformActionInput, ctx: PerformActionContext) =>\n handlePerformAction(\"boson-completeExchange\", input, ctx);\nexport const handleDisputeRaise = (input: PerformActionInput, ctx: PerformActionContext) =>\n handlePerformAction(\"boson-raiseDispute\", input, ctx);\nexport const handleDisputeResolve = (input: PerformActionInput, ctx: PerformActionContext) =>\n handlePerformAction(\"boson-resolveDispute\", input, ctx);\nexport const handleDisputeRetract = (input: PerformActionInput, ctx: PerformActionContext) =>\n handlePerformAction(\"boson-retractDispute\", input, ctx);\nexport const handleDisputeEscalate = (input: PerformActionInput, ctx: PerformActionContext) =>\n handlePerformAction(\"boson-escalateDispute\", input, ctx);\n","// Shared input-shape regexes for the entity-keyed handlers\n// (`handleWithdrawFunds`, `handleGetAvailableFunds`, the express\n// adapter routes). Centralised here so the wire-level validation stays\n// consistent across endpoints — drift between two copies is exactly\n// the kind of bug that lets a malformed request slip through one\n// route's check but trip a deeper layer with a less precise error.\n//\n// `DECIMAL_UINT` and `ADDRESS` are sourced from `@bosonprotocol/x402-core`'s\n// `schemes/escrow` validators (the JSON-Schema-aligned canonical\n// definitions); re-exported under the local `_RE` alias to keep the\n// existing call sites stable.\n\nimport { ADDRESS, DECIMAL_UINT } from \"@bosonprotocol/x402-core/schemes/escrow\";\n\n/** Boson account `entityId` — uint256 in decimal-string form, no leading zeros. */\nexport const DECIMAL_UINT_RE = DECIMAL_UINT;\n\n/** 20-byte EVM address, 0x-prefixed, any letter case (we normalise downstream). */\nexport const ADDRESS_RE = ADDRESS;\n\n/**\n * Hex-string check for `signedPayload`. Requires `0x` followed by an\n * *even* number of hex digits so the body decodes to whole bytes —\n * odd-length payloads like `0xabc` would surface as\n * `signedPayload decode failed: …` deep in the facilitator pipeline,\n * which is a less precise 502 than the adapter-level 400 this regex\n * catches. Stricter than core's `HEX_BYTES` (which permits odd\n * lengths) so we keep this one local.\n */\nexport const HEX_BYTES_RE = /^0x([0-9a-fA-F]{2})*$/;\n","// Resolve an EVM address to a Boson Protocol `entityId` (seller or\n// buyer) via the core-sdk subgraph helpers.\n//\n// `coreSdk.getSellersByAddress(addr)` matches any of the four seller\n// roles (admin / assistant / clerk / treasury); `coreSdk.getBuyers({\n// buyersFilter: { wallet: addr.toLowerCase() } })` covers buyer-side.\n// There is no single-call helper that returns \"the entityId for this\n// wallet\"; we call both in parallel and disambiguate.\n//\n// Both branches can also legitimately return *multiple* entities for\n// one address — one wallet can be the admin of several Boson sellers,\n// for example. When that happens we refuse to guess: the caller must\n// re-issue with an explicit `entityId` so the withdraw signature\n// commits to a single account.\n\nimport type { CoreSdkReadAdapter } from \"../onchain/core-sdk-read.js\";\n\nexport interface ResolveEntityInput {\n address: string;\n role?: \"buyer\" | \"seller\";\n}\n\nexport interface ResolveEntityOk {\n ok: true;\n entityId: string;\n role: \"buyer\" | \"seller\";\n}\n\nexport type ResolveEntityError =\n | { ok: false; code: \"NOT_FOUND\"; reason: string }\n | {\n ok: false;\n code: \"AMBIGUOUS\";\n reason: string;\n /** Seller ids matching the address (one or many). Absent when no sellers matched. */\n sellerIds?: string[];\n /** Buyer ids matching the address (one or many). Absent when no buyers matched. */\n buyerIds?: string[];\n }\n | { ok: false; code: \"SUBGRAPH_FAILURE\"; reason: string };\n\nexport type ResolveEntityResult = ResolveEntityOk | ResolveEntityError;\n\nexport async function resolveEntityId(\n coreSdk: CoreSdkReadAdapter,\n input: ResolveEntityInput,\n): Promise<ResolveEntityResult> {\n const address = input.address.toLowerCase();\n\n let sellers: { id: string }[] = [];\n let buyers: { id: string }[] = [];\n try {\n [sellers, buyers] = await Promise.all([\n input.role === \"buyer\" ? Promise.resolve([]) : coreSdk.getSellersByAddress(address),\n input.role === \"seller\"\n ? Promise.resolve([])\n : coreSdk.getBuyers({ buyersFilter: { wallet: address } }),\n ]);\n } catch (e) {\n return {\n ok: false,\n code: \"SUBGRAPH_FAILURE\",\n reason: e instanceof Error ? e.message : \"subgraph lookup failed\",\n };\n }\n\n const sellerIds = sellers.map((s) => s.id);\n const buyerIds = buyers.map((b) => b.id);\n\n if (input.role === \"seller\") {\n if (sellerIds.length === 0) {\n return {\n ok: false,\n code: \"NOT_FOUND\",\n reason: `no seller entity found for address ${address}`,\n };\n }\n if (sellerIds.length > 1) {\n return {\n ok: false,\n code: \"AMBIGUOUS\",\n reason: `address ${address} resolves to multiple seller entities (ids ${sellerIds.join(\", \")}); pass entityId to disambiguate`,\n sellerIds,\n };\n }\n return { ok: true, entityId: sellerIds[0]!, role: \"seller\" };\n }\n if (input.role === \"buyer\") {\n if (buyerIds.length === 0) {\n return {\n ok: false,\n code: \"NOT_FOUND\",\n reason: `no buyer entity found for address ${address}`,\n };\n }\n if (buyerIds.length > 1) {\n return {\n ok: false,\n code: \"AMBIGUOUS\",\n reason: `address ${address} resolves to multiple buyer entities (ids ${buyerIds.join(\", \")}); pass entityId to disambiguate`,\n buyerIds,\n };\n }\n return { ok: true, entityId: buyerIds[0]!, role: \"buyer\" };\n }\n\n // role unspecified — exactly-one rule across both sides.\n const totalMatches = sellerIds.length + buyerIds.length;\n if (totalMatches === 0) {\n return {\n ok: false,\n code: \"NOT_FOUND\",\n reason: `no seller or buyer entity found for address ${address}`,\n };\n }\n if (totalMatches > 1) {\n return {\n ok: false,\n code: \"AMBIGUOUS\",\n reason: `address ${address} resolves to ${describeMatches(sellerIds, buyerIds)}; pass role and/or entityId to disambiguate`,\n ...(sellerIds.length > 0 ? { sellerIds } : {}),\n ...(buyerIds.length > 0 ? { buyerIds } : {}),\n };\n }\n if (sellerIds.length === 1) return { ok: true, entityId: sellerIds[0]!, role: \"seller\" };\n return { ok: true, entityId: buyerIds[0]!, role: \"buyer\" };\n}\n\nfunction describeMatches(sellerIds: string[], buyerIds: string[]): string {\n const parts: string[] = [];\n if (sellerIds.length > 0) {\n parts.push(\n sellerIds.length === 1\n ? `seller (id ${sellerIds[0]})`\n : `${sellerIds.length} sellers (ids ${sellerIds.join(\", \")})`,\n );\n }\n if (buyerIds.length > 0) {\n parts.push(\n buyerIds.length === 1\n ? `buyer (id ${buyerIds[0]})`\n : `${buyerIds.length} buyers (ids ${buyerIds.join(\", \")})`,\n );\n }\n return parts.join(\" and \");\n}\n","// Convenience handler for the entity-keyed `boson-withdrawFunds`\n// action. The buyer or seller signs an EIP-712 meta-tx for\n// `withdrawFunds(uint256 entityId, address[] tokenList, uint256[] tokenAmounts)`;\n// the server forwards the signed payload to the facilitator and\n// returns the resulting tx hash.\n//\n// Unlike the exchange-keyed `handlePerformAction`, this handler:\n// - takes an `entityId` (or an `address` + optional `role`) instead\n// of an `exchangeId`,\n// - skips the post-action `exchangeReader.read` + `verifyExchange`\n// step (the action doesn't transition the exchange state machine),\n// - returns just `{ txHash, entityId, role? }` — no `nextActions`\n// envelope (withdraw is deliberately absent from `next[]`).\n\nimport type { Address } from \"@bosonprotocol/x402-core/schemes/escrow\";\nimport type { Hex } from \"viem\";\n\nimport type { X402bServerConfig } from \"../config.js\";\nimport type { FacilitatorClient } from \"../facilitator/client.js\";\nimport { FacilitatorHttpError } from \"../facilitator/errors.js\";\nimport type { CoreSdkReadAdapter } from \"../onchain/core-sdk-read.js\";\nimport { ADDRESS_RE, DECIMAL_UINT_RE } from \"./entity-input-validators.js\";\nimport { resolveEntityId } from \"./resolve-entity.js\";\nimport { handlerErr, plainHandlerOk, type PlainHandlerResult } from \"./types.js\";\n\nexport interface WithdrawFundsBaseInput {\n /** ABI-encoded `BosonMetaTx` tuple — see `encodeSignedPayload` in `@bosonprotocol/x402-evm/codec`. */\n signedPayload: Hex;\n}\n\nexport type WithdrawFundsInput = WithdrawFundsBaseInput &\n ({ entityId: string } | { address: string; role?: \"buyer\" | \"seller\" });\n\nexport interface WithdrawFundsContext {\n config: X402bServerConfig;\n facilitator: FacilitatorClient;\n coreSdkRead: CoreSdkReadAdapter;\n}\n\nexport interface WithdrawFundsOk {\n txHash: string;\n entityId: string;\n role?: \"buyer\" | \"seller\";\n}\n\nexport async function handleWithdrawFunds(\n input: WithdrawFundsInput,\n ctx: WithdrawFundsContext,\n): Promise<PlainHandlerResult<WithdrawFundsOk>> {\n let entityId: string;\n let role: \"buyer\" | \"seller\" | undefined;\n\n if (\"entityId\" in input) {\n if (!DECIMAL_UINT_RE.test(input.entityId)) {\n return handlerErr(\n 400,\n \"INVALID_ENTITY_ID\",\n `entityId must be a decimal uint256 string, got \"${input.entityId}\"`,\n );\n }\n entityId = input.entityId;\n } else {\n if (!ADDRESS_RE.test(input.address)) {\n return handlerErr(\n 400,\n \"INVALID_ADDRESS\",\n `address must be a 20-byte 0x-prefixed hex string, got \"${input.address}\"`,\n );\n }\n const resolved = await resolveEntityId(ctx.coreSdkRead, {\n address: input.address,\n ...(input.role !== undefined ? { role: input.role } : {}),\n });\n if (!resolved.ok) {\n const status =\n resolved.code === \"NOT_FOUND\" ? 404 : resolved.code === \"AMBIGUOUS\" ? 409 : 502;\n const details =\n resolved.code === \"AMBIGUOUS\"\n ? {\n ...(resolved.sellerIds !== undefined ? { sellerIds: resolved.sellerIds } : {}),\n ...(resolved.buyerIds !== undefined ? { buyerIds: resolved.buyerIds } : {}),\n }\n : undefined;\n return handlerErr(status, resolved.code, resolved.reason, details);\n }\n entityId = resolved.entityId;\n role = resolved.role;\n }\n\n let result: Awaited<ReturnType<FacilitatorClient[\"performAction\"]>>;\n try {\n result = await ctx.facilitator.performAction({\n network: ctx.config.network,\n escrowAddress: ctx.config.escrow as Address,\n entityId,\n action: \"boson-withdrawFunds\",\n signedPayload: input.signedPayload,\n });\n } catch (e) {\n if (e instanceof FacilitatorHttpError) {\n return handlerErr(502, \"FACILITATOR_UNREACHABLE\", e.message, {\n code: e.code,\n status: e.status,\n facilitatorCode: e.facilitatorCode,\n });\n }\n throw e;\n }\n\n if (!result.ok) {\n return handlerErr(502, \"FACILITATOR_REJECTED\", result.reason, {\n facilitatorCode: result.code,\n });\n }\n\n return plainHandlerOk<WithdrawFundsOk>({\n txHash: result.txHash,\n entityId,\n ...(role !== undefined ? { role } : {}),\n });\n}\n","// Read-only handler returning a Boson entity's currently available\n// funds. Backed by `coreSdk.getFunds` against the protocol subgraph.\n//\n// Accepts either a raw `entityId` (the protocol's own numeric id) or an\n// EVM `address` (with optional `role` to disambiguate when the address\n// is registered as both a seller and a buyer).\n\nimport type { Address } from \"@bosonprotocol/x402-core/schemes/escrow\";\n\nimport type { CoreSdkReadAdapter } from \"../onchain/core-sdk-read.js\";\nimport { ADDRESS_RE, DECIMAL_UINT_RE } from \"./entity-input-validators.js\";\nimport { handlerErr, plainHandlerOk, type PlainHandlerResult } from \"./types.js\";\nimport { resolveEntityId } from \"./resolve-entity.js\";\n\nexport interface AvailableFundsEntry {\n tokenAddress: Address;\n tokenSymbol: string;\n tokenName: string;\n decimals: number;\n availableAmount: string;\n}\n\nexport interface AvailableFundsBody {\n entityId: string;\n /** Present when the caller looked up by `address`; omitted when looked up by `entityId`. */\n role?: \"buyer\" | \"seller\";\n funds: AvailableFundsEntry[];\n}\n\nexport type AvailableFundsQuery =\n | { entityId: string }\n | { address: string; role?: \"buyer\" | \"seller\" };\n\nexport interface AvailableFundsContext {\n coreSdkRead: CoreSdkReadAdapter;\n}\n\nexport async function handleGetAvailableFunds(\n query: AvailableFundsQuery,\n ctx: AvailableFundsContext,\n): Promise<PlainHandlerResult<AvailableFundsBody>> {\n let entityId: string;\n let role: \"buyer\" | \"seller\" | undefined;\n\n if (\"entityId\" in query) {\n if (!DECIMAL_UINT_RE.test(query.entityId)) {\n return handlerErr(\n 400,\n \"INVALID_ENTITY_ID\",\n `entityId must be a decimal uint256 string, got \"${query.entityId}\"`,\n );\n }\n entityId = query.entityId;\n } else {\n if (!ADDRESS_RE.test(query.address)) {\n return handlerErr(\n 400,\n \"INVALID_ADDRESS\",\n `address must be a 20-byte 0x-prefixed hex string, got \"${query.address}\"`,\n );\n }\n const resolved = await resolveEntityId(ctx.coreSdkRead, {\n address: query.address,\n ...(query.role !== undefined ? { role: query.role } : {}),\n });\n if (!resolved.ok) {\n const status =\n resolved.code === \"NOT_FOUND\" ? 404 : resolved.code === \"AMBIGUOUS\" ? 409 : 502;\n return handlerErr(status, resolved.code, resolved.reason, omitErrorMetadata(resolved));\n }\n entityId = resolved.entityId;\n role = resolved.role;\n }\n\n let raw;\n try {\n raw = await ctx.coreSdkRead.getFunds({ fundsFilter: { accountId: entityId } });\n } catch (e) {\n return handlerErr(\n 502,\n \"SUBGRAPH_FAILURE\",\n e instanceof Error ? e.message : \"subgraph getFunds lookup failed\",\n );\n }\n\n const funds: AvailableFundsEntry[] = raw.map((entry) => ({\n tokenAddress: entry.token.address as Address,\n tokenSymbol: entry.token.symbol,\n tokenName: entry.token.name,\n decimals: Number(entry.token.decimals),\n availableAmount: entry.availableAmount,\n }));\n\n return plainHandlerOk<AvailableFundsBody>({\n entityId,\n ...(role !== undefined ? { role } : {}),\n funds,\n });\n}\n\nfunction omitErrorMetadata(resolved: {\n code: string;\n sellerIds?: string[];\n buyerIds?: string[];\n}): Record<string, string[]> | undefined {\n if (resolved.code !== \"AMBIGUOUS\") return undefined;\n const details: Record<string, string[]> = {};\n if (resolved.sellerIds !== undefined) details.sellerIds = resolved.sellerIds;\n if (resolved.buyerIds !== undefined) details.buyerIds = resolved.buyerIds;\n return Object.keys(details).length > 0 ? details : undefined;\n}\n","// Minimal read-only adapter over `@bosonprotocol/core-sdk` used by the\n// `withdraw-funds` and `available-funds` handlers.\n//\n// The full `CoreSDK` type pulls in a lot of surface area (every facet,\n// every signing helper) — none of which the read paths need. Narrowing\n// it to a structural interface keeps the server's dependency\n// footprint small for consumers that just want to expose the read\n// endpoints (and lets tests pass a hand-rolled stub without\n// constructing a real CoreSDK).\n\nimport type { CoreSDK } from \"@bosonprotocol/core-sdk\";\n\n/** Funds entity returned by `coreSdk.getFunds` — narrowed to the fields the handler reshapes. */\nexport interface CoreSdkFundsEntity {\n id?: string;\n accountId: string;\n availableAmount: string;\n token: {\n address: string;\n decimals: string;\n symbol: string;\n name: string;\n };\n}\n\n/** Seller entity returned by `coreSdk.getSellersByAddress` — only the id is consumed. */\nexport interface CoreSdkSellerEntity {\n id: string;\n}\n\n/** Buyer entity returned by `coreSdk.getBuyers` — only the id is consumed. */\nexport interface CoreSdkBuyerEntity {\n id: string;\n}\n\n/**\n * The subset of `CoreSDK` the read-only handlers actually use. Both the\n * real `CoreSDK` and a hand-rolled stub for tests satisfy this shape.\n */\nexport interface CoreSdkReadAdapter {\n getFunds(queryVars: { fundsFilter: { accountId: string } }): Promise<CoreSdkFundsEntity[]>;\n getSellersByAddress(address: string): Promise<CoreSdkSellerEntity[]>;\n getBuyers(queryVars: { buyersFilter: { wallet: string } }): Promise<CoreSdkBuyerEntity[]>;\n}\n\n/**\n * Cast a full `CoreSDK` to the narrowed adapter shape. Structural-only;\n * does not capture or wrap anything.\n */\nexport function asCoreSdkReadAdapter(coreSdk: CoreSDK): CoreSdkReadAdapter {\n return coreSdk as unknown as CoreSdkReadAdapter;\n}\n","// `createX402bServer` — the per-server factory. Wires the 402\n// challenge builder + FullOffer signer (PR 1), and the convenience\n// handlers (commit, commit-and-redeem, redeem, complete, dispute/*,\n// withdraw-funds, available-funds) over the facilitator HTTP client +\n// configured `ExchangeReader` and read-only core-sdk client.\n\nimport { CoreSDK } from \"@bosonprotocol/core-sdk\";\nimport type { UnsignedFullOffer } from \"@bosonprotocol/x402-core/eip712\";\nimport type {\n BosonOfferRef,\n EscrowPaymentRequirements,\n} from \"@bosonprotocol/x402-core/schemes/escrow\";\n\nimport { createReadOnlyWeb3LibStub } from \"./onchain/web3lib-read-stub.js\";\n\nimport { buildPaymentRequirements } from \"./challenge/build-requirements.js\";\nimport { signFullOffer } from \"./challenge/sign-full-offer.js\";\nimport {\n assertChannelRegistryEscrowMatch,\n x402bServerConfigSchema,\n type FulfillmentRecoveryEntry,\n type X402bServerConfig,\n} from \"./config.js\";\nimport { createFacilitatorClient, type FacilitatorClient } from \"./facilitator/client.js\";\nimport {\n handleCommit,\n handleCommitAndRedeem,\n handleComplete,\n handleDisputeEscalate,\n handleDisputeRaise,\n handleDisputeResolve,\n handleDisputeRetract,\n handleGetAvailableFunds,\n handleRedeem,\n handleWithdrawFunds,\n type AvailableFundsBody,\n type AvailableFundsQuery,\n type CommitHandlerInput,\n type CommitOk,\n type HandlerResult,\n type PerformActionInput,\n type PerformActionOk,\n type PlainHandlerResult,\n type RedeemHandlerInput,\n type WithdrawFundsInput,\n type WithdrawFundsOk,\n} from \"./handlers/index.js\";\nimport { stampFacilitatorEndpoints } from \"./internal/facilitator-endpoints.js\";\nimport { asCoreSdkReadAdapter, type CoreSdkReadAdapter } from \"./onchain/core-sdk-read.js\";\nimport type { ExchangeReader } from \"./onchain/verify-exchange.js\";\n\n/** Per-offer inputs for `server.buildPaymentRequirements` — everything the offer-level args carry, minus the per-server context the factory already holds. */\nexport interface BuildRequirementsInput {\n /** Already-signed offer reference, or `{ unsigned }` to have the server sign it. */\n offer: BosonOfferRef | { unsigned: UnsignedFullOffer };\n asset: string;\n amount: string;\n tokenAuthStrategies: readonly (\"none\" | \"erc3009\" | \"permit\" | \"permit2\")[];\n recipientId: string;\n maxTimeoutSeconds: number;\n fulfillment?: import(\"@bosonprotocol/x402-core/schemes/escrow\").FulfillmentRequirements;\n}\n\nexport interface X402bServer {\n readonly config: X402bServerConfig;\n readonly facilitator: FacilitatorClient;\n\n /** Sign an unsigned FullOffer with the configured seller signer. */\n signOffer(unsigned: UnsignedFullOffer): Promise<BosonOfferRef>;\n /** Build a 402 `EscrowPaymentRequirements`. */\n buildPaymentRequirements(input: BuildRequirementsInput): Promise<EscrowPaymentRequirements>;\n\n /** Convenience handlers — pure, framework-agnostic. The express adapter (PR 5) maps them to routes. */\n readonly handlers: {\n commit(input: CommitHandlerInput): Promise<HandlerResult<CommitOk>>;\n commitAndRedeem(input: CommitHandlerInput): Promise<HandlerResult<CommitOk>>;\n redeem(input: RedeemHandlerInput): Promise<HandlerResult<PerformActionOk>>;\n complete(input: PerformActionInput): Promise<HandlerResult<PerformActionOk>>;\n disputeRaise(input: PerformActionInput): Promise<HandlerResult<PerformActionOk>>;\n disputeResolve(input: PerformActionInput): Promise<HandlerResult<PerformActionOk>>;\n disputeRetract(input: PerformActionInput): Promise<HandlerResult<PerformActionOk>>;\n disputeEscalate(input: PerformActionInput): Promise<HandlerResult<PerformActionOk>>;\n withdrawFunds(input: WithdrawFundsInput): Promise<PlainHandlerResult<WithdrawFundsOk>>;\n getAvailableFunds(query: AvailableFundsQuery): Promise<PlainHandlerResult<AvailableFundsBody>>;\n };\n}\n\nfunction withFacilitatorEndpoints(\n requirements: EscrowPaymentRequirements,\n facilitatorUrl: string,\n): EscrowPaymentRequirements {\n return {\n ...requirements,\n actions: {\n ...requirements.actions,\n next: stampFacilitatorEndpoints(requirements.actions.next, facilitatorUrl),\n },\n };\n}\n\n/**\n * Validate a config and return a `X402bServer` whose methods are\n * bound to the validated context. Throws synchronously (`ZodError`)\n * on bad config or (`Error`) on the escrow / channel-registry escrow\n * mismatch.\n */\nexport function createX402bServer(config: X402bServerConfig): X402bServer {\n const validated = x402bServerConfigSchema.parse(config) as X402bServerConfig;\n assertChannelRegistryEscrowMatch(validated);\n\n const facilitator = createFacilitatorClient({ url: validated.facilitator.url });\n // Default to a fresh in-memory store when the host doesn't supply\n // one. Single shared reference for the lifetime of this server — so\n // commit-time writes and redeem-time reads observe the same Map.\n const exchangeFulfillmentOptionStore: Map<string, readonly string[]> =\n validated.exchangeFulfillmentOptionStore ?? new Map();\n const fulfillmentRecoveryStore: Map<string, FulfillmentRecoveryEntry> =\n validated.fulfillmentRecoveryStore ?? new Map();\n validated.exchangeFulfillmentOptionStore = exchangeFulfillmentOptionStore;\n validated.fulfillmentRecoveryStore = fulfillmentRecoveryStore;\n\n const signOffer = (unsigned: UnsignedFullOffer): Promise<BosonOfferRef> =>\n signFullOffer({\n fullOffer: unsigned,\n signer: validated.signer,\n escrow: validated.escrow,\n chainId: validated.chainId,\n });\n\n const requireReader = async (action: string): Promise<ExchangeReader> => {\n if (validated.exchangeReader === undefined) {\n throw new Error(\n `x402-server: handlers.${action}() requires \\`exchangeReader\\` in config (post-settle state verification step).`,\n );\n }\n return validated.exchangeReader;\n };\n\n // Lazy-memoised read-only core-sdk. The construction itself is cheap\n // but happens on every `handlers.withdrawFunds()` /\n // `handlers.getAvailableFunds()` call — caching the adapter keeps the\n // hot path allocation-free and shares one subgraph client across\n // requests. `validated.coreSdkRead`, when supplied by the host, is\n // already shared.\n let cachedCoreSdkRead: CoreSdkReadAdapter | undefined;\n const requireCoreSdkRead = (action: string): CoreSdkReadAdapter => {\n if (validated.coreSdkRead !== undefined) return validated.coreSdkRead;\n if (cachedCoreSdkRead !== undefined) return cachedCoreSdkRead;\n if (validated.subgraphUrl === undefined) {\n throw new Error(\n `x402-server: handlers.${action}() requires either \\`coreSdkRead\\` or \\`subgraphUrl\\` in config (subgraph read step).`,\n );\n }\n cachedCoreSdkRead = asCoreSdkReadAdapter(\n new CoreSDK({\n web3Lib: createReadOnlyWeb3LibStub(),\n subgraphUrl: validated.subgraphUrl,\n protocolDiamond: validated.escrow,\n chainId: validated.chainId,\n }),\n );\n return cachedCoreSdkRead;\n };\n\n return {\n config: validated,\n facilitator,\n signOffer,\n async buildPaymentRequirements(input) {\n const offer = \"unsigned\" in input.offer ? await signOffer(input.offer.unsigned) : input.offer;\n const requirements = buildPaymentRequirements({\n offer,\n asset: input.offer && \"unsigned\" in input.offer ? input.asset : input.asset,\n amount: input.amount,\n tokenAuthStrategies: input.tokenAuthStrategies,\n recipientId: input.recipientId,\n maxTimeoutSeconds: input.maxTimeoutSeconds,\n ...(input.fulfillment !== undefined ? { fulfillment: input.fulfillment } : {}),\n network: validated.network,\n escrow: validated.escrow,\n channelRegistry: validated.channelRegistry,\n });\n return withFacilitatorEndpoints(requirements, validated.facilitator.url);\n },\n handlers: {\n commit: async (input) =>\n handleCommit(input, {\n config: validated,\n facilitator,\n exchangeReader: await requireReader(\"commit\"),\n fulfillmentRecoveryStore,\n exchangeFulfillmentOptionStore,\n }),\n commitAndRedeem: async (input) =>\n handleCommitAndRedeem(input, {\n config: validated,\n facilitator,\n exchangeReader: await requireReader(\"commitAndRedeem\"),\n fulfillmentRecoveryStore,\n exchangeFulfillmentOptionStore,\n }),\n redeem: async (input) =>\n handleRedeem(input, {\n config: validated,\n facilitator,\n exchangeReader: await requireReader(\"redeem\"),\n exchangeFulfillmentOptionStore,\n fulfillmentRecoveryStore,\n }),\n complete: async (input) =>\n handleComplete(input, {\n config: validated,\n facilitator,\n exchangeReader: await requireReader(\"complete\"),\n }),\n disputeRaise: async (input) =>\n handleDisputeRaise(input, {\n config: validated,\n facilitator,\n exchangeReader: await requireReader(\"disputeRaise\"),\n }),\n disputeResolve: async (input) =>\n handleDisputeResolve(input, {\n config: validated,\n facilitator,\n exchangeReader: await requireReader(\"disputeResolve\"),\n }),\n disputeRetract: async (input) =>\n handleDisputeRetract(input, {\n config: validated,\n facilitator,\n exchangeReader: await requireReader(\"disputeRetract\"),\n }),\n disputeEscalate: async (input) =>\n handleDisputeEscalate(input, {\n config: validated,\n facilitator,\n exchangeReader: await requireReader(\"disputeEscalate\"),\n }),\n withdrawFunds: async (input) =>\n handleWithdrawFunds(input, {\n config: validated,\n facilitator,\n coreSdkRead: requireCoreSdkRead(\"withdrawFunds\"),\n }),\n getAvailableFunds: async (query) =>\n handleGetAvailableFunds(query, {\n coreSdkRead: requireCoreSdkRead(\"getAvailableFunds\"),\n }),\n },\n };\n}\n","// Encoder for the `X-PAYMENT-RESPONSE` header. The base x402 spec uses\n// base64-of-JSON for `X-PAYMENT-RESPONSE`, and the buyer SDK's\n// `parsePaymentResponse` ([client/src/response.ts]) decodes it the\n// same way. This helper is the inverse — give it the success body and\n// it produces the header value.\n//\n// The header is best-effort metadata that lets the client read\n// `exchangeId` (and any future scheme-specific fields) without parsing\n// the full JSON body. We pass the body through verbatim so the wire\n// shape is identical to the response body; consumers stay free to\n// branch on either.\n\n/**\n * Base64-encode the success-response body for the `X-PAYMENT-RESPONSE`\n * header. The companion decoder lives in\n * `@bosonprotocol/x402-client`'s `parsePaymentResponse`.\n */\nexport function encodeXPaymentResponse(body: unknown): string {\n const json = JSON.stringify(body);\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(json, \"utf8\").toString(\"base64\");\n }\n // Node ships `Buffer`; the browser fallback exists for completeness so\n // a non-Node integrator (Workers, Deno) can reuse this helper.\n const bytes = new TextEncoder().encode(json);\n let binary = \"\";\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\n/** Canonical header name — exported so adapters share one spelling. */\nexport const X_PAYMENT_RESPONSE_HEADER = \"X-PAYMENT-RESPONSE\" as const;\n"]}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { ExchangeState, DisputeState } from '@bosonprotocol/x402-actions';
|
|
2
|
+
import { Address } from '@bosonprotocol/x402-core/schemes/escrow';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Minimal protocol-level snapshot of an exchange the verifier needs.
|
|
6
|
+
*
|
|
7
|
+
* Sourced by `ExchangeReader.read` — typical implementations:
|
|
8
|
+
*
|
|
9
|
+
* - `@bosonprotocol/core-sdk`'s `coreSDK.getExchangeById` (subgraph
|
|
10
|
+
* round-trip; tolerant of indexer lag).
|
|
11
|
+
* - A viem `publicClient.readContract` against
|
|
12
|
+
* `IBosonExchangeHandler.getExchange(exchangeId)` plus a follow-up
|
|
13
|
+
* `getOffer(offerId)` for `exchangeToken` + `price` (no indexer
|
|
14
|
+
* lag, costs an extra RPC call).
|
|
15
|
+
*/
|
|
16
|
+
interface ExchangeSnapshot {
|
|
17
|
+
state: ExchangeState;
|
|
18
|
+
/** Present when `state === ExchangeState.DISPUTED`. */
|
|
19
|
+
disputeState?: DisputeState;
|
|
20
|
+
seller: Address;
|
|
21
|
+
exchangeToken: Address;
|
|
22
|
+
/** Atomic units, decimal string. */
|
|
23
|
+
price: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Pluggable reader for the post-settle / post-perform-action state
|
|
27
|
+
* verification step. The reader returns `null` iff the exchange id
|
|
28
|
+
* doesn't yet exist in the data source (subgraph not yet indexed,
|
|
29
|
+
* `getExchange` reverts on a non-existent id, etc.). `verifyExchange`
|
|
30
|
+
* retries transient not-found / stale-state results with a bounded wait.
|
|
31
|
+
*/
|
|
32
|
+
interface ExchangeReader {
|
|
33
|
+
read(exchangeId: string): Promise<ExchangeSnapshot | null>;
|
|
34
|
+
}
|
|
35
|
+
interface VerifyExchangeExpected {
|
|
36
|
+
state: ExchangeState;
|
|
37
|
+
/** Present iff `state === ExchangeState.DISPUTED`. */
|
|
38
|
+
disputeState?: DisputeState;
|
|
39
|
+
seller: Address;
|
|
40
|
+
exchangeToken: Address;
|
|
41
|
+
price: string;
|
|
42
|
+
}
|
|
43
|
+
type VerifyExchangeResult = {
|
|
44
|
+
ok: true;
|
|
45
|
+
} | {
|
|
46
|
+
ok: false;
|
|
47
|
+
code: VerifyExchangeErrorCode;
|
|
48
|
+
field?: string;
|
|
49
|
+
expected?: unknown;
|
|
50
|
+
got?: unknown;
|
|
51
|
+
};
|
|
52
|
+
type VerifyExchangeErrorCode = "EXCHANGE_NOT_FOUND" | "STATE_MISMATCH" | "DISPUTE_STATE_MISMATCH" | "SELLER_MISMATCH" | "TOKEN_MISMATCH" | "PRICE_MISMATCH";
|
|
53
|
+
interface VerifyExchangeOptions {
|
|
54
|
+
/** Maximum read/compare attempts. Defaults to 3. */
|
|
55
|
+
attempts?: number;
|
|
56
|
+
/** Delay between retryable attempts in milliseconds. Defaults to 50. */
|
|
57
|
+
delayMs?: number;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Compare a snapshot against the expected post-state. Short-circuits
|
|
61
|
+
* at the first mismatch. Pure; the reader does the I/O.
|
|
62
|
+
*/
|
|
63
|
+
declare function verifyExchangeSnapshot(snapshot: ExchangeSnapshot | null, expected: VerifyExchangeExpected): VerifyExchangeResult;
|
|
64
|
+
/**
|
|
65
|
+
* High-level convenience — read via the configured `ExchangeReader`
|
|
66
|
+
* and apply `verifyExchangeSnapshot`. Retries boundedly when a reader
|
|
67
|
+
* may be behind the just-mined transaction (`EXCHANGE_NOT_FOUND`,
|
|
68
|
+
* `STATE_MISMATCH`, or `DISPUTE_STATE_MISMATCH`), then returns the
|
|
69
|
+
* last comparison result.
|
|
70
|
+
*/
|
|
71
|
+
declare function verifyExchange(reader: ExchangeReader, exchangeId: string, expected: VerifyExchangeExpected, options?: VerifyExchangeOptions): Promise<VerifyExchangeResult>;
|
|
72
|
+
|
|
73
|
+
export { type ExchangeReader, type ExchangeSnapshot, type VerifyExchangeErrorCode, type VerifyExchangeExpected, type VerifyExchangeOptions, type VerifyExchangeResult, verifyExchange, verifyExchangeSnapshot };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var x402Actions = require('@bosonprotocol/x402-actions');
|
|
4
|
+
|
|
5
|
+
// src/onchain/verify-exchange.ts
|
|
6
|
+
function verifyExchangeSnapshot(snapshot, expected) {
|
|
7
|
+
if (snapshot === null) {
|
|
8
|
+
return { ok: false, code: "EXCHANGE_NOT_FOUND" };
|
|
9
|
+
}
|
|
10
|
+
if (snapshot.state !== expected.state) {
|
|
11
|
+
return {
|
|
12
|
+
ok: false,
|
|
13
|
+
code: "STATE_MISMATCH",
|
|
14
|
+
field: "state",
|
|
15
|
+
expected: expected.state,
|
|
16
|
+
got: snapshot.state
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
if (expected.state === x402Actions.ExchangeState.DISPUTED) {
|
|
20
|
+
if (snapshot.disputeState !== expected.disputeState) {
|
|
21
|
+
return {
|
|
22
|
+
ok: false,
|
|
23
|
+
code: "DISPUTE_STATE_MISMATCH",
|
|
24
|
+
field: "disputeState",
|
|
25
|
+
expected: expected.disputeState,
|
|
26
|
+
got: snapshot.disputeState
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (snapshot.seller.toLowerCase() !== expected.seller.toLowerCase()) {
|
|
31
|
+
return {
|
|
32
|
+
ok: false,
|
|
33
|
+
code: "SELLER_MISMATCH",
|
|
34
|
+
field: "seller",
|
|
35
|
+
expected: expected.seller,
|
|
36
|
+
got: snapshot.seller
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
if (snapshot.exchangeToken.toLowerCase() !== expected.exchangeToken.toLowerCase()) {
|
|
40
|
+
return {
|
|
41
|
+
ok: false,
|
|
42
|
+
code: "TOKEN_MISMATCH",
|
|
43
|
+
field: "exchangeToken",
|
|
44
|
+
expected: expected.exchangeToken,
|
|
45
|
+
got: snapshot.exchangeToken
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
if (snapshot.price !== expected.price) {
|
|
49
|
+
return {
|
|
50
|
+
ok: false,
|
|
51
|
+
code: "PRICE_MISMATCH",
|
|
52
|
+
field: "price",
|
|
53
|
+
expected: expected.price,
|
|
54
|
+
got: snapshot.price
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return { ok: true };
|
|
58
|
+
}
|
|
59
|
+
async function verifyExchange(reader, exchangeId, expected, options = {}) {
|
|
60
|
+
const attempts = Math.max(1, Math.floor(options.attempts ?? 3));
|
|
61
|
+
const delayMs = Math.max(0, Math.floor(options.delayMs ?? 50));
|
|
62
|
+
let result = { ok: false, code: "EXCHANGE_NOT_FOUND" };
|
|
63
|
+
for (let attempt = 1; attempt <= attempts; attempt += 1) {
|
|
64
|
+
const snapshot = await reader.read(exchangeId);
|
|
65
|
+
result = verifyExchangeSnapshot(snapshot, expected);
|
|
66
|
+
if (result.ok || !isRetryableVerifyResult(result) || attempt === attempts) {
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
if (delayMs > 0) {
|
|
70
|
+
await delay(delayMs);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
function isRetryableVerifyResult(result) {
|
|
76
|
+
return !result.ok && (result.code === "EXCHANGE_NOT_FOUND" || result.code === "STATE_MISMATCH" || result.code === "DISPUTE_STATE_MISMATCH");
|
|
77
|
+
}
|
|
78
|
+
async function delay(ms) {
|
|
79
|
+
await new Promise((resolve) => {
|
|
80
|
+
setTimeout(resolve, ms);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
exports.verifyExchange = verifyExchange;
|
|
85
|
+
exports.verifyExchangeSnapshot = verifyExchangeSnapshot;
|
|
86
|
+
//# sourceMappingURL=index.js.map
|
|
87
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/onchain/verify-exchange.ts"],"names":["ExchangeState"],"mappings":"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","file":"index.js","sourcesContent":["// On-chain (or off-chain — subgraph) verification of an exchange's\n// state after a facilitator settle / perform-action. The reader is\n// pluggable so callers can wire up a subgraph query, a viem RPC\n// read, or core-sdk's `exchanges.handler.getExchange` without\n// x402-server taking a hard dependency on any one mechanism.\n//\n// The verifier itself is pure: given a snapshot + the four-field\n// expectation from boson-impl-02-flows.md Flow A/B \"Verify\" step\n// (state, seller, exchangeToken, price), it returns a structured\n// pass / fail result.\n\nimport { DisputeState, ExchangeState } from \"@bosonprotocol/x402-actions\";\nimport type { Address } from \"@bosonprotocol/x402-core/schemes/escrow\";\n\n/**\n * Minimal protocol-level snapshot of an exchange the verifier needs.\n *\n * Sourced by `ExchangeReader.read` — typical implementations:\n *\n * - `@bosonprotocol/core-sdk`'s `coreSDK.getExchangeById` (subgraph\n * round-trip; tolerant of indexer lag).\n * - A viem `publicClient.readContract` against\n * `IBosonExchangeHandler.getExchange(exchangeId)` plus a follow-up\n * `getOffer(offerId)` for `exchangeToken` + `price` (no indexer\n * lag, costs an extra RPC call).\n */\nexport interface ExchangeSnapshot {\n state: ExchangeState;\n /** Present when `state === ExchangeState.DISPUTED`. */\n disputeState?: DisputeState;\n seller: Address;\n exchangeToken: Address;\n /** Atomic units, decimal string. */\n price: string;\n}\n\n/**\n * Pluggable reader for the post-settle / post-perform-action state\n * verification step. The reader returns `null` iff the exchange id\n * doesn't yet exist in the data source (subgraph not yet indexed,\n * `getExchange` reverts on a non-existent id, etc.). `verifyExchange`\n * retries transient not-found / stale-state results with a bounded wait.\n */\nexport interface ExchangeReader {\n read(exchangeId: string): Promise<ExchangeSnapshot | null>;\n}\n\nexport interface VerifyExchangeExpected {\n state: ExchangeState;\n /** Present iff `state === ExchangeState.DISPUTED`. */\n disputeState?: DisputeState;\n seller: Address;\n exchangeToken: Address;\n price: string;\n}\n\nexport type VerifyExchangeResult =\n | { ok: true }\n | { ok: false; code: VerifyExchangeErrorCode; field?: string; expected?: unknown; got?: unknown };\n\nexport type VerifyExchangeErrorCode =\n | \"EXCHANGE_NOT_FOUND\"\n | \"STATE_MISMATCH\"\n | \"DISPUTE_STATE_MISMATCH\"\n | \"SELLER_MISMATCH\"\n | \"TOKEN_MISMATCH\"\n | \"PRICE_MISMATCH\";\n\nexport interface VerifyExchangeOptions {\n /** Maximum read/compare attempts. Defaults to 3. */\n attempts?: number;\n /** Delay between retryable attempts in milliseconds. Defaults to 50. */\n delayMs?: number;\n}\n\n/**\n * Compare a snapshot against the expected post-state. Short-circuits\n * at the first mismatch. Pure; the reader does the I/O.\n */\nexport function verifyExchangeSnapshot(\n snapshot: ExchangeSnapshot | null,\n expected: VerifyExchangeExpected,\n): VerifyExchangeResult {\n if (snapshot === null) {\n return { ok: false, code: \"EXCHANGE_NOT_FOUND\" };\n }\n if (snapshot.state !== expected.state) {\n return {\n ok: false,\n code: \"STATE_MISMATCH\",\n field: \"state\",\n expected: expected.state,\n got: snapshot.state,\n };\n }\n if (expected.state === ExchangeState.DISPUTED) {\n if (snapshot.disputeState !== expected.disputeState) {\n return {\n ok: false,\n code: \"DISPUTE_STATE_MISMATCH\",\n field: \"disputeState\",\n expected: expected.disputeState,\n got: snapshot.disputeState,\n };\n }\n }\n if (snapshot.seller.toLowerCase() !== expected.seller.toLowerCase()) {\n return {\n ok: false,\n code: \"SELLER_MISMATCH\",\n field: \"seller\",\n expected: expected.seller,\n got: snapshot.seller,\n };\n }\n if (snapshot.exchangeToken.toLowerCase() !== expected.exchangeToken.toLowerCase()) {\n return {\n ok: false,\n code: \"TOKEN_MISMATCH\",\n field: \"exchangeToken\",\n expected: expected.exchangeToken,\n got: snapshot.exchangeToken,\n };\n }\n if (snapshot.price !== expected.price) {\n return {\n ok: false,\n code: \"PRICE_MISMATCH\",\n field: \"price\",\n expected: expected.price,\n got: snapshot.price,\n };\n }\n return { ok: true };\n}\n\n/**\n * High-level convenience — read via the configured `ExchangeReader`\n * and apply `verifyExchangeSnapshot`. Retries boundedly when a reader\n * may be behind the just-mined transaction (`EXCHANGE_NOT_FOUND`,\n * `STATE_MISMATCH`, or `DISPUTE_STATE_MISMATCH`), then returns the\n * last comparison result.\n */\nexport async function verifyExchange(\n reader: ExchangeReader,\n exchangeId: string,\n expected: VerifyExchangeExpected,\n options: VerifyExchangeOptions = {},\n): Promise<VerifyExchangeResult> {\n const attempts = Math.max(1, Math.floor(options.attempts ?? 3));\n const delayMs = Math.max(0, Math.floor(options.delayMs ?? 50));\n let result: VerifyExchangeResult = { ok: false, code: \"EXCHANGE_NOT_FOUND\" };\n\n for (let attempt = 1; attempt <= attempts; attempt += 1) {\n const snapshot = await reader.read(exchangeId);\n result = verifyExchangeSnapshot(snapshot, expected);\n if (result.ok || !isRetryableVerifyResult(result) || attempt === attempts) {\n return result;\n }\n if (delayMs > 0) {\n await delay(delayMs);\n }\n }\n\n return result;\n}\n\nfunction isRetryableVerifyResult(result: VerifyExchangeResult): boolean {\n return (\n !result.ok &&\n (result.code === \"EXCHANGE_NOT_FOUND\" ||\n result.code === \"STATE_MISMATCH\" ||\n result.code === \"DISPUTE_STATE_MISMATCH\")\n );\n}\n\nasync function delay(ms: number): Promise<void> {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n"]}
|