@bosonprotocol/x402-server 0.2.0 → 0.3.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.
@@ -0,0 +1,292 @@
1
+ import { EscrowPaymentRequirements, Address } from '@bosonprotocol/x402-core/schemes/escrow';
2
+ import { EscrowNextActions, ExchangeState, DisputeState, ChannelRegistry } from '@bosonprotocol/x402-actions';
3
+ import { ExchangeReader } from './onchain/index.js';
4
+ import { a as FacilitatorClient, L as Logger } from './client-B2yejopi.js';
5
+ import { X as X402bServerConfig, e as Store, F as FulfillmentRecoveryEntry, C as CoreSdkReadAdapter } from './config-hnCiZiXF.js';
6
+ import { ExchangeActionId } from '@bosonprotocol/x402-core/state-machine';
7
+ import { Hex } from 'viem';
8
+
9
+ /** JSON-safe view of a `FulfillmentResult` for the response body. */
10
+ type SerializedFulfillmentResult = {
11
+ kind: "inline";
12
+ body: string;
13
+ contentType: string;
14
+ } | {
15
+ kind: "async";
16
+ pointer?: string;
17
+ };
18
+
19
+ type HandlerStatus = 200 | 400 | 402 | 404 | 409 | 500 | 502;
20
+ type HandlerResult<TBody> = {
21
+ ok: true;
22
+ status: 200;
23
+ body: TBody & {
24
+ nextActions: EscrowNextActions;
25
+ };
26
+ } | {
27
+ ok: false;
28
+ status: Exclude<HandlerStatus, 200>;
29
+ body: HandlerErrorBody;
30
+ };
31
+ /**
32
+ * Result shape for handlers whose success body does NOT carry a
33
+ * `nextActions` envelope — used by entity-keyed actions
34
+ * (`boson-withdrawFunds`) and the read-only `available-funds`
35
+ * endpoint, neither of which advance the exchange state machine.
36
+ */
37
+ type PlainHandlerResult<TBody> = {
38
+ ok: true;
39
+ status: 200;
40
+ body: TBody;
41
+ } | {
42
+ ok: false;
43
+ status: Exclude<HandlerStatus, 200>;
44
+ body: HandlerErrorBody;
45
+ };
46
+ interface HandlerErrorBody {
47
+ /** Stable identifier — caller branches on this rather than the human-readable `reason`. */
48
+ code: string;
49
+ reason: string;
50
+ /** Optional rich detail — validator field/expected/got, facilitator code, etc. */
51
+ details?: unknown;
52
+ }
53
+ interface HandlerWarning {
54
+ /** Stable identifier — caller branches on this rather than the human-readable `reason`. */
55
+ code: string;
56
+ reason: string;
57
+ /** Optional rich detail — tx hash, exchange id, deferred operation, etc. */
58
+ details?: unknown;
59
+ }
60
+ declare function handlerOk<TBody>(body: TBody & {
61
+ nextActions: EscrowNextActions;
62
+ }): HandlerResult<TBody>;
63
+ declare function plainHandlerOk<TBody>(body: TBody): PlainHandlerResult<TBody>;
64
+ declare function handlerErr(status: Exclude<HandlerStatus, 200>, code: string, reason: string, details?: unknown): HandlerResult<never> & PlainHandlerResult<never>;
65
+
66
+ interface CommitHandlerInput {
67
+ /** Raw `X-PAYMENT` header value (base64'd JSON). */
68
+ paymentHeader: string | undefined | null;
69
+ /** The 402 `PaymentRequirements` the buyer is responding to. */
70
+ requirements: EscrowPaymentRequirements;
71
+ }
72
+ interface CommitHandlerContext {
73
+ config: X402bServerConfig;
74
+ facilitator: FacilitatorClient;
75
+ exchangeReader: ExchangeReader;
76
+ fulfillmentRecoveryStore: Store<FulfillmentRecoveryEntry>;
77
+ /**
78
+ * Per-exchange fulfillment option policy. Flow A writes the ids
79
+ * advertised by the original requirements so the redeem-time choice
80
+ * is constrained to the offer's own channel set.
81
+ */
82
+ exchangeFulfillmentOptionStore: Store<readonly string[]>;
83
+ /** Optional structured logger. Defaults to no-op when absent. */
84
+ logger?: Logger;
85
+ }
86
+ interface CommitOk {
87
+ exchangeId: string;
88
+ txHash: string;
89
+ /**
90
+ * Non-fatal post-settle conditions. Today only Flow B uses this slot —
91
+ * the on-chain redeem may have succeeded while the configured channel
92
+ * adapter's `onCommit(...)` failed (the buyer's funds and voucher are
93
+ * already gone; the seller's host needs to recover the delivery target
94
+ * out-of-band). The exchange state is the wire-format source of truth;
95
+ * warnings are advisory.
96
+ */
97
+ warnings?: HandlerWarning[];
98
+ /**
99
+ * Delivery outcome from the fulfillment channel's `onFulfill`, when one
100
+ * ran. Only Flow B reaches REDEEMED in this handler, so only Flow B can
101
+ * populate it; `async` carries the out-of-band `pointer`, `inline` a
102
+ * base64 `body`. Absent when no channel delivered.
103
+ */
104
+ fulfillment?: SerializedFulfillmentResult;
105
+ }
106
+ /**
107
+ * Flow A — `boson-createOfferAndCommit`. Settles via facilitator,
108
+ * expects the resulting exchange in `COMMITTED`, returns 200 with
109
+ * `nextActions` advertising the legal post-COMMITTED transitions.
110
+ */
111
+ declare function handleCommit(input: CommitHandlerInput, ctx: CommitHandlerContext): Promise<HandlerResult<CommitOk>>;
112
+ /**
113
+ * Flow B — `boson-createOfferCommitAndRedeem`. Same pipeline as
114
+ * `handleCommit` but verifies the exchange reached `REDEEMED`.
115
+ */
116
+ declare function handleCommitAndRedeem(input: CommitHandlerInput, ctx: CommitHandlerContext): Promise<HandlerResult<CommitOk>>;
117
+
118
+ /** Per-action inputs accepted by every post-commit convenience handler. */
119
+ interface PerformActionInput {
120
+ exchangeId: string;
121
+ /** ABI-encoded `BosonMetaTx` tuple — see `encodeSignedPayload` in `@bosonprotocol/x402-facilitator`. */
122
+ signedPayload: Hex;
123
+ }
124
+ /**
125
+ * Redeem-time variant of `PerformActionInput`. Carries the buyer's
126
+ * `fulfillment` selection for Flow A — `data` is the delivery target
127
+ * the redeem-time channel adapter persists. Required when the
128
+ * original 402 advertised `fulfillment.required = true`; omitted
129
+ * otherwise.
130
+ */
131
+ interface RedeemHandlerInput extends PerformActionInput {
132
+ fulfillment?: {
133
+ option: string;
134
+ data: Record<string, unknown> | null;
135
+ };
136
+ }
137
+ interface PerformActionContext {
138
+ config: X402bServerConfig;
139
+ facilitator: FacilitatorClient;
140
+ exchangeReader: ExchangeReader;
141
+ /** Optional structured logger. Defaults to no-op when absent. */
142
+ logger?: Logger;
143
+ }
144
+ interface RedeemHandlerContext extends PerformActionContext {
145
+ exchangeFulfillmentOptionStore: Store<readonly string[]>;
146
+ fulfillmentRecoveryStore: Store<FulfillmentRecoveryEntry>;
147
+ }
148
+ interface PerformActionOk {
149
+ txHash: string;
150
+ warnings?: HandlerWarning[];
151
+ /**
152
+ * Delivery outcome from the fulfillment channel's `onFulfill`, when one
153
+ * ran (redeem carried `fulfillment` and the channel implements it).
154
+ * `async` carries the out-of-band `pointer` (e.g. `ipfs://…`); `inline`
155
+ * carries a base64 `body`. Absent when no channel delivered.
156
+ */
157
+ fulfillment?: SerializedFulfillmentResult;
158
+ }
159
+ /**
160
+ * Generic exchange-keyed post-commit handler — wired from each of the
161
+ * per-action wrappers below. Entity-keyed actions (e.g. `withdrawFunds`)
162
+ * have their own handler in `./withdraw-funds.ts`.
163
+ */
164
+ declare function handlePerformAction(action: ExchangeActionId, input: PerformActionInput, ctx: PerformActionContext): Promise<HandlerResult<PerformActionOk>>;
165
+ /**
166
+ * Redeem handler. Validates the buyer's `fulfillment` selection (if
167
+ * present) against the offer's advertised option set and the host's
168
+ * channel registry, runs the channel's `validate` up-front, then
169
+ * forwards to the facilitator. The corresponding
170
+ * `onCommit(exchangeId, data)` upsert is deferred until *after* the
171
+ * facilitator + state verification confirm the exchange reached
172
+ * `REDEEMED`, so a failed redeem leaves the stored delivery target
173
+ * unchanged. The voucher NFT is transferable; whichever wallet signs
174
+ * `boson-redeem` supplies the delivery data — it's the redeemer's
175
+ * choice end-to-end.
176
+ */
177
+ declare function handleRedeem(input: RedeemHandlerInput, ctx: RedeemHandlerContext): Promise<HandlerResult<PerformActionOk>>;
178
+ /** Per-action sugar — preserves the action id at the type level. */
179
+ declare const handleComplete: (input: PerformActionInput, ctx: PerformActionContext) => Promise<HandlerResult<PerformActionOk>>;
180
+ declare const handleDisputeRaise: (input: PerformActionInput, ctx: PerformActionContext) => Promise<HandlerResult<PerformActionOk>>;
181
+ declare const handleDisputeResolve: (input: PerformActionInput, ctx: PerformActionContext) => Promise<HandlerResult<PerformActionOk>>;
182
+ declare const handleDisputeRetract: (input: PerformActionInput, ctx: PerformActionContext) => Promise<HandlerResult<PerformActionOk>>;
183
+ declare const handleDisputeEscalate: (input: PerformActionInput, ctx: PerformActionContext) => Promise<HandlerResult<PerformActionOk>>;
184
+
185
+ interface WithdrawFundsBaseInput {
186
+ /** ABI-encoded `BosonMetaTx` tuple — see `encodeSignedPayload` in `@bosonprotocol/x402-evm/codec`. */
187
+ signedPayload: Hex;
188
+ }
189
+ type WithdrawFundsInput = WithdrawFundsBaseInput & ({
190
+ entityId: string;
191
+ } | {
192
+ address: string;
193
+ role?: "buyer" | "seller";
194
+ });
195
+ interface WithdrawFundsContext {
196
+ config: X402bServerConfig;
197
+ facilitator: FacilitatorClient;
198
+ coreSdkRead: CoreSdkReadAdapter;
199
+ }
200
+ interface WithdrawFundsOk {
201
+ txHash: string;
202
+ entityId: string;
203
+ role?: "buyer" | "seller";
204
+ }
205
+ declare function handleWithdrawFunds(input: WithdrawFundsInput, ctx: WithdrawFundsContext): Promise<PlainHandlerResult<WithdrawFundsOk>>;
206
+
207
+ interface AvailableFundsEntry {
208
+ tokenAddress: Address;
209
+ tokenSymbol: string;
210
+ tokenName: string;
211
+ decimals: number;
212
+ availableAmount: string;
213
+ }
214
+ interface AvailableFundsBody {
215
+ entityId: string;
216
+ /** Present when the caller looked up by `address`; omitted when looked up by `entityId`. */
217
+ role?: "buyer" | "seller";
218
+ funds: AvailableFundsEntry[];
219
+ }
220
+ type AvailableFundsQuery = {
221
+ entityId: string;
222
+ } | {
223
+ address: string;
224
+ role?: "buyer" | "seller";
225
+ };
226
+ interface AvailableFundsContext {
227
+ coreSdkRead: CoreSdkReadAdapter;
228
+ }
229
+ declare function handleGetAvailableFunds(query: AvailableFundsQuery, ctx: AvailableFundsContext): Promise<PlainHandlerResult<AvailableFundsBody>>;
230
+
231
+ interface ResolveEntityInput {
232
+ address: string;
233
+ role?: "buyer" | "seller";
234
+ }
235
+ interface ResolveEntityOk {
236
+ ok: true;
237
+ entityId: string;
238
+ role: "buyer" | "seller";
239
+ }
240
+ type ResolveEntityError = {
241
+ ok: false;
242
+ code: "NOT_FOUND";
243
+ reason: string;
244
+ } | {
245
+ ok: false;
246
+ code: "AMBIGUOUS";
247
+ reason: string;
248
+ /** Seller ids matching the address (one or many). Absent when no sellers matched. */
249
+ sellerIds?: string[];
250
+ /** Buyer ids matching the address (one or many). Absent when no buyers matched. */
251
+ buyerIds?: string[];
252
+ } | {
253
+ ok: false;
254
+ code: "SUBGRAPH_FAILURE";
255
+ reason: string;
256
+ };
257
+ type ResolveEntityResult = ResolveEntityOk | ResolveEntityError;
258
+ declare function resolveEntityId(coreSdk: CoreSdkReadAdapter, input: ResolveEntityInput): Promise<ResolveEntityResult>;
259
+
260
+ /** Boson account `entityId` — uint256 in decimal-string form, no leading zeros. */
261
+ declare const DECIMAL_UINT_RE: RegExp;
262
+ /** 20-byte EVM address, 0x-prefixed, any letter case (we normalise downstream). */
263
+ declare const ADDRESS_RE: RegExp;
264
+ /**
265
+ * Hex-string check for `signedPayload`. Requires `0x` followed by an
266
+ * *even* number of hex digits so the body decodes to whole bytes —
267
+ * odd-length payloads like `0xabc` would surface as
268
+ * `signedPayload decode failed: …` deep in the facilitator pipeline,
269
+ * which is a less precise 502 than the adapter-level 400 this regex
270
+ * catches. Stricter than core's `HEX_BYTES` (which permits odd
271
+ * lengths) so we keep this one local.
272
+ */
273
+ declare const HEX_BYTES_RE: RegExp;
274
+
275
+ type EmitNextActionsInput = {
276
+ exchangeId: string;
277
+ } & ({
278
+ exchangeState: Exclude<ExchangeState, typeof ExchangeState.DISPUTED>;
279
+ disputeState?: never;
280
+ } | {
281
+ exchangeState: typeof ExchangeState.DISPUTED;
282
+ disputeState: DisputeState;
283
+ });
284
+ /**
285
+ * Build the `nextActions` envelope a handler attaches to its 200 body.
286
+ * Pure wrapper; the logic beyond `deriveNextActions` is the
287
+ * `DISPUTED → disputeState required` narrowing and the optional
288
+ * facilitator-endpoint stamp.
289
+ */
290
+ declare function emitNextActions(input: EmitNextActionsInput, registry: ChannelRegistry, facilitatorUrl?: string): EscrowNextActions;
291
+
292
+ export { type AvailableFundsQuery as A, handleDisputeResolve as B, type CommitHandlerInput as C, DECIMAL_UINT_RE as D, type EmitNextActionsInput as E, handleDisputeRetract as F, handleGetAvailableFunds as G, type HandlerResult as H, handlePerformAction as I, handleRedeem as J, handleWithdrawFunds as K, handlerErr as L, handlerOk as M, plainHandlerOk as N, resolveEntityId as O, type PerformActionOk as P, type RedeemHandlerInput as R, type SerializedFulfillmentResult as S, type WithdrawFundsInput as W, type CommitOk as a, type PerformActionInput as b, type PlainHandlerResult as c, type WithdrawFundsOk as d, type AvailableFundsBody as e, ADDRESS_RE as f, type AvailableFundsContext as g, type AvailableFundsEntry as h, type CommitHandlerContext as i, HEX_BYTES_RE as j, type HandlerErrorBody as k, type HandlerStatus as l, type HandlerWarning as m, type PerformActionContext as n, type RedeemHandlerContext as o, type ResolveEntityError as p, type ResolveEntityInput as q, type ResolveEntityOk as r, type ResolveEntityResult as s, type WithdrawFundsContext as t, emitNextActions as u, handleCommit as v, handleCommitAndRedeem as w, handleComplete as x, handleDisputeEscalate as y, handleDisputeRaise as z };
@@ -1,12 +1,12 @@
1
1
  import * as _bosonprotocol_x402_core_schemes_escrow from '@bosonprotocol/x402-core/schemes/escrow';
2
2
  import { BosonOfferRef, EscrowPaymentRequirements } from '@bosonprotocol/x402-core/schemes/escrow';
3
3
  import { UnsignedFullOffer } from '@bosonprotocol/x402-core/eip712';
4
- import { X as X402bServerConfig } from './config-CBr9qMps.js';
5
- export { C as CoreSdkBuyerEntity, a as CoreSdkFundsEntity, b as CoreSdkReadAdapter, c as CoreSdkSellerEntity, F as FulfillmentRecoveryEntry, R as RedeemFulfillmentChannel, S as SellerSigner, d as asCoreSdkReadAdapter, e as assertChannelRegistryEscrowMatch, x as x402bServerConfigSchema } from './config-CBr9qMps.js';
6
- import { F as FacilitatorClient } from './client-tnrpqVMW.js';
7
- export { C as CreateFacilitatorClientOptions, a as FetchLike, c as createFacilitatorClient } from './client-tnrpqVMW.js';
8
- import { CommitHandlerInput, HandlerResult, CommitOk, RedeemHandlerInput, PerformActionOk, PerformActionInput, WithdrawFundsInput, PlainHandlerResult, WithdrawFundsOk, AvailableFundsQuery, AvailableFundsBody } from './handlers/index.js';
9
- export { ADDRESS_RE, AvailableFundsContext, AvailableFundsEntry, CommitHandlerContext, DECIMAL_UINT_RE, EmitNextActionsInput, HEX_BYTES_RE, HandlerErrorBody, HandlerStatus, HandlerWarning, PerformActionContext, RedeemHandlerContext, ResolveEntityError, ResolveEntityInput, ResolveEntityOk, ResolveEntityResult, WithdrawFundsContext, emitNextActions, handleCommit, handleCommitAndRedeem, handleComplete, handleDisputeEscalate, handleDisputeRaise, handleDisputeResolve, handleDisputeRetract, handleGetAvailableFunds, handlePerformAction, handleRedeem, handleWithdrawFunds, handlerErr, handlerOk, plainHandlerOk, resolveEntityId } from './handlers/index.js';
4
+ import { C as CoreSdkReadAdapter, F as FulfillmentRecoveryEntry, X as X402bServerConfig } from './config-hnCiZiXF.js';
5
+ export { a as CoreSdkBuyerEntity, b as CoreSdkFundsEntity, c as CoreSdkSellerEntity, d as FulfillmentResult, R as RedeemFulfillmentChannel, S as SellerSigner, e as Store, f as asCoreSdkReadAdapter, g as assertChannelRegistryEscrowMatch, i as isStore, m as mapAsStore, x as x402bServerConfigSchema } from './config-hnCiZiXF.js';
6
+ import { a as FacilitatorClient } from './client-B2yejopi.js';
7
+ export { C as CreateFacilitatorClientOptions, F as FacilitatorRetryOptions, b as FetchLike, I as IDEMPOTENCY_KEY_HEADER, L as Logger, c as createFacilitatorClient, n as noopLogger } from './client-B2yejopi.js';
8
+ import { C as CommitHandlerInput, H as HandlerResult, a as CommitOk, R as RedeemHandlerInput, P as PerformActionOk, b as PerformActionInput, W as WithdrawFundsInput, c as PlainHandlerResult, d as WithdrawFundsOk, A as AvailableFundsQuery, e as AvailableFundsBody } from './index-COmLTH-U.js';
9
+ export { f as ADDRESS_RE, g as AvailableFundsContext, h as AvailableFundsEntry, i as CommitHandlerContext, D as DECIMAL_UINT_RE, E as EmitNextActionsInput, j as HEX_BYTES_RE, k as HandlerErrorBody, l as HandlerStatus, m as HandlerWarning, n as PerformActionContext, o as RedeemHandlerContext, p as ResolveEntityError, q as ResolveEntityInput, r as ResolveEntityOk, s as ResolveEntityResult, S as SerializedFulfillmentResult, t as WithdrawFundsContext, u as emitNextActions, v as handleCommit, w as handleCommitAndRedeem, x as handleComplete, y as handleDisputeEscalate, z as handleDisputeRaise, B as handleDisputeResolve, F as handleDisputeRetract, G as handleGetAvailableFunds, I as handlePerformAction, J as handleRedeem, K as handleWithdrawFunds, L as handlerErr, M as handlerOk, N as plainHandlerOk, O as resolveEntityId } from './index-COmLTH-U.js';
10
10
  export { BuildPaymentRequirementsArgs, SignFullOfferArgs, buildPaymentRequirements, signFullOffer } from './challenge/index.js';
11
11
  export { DecodeErrorCode, DecodeXPaymentResult, ValidatePaymentPayloadArgs, ValidatePaymentPayloadResult, ValidationErrorCode, ValidationWarning, decodeXPaymentHeader, validatePaymentPayload } from './validate/index.js';
12
12
  export { FacilitatorHttpError, FacilitatorHttpErrorCode } from './facilitator/index.js';
@@ -18,6 +18,28 @@ import 'zod';
18
18
  import '@bosonprotocol/core-sdk';
19
19
  import '@bosonprotocol/x402-core/state-machine';
20
20
 
21
+ /**
22
+ * Per-dependency health status.
23
+ *
24
+ * - `"ok"` — last probe succeeded
25
+ * - `"down"` — last probe threw or returned a non-2xx
26
+ * - `"n/a"` — dependency isn't configured (subgraph is optional —
27
+ * commit/redeem-only servers don't have one). For the subgraph
28
+ * probe, `"n/a"` means **neither** `coreSdkRead` nor `subgraphUrl`
29
+ * was supplied; a configured `subgraphUrl` is materialised on the
30
+ * first probe so it always reports `"ok"` / `"down"`.
31
+ */
32
+ type HealthState = "ok" | "down" | "n/a";
33
+ interface HealthCheckResult {
34
+ facilitator: HealthState;
35
+ subgraph: HealthState;
36
+ }
37
+ /** Build a `healthCheck()` function bound to a facilitator client + optional read client. */
38
+ declare function createHealthCheck(deps: {
39
+ facilitator: FacilitatorClient;
40
+ coreSdkRead?: CoreSdkReadAdapter | (() => CoreSdkReadAdapter | undefined);
41
+ }): () => Promise<HealthCheckResult>;
42
+
21
43
  /** Per-offer inputs for `server.buildPaymentRequirements` — everything the offer-level args carry, minus the per-server context the factory already holds. */
22
44
  interface BuildRequirementsInput {
23
45
  /** Already-signed offer reference, or `{ unsigned }` to have the server sign it. */
@@ -31,6 +53,41 @@ interface BuildRequirementsInput {
31
53
  maxTimeoutSeconds: number;
32
54
  fulfillment?: _bosonprotocol_x402_core_schemes_escrow.FulfillmentRequirements;
33
55
  }
56
+ /**
57
+ * Result of a single `recovery.replay(exchangeId)` call. `{ ok: true }`
58
+ * means the channel adapter's `onCommit(...)` succeeded and the recovery
59
+ * entry has been deleted; `{ ok: false, reason }` leaves the entry in
60
+ * place and reports the failure cause.
61
+ */
62
+ type RecoveryReplayResult = {
63
+ ok: true;
64
+ } | {
65
+ ok: false;
66
+ reason: string;
67
+ };
68
+ /**
69
+ * Operator surface for inspecting and replaying the deferred-fulfillment
70
+ * recovery store. The handlers record an entry when a post-settle
71
+ * `channel.onCommit(...)` fails or is missing an adapter; the entries
72
+ * sit until the host replays them out-of-band. This API exposes the
73
+ * inspection + replay primitives so a host doesn't need to hold the
74
+ * raw Map reference itself.
75
+ */
76
+ interface RecoveryApi {
77
+ /** Snapshot of all pending recovery entries. */
78
+ list(): Promise<readonly FulfillmentRecoveryEntry[]>;
79
+ /**
80
+ * Re-run the channel step that was pending when the entry was
81
+ * recorded. Branches on `entry.phase`:
82
+ * - `"commit"` → re-runs `channel.onCommit(exchangeId, entry.data)`.
83
+ * - `"delivery"` → re-runs `channel.onFulfill(exchangeId)` (the
84
+ * prior `onCommit` already persisted).
85
+ * Deletes the entry on success; leaves it (with an updated `error`
86
+ * field) on failure. A `"delivery"` entry whose channel has no
87
+ * `onFulfill` returns `{ ok: false }` with the entry retained.
88
+ */
89
+ replay(exchangeId: string): Promise<RecoveryReplayResult>;
90
+ }
34
91
  interface X402bServer {
35
92
  readonly config: X402bServerConfig;
36
93
  readonly facilitator: FacilitatorClient;
@@ -51,6 +108,19 @@ interface X402bServer {
51
108
  withdrawFunds(input: WithdrawFundsInput): Promise<PlainHandlerResult<WithdrawFundsOk>>;
52
109
  getAvailableFunds(query: AvailableFundsQuery): Promise<PlainHandlerResult<AvailableFundsBody>>;
53
110
  };
111
+ /**
112
+ * Operator API for the deferred-fulfillment recovery queue. See
113
+ * `RecoveryApi` and `docs/boson-impl-05-server-sdk.md` for the
114
+ * operator runbook.
115
+ */
116
+ readonly recovery: RecoveryApi;
117
+ /**
118
+ * Liveness probe — pings the facilitator's `/healthz` and (if a
119
+ * subgraph / read client is configured) a cheap subgraph read. Hosts
120
+ * mount this behind whatever `/healthz` / `/readyz` route their
121
+ * framework uses.
122
+ */
123
+ healthCheck(): Promise<HealthCheckResult>;
54
124
  }
55
125
  /**
56
126
  * Validate a config and return a `X402bServer` whose methods are
@@ -69,4 +139,18 @@ declare function encodeXPaymentResponse(body: unknown): string;
69
139
  /** Canonical header name — exported so adapters share one spelling. */
70
140
  declare const X_PAYMENT_RESPONSE_HEADER: "X-PAYMENT-RESPONSE";
71
141
 
72
- export { AvailableFundsBody, AvailableFundsQuery, type BuildRequirementsInput, CommitHandlerInput, CommitOk, FacilitatorClient, HandlerResult, PerformActionInput, PerformActionOk, PlainHandlerResult, RedeemHandlerInput, WithdrawFundsInput, WithdrawFundsOk, type X402bServer, X402bServerConfig, X_PAYMENT_RESPONSE_HEADER, createX402bServer, encodeXPaymentResponse };
142
+ interface KeyedMutex<K> {
143
+ /**
144
+ * Run `fn` once any previously-queued work for `key` has settled.
145
+ * Successive callers for the same `key` queue in FIFO order; callers
146
+ * for different keys run independently.
147
+ *
148
+ * `fn`'s resolution and rejection are surfaced to the caller
149
+ * directly — the mutex itself never alters the return value or
150
+ * masks errors.
151
+ */
152
+ runExclusive<T>(key: K, fn: () => Promise<T>): Promise<T>;
153
+ }
154
+ declare function createKeyedMutex<K>(): KeyedMutex<K>;
155
+
156
+ export { AvailableFundsBody, AvailableFundsQuery, type BuildRequirementsInput, CommitHandlerInput, CommitOk, CoreSdkReadAdapter, FacilitatorClient, FulfillmentRecoveryEntry, HandlerResult, type HealthCheckResult, type HealthState, type KeyedMutex, PerformActionInput, PerformActionOk, PlainHandlerResult, type RecoveryApi, type RecoveryReplayResult, RedeemHandlerInput, WithdrawFundsInput, WithdrawFundsOk, type X402bServer, X402bServerConfig, X_PAYMENT_RESPONSE_HEADER, createHealthCheck, createKeyedMutex, createX402bServer, encodeXPaymentResponse };