@lunora/x402 1.0.0-alpha.83 → 1.0.0-alpha.85

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.
@@ -1,5 +1,3 @@
1
- import { ProcessSettleSuccessResponse } from '@x402/core/http';
2
- import { BeforePaymentCreationHook, PaymentPolicy, OnPaymentCreationFailureHook } from '@x402/core/client';
3
1
  import { PaymentRequirements } from '@x402/core/types';
4
2
  import { TransactionSigner } from '@solana/accounts';
5
3
  /**
@@ -69,7 +67,6 @@ type ClientSvmSigner = TransactionSigner;
69
67
  * as its exact on-chain atomic-unit string (USDC has 6 decimals) — never coerced
70
68
  * to a fractional-dollar number — so no precision is lost crossing the reporting
71
69
  * seam.
72
- * @experimental
73
70
  */
74
71
  interface X402Receipt {
75
72
  /** Settled amount in the asset's atomic base units (USDC: 6 decimals), as an exact string. */
@@ -95,26 +92,12 @@ interface X402Receipt {
95
92
  * settlement, does not block the paid response on it, and swallows any error it
96
93
  * throws — so a sink must never rely on being awaited or on its failures
97
94
  * surfacing.
98
- * @experimental
99
95
  */
100
96
  type X402ReceiptSink = (receipt: X402Receipt) => Promise<void> | void;
101
- /**
102
- * Normalise a successful facilitator settlement into an {@link X402Receipt}.
103
- * `resource` (the gated URL or procedure id) and `ts` are supplied by the caller —
104
- * the settlement result carries neither. Prefers the actual settled `amount`
105
- * (present for `upto`-scheme partial settlements) and falls back to the route's
106
- * required amount for `exact`.
107
- * @experimental
108
- */
109
- declare const toReceipt: (settlement: ProcessSettleSuccessResponse, context: {
110
- readonly resource: string;
111
- readonly ts: number;
112
- }) => X402Receipt;
113
97
  /**
114
98
  * A row for `@lunora/payment`'s durable `events` table. Deliberately a plain
115
99
  * structural type — building one imports nothing from `@lunora/payment`, so the
116
100
  * rails stay decoupled.
117
- * @experimental
118
101
  */
119
102
  interface PaymentEventRow {
120
103
  /** Epoch milliseconds the settlement was recorded. */
@@ -142,47 +125,25 @@ interface PaymentEventRow {
142
125
  * table (`packages/payment/src/schema.ts`). Amount / from / to / resource are
143
126
  * intentionally not on this row — that card renders none of them; read them off
144
127
  * the {@link X402Receipt} (e.g. into your own revenue table) if you need them.
145
- * @experimental
146
128
  */
147
129
  declare const toPaymentEventRow: (receipt: X402Receipt) => PaymentEventRow;
148
- /**
149
- * Network identity for `@lunora/x402`.
150
- *
151
- * `@x402/core` v2 speaks **CAIP-2** chain ids (`eip155:8453` for Base,
152
- * `solana:5eyk…` for Solana mainnet) — `type Network = ` `${string}:${string}` ``.
153
- * Lunora keeps ergonomic **friendly** names (`"base"`, `"base-sepolia"`) as the
154
- * public surface and maps them to CAIP-2 here, at the single seam where we hand a
155
- * network to the SDK. A raw CAIP-2 string is also accepted as a power-user escape
156
- * hatch (e.g. a chain we don't yet have a friendly alias for).
157
- *
158
- * The friendly set is intentionally scoped to chains `@x402/evm` / `@x402/svm`
159
- * can settle the ergonomic `price:"$0.01"` path on out of the box (i.e. chains in
160
- * their `DEFAULT_STABLECOINS` registry). Notably that excludes Optimism and
161
- * Avalanche today — advertising them would 500 at settlement — so they are not
162
- * friendly aliases; a caller who needs them can still pass a raw CAIP-2 id with an
163
- * explicit asset.
164
- */
165
130
  /**
166
131
  * A CAIP-2 chain identifier, e.g. `"eip155:8453"` (Base) or `"solana:5eyk…"`.
167
- * @experimental
168
132
  */
169
133
  type Caip2 = `${string}:${string}`;
170
134
  /**
171
135
  * Friendly network names Lunora maps to CAIP-2 for `@x402/core`.
172
- * @experimental
173
136
  */
174
137
  type FriendlyNetwork = "arbitrum" | "arbitrum-sepolia" | "base" | "base-sepolia" | "ethereum" | "polygon" | "solana" | "solana-devnet";
175
138
  /**
176
139
  * A network Lunora can settle on: a {@link FriendlyNetwork} alias (mapped to
177
140
  * CAIP-2 internally) or a raw {@link Caip2} id for chains without a friendly name.
178
- * @experimental
179
141
  */
180
142
  type X402Network = Caip2 | FriendlyNetwork;
181
143
  /**
182
144
  * Friendly name → CAIP-2 id. Values verified against `@x402/evm` and `@x402/svm`
183
145
  * `DEFAULT_STABLECOINS` at 2.17.0. `base` / `base-sepolia` are the primary
184
146
  * prod / test pair.
185
- * @experimental
186
147
  */
187
148
  declare const NETWORK_TO_CAIP2: {
188
149
  readonly arbitrum: "eip155:42161";
@@ -196,28 +157,23 @@ declare const NETWORK_TO_CAIP2: {
196
157
  };
197
158
  /**
198
159
  * EVM friendly networks (signed via `@x402/evm` + viem).
199
- * @experimental
200
160
  */
201
161
  declare const EVM_NETWORKS: readonly ["arbitrum", "arbitrum-sepolia", "base", "base-sepolia", "ethereum", "polygon"];
202
162
  /**
203
163
  * Solana friendly networks (signed via `@x402/svm`).
204
- * @experimental
205
164
  */
206
165
  declare const SVM_NETWORKS: readonly ["solana", "solana-devnet"];
207
166
  /**
208
167
  * Resolve a network to its CAIP-2 id. Friendly aliases are looked up; a value
209
168
  * that already looks like CAIP-2 (`namespace:reference`) passes through.
210
- * @experimental
211
169
  */
212
170
  declare const toCaip2: (network: X402Network) => Caip2;
213
171
  /**
214
172
  * True when `network` settles on an EVM chain (viem signer path).
215
- * @experimental
216
173
  */
217
174
  declare const isEvmNetwork: (network: X402Network) => boolean;
218
175
  /**
219
176
  * True when `network` settles on Solana (`@x402/svm` signer path).
220
- * @experimental
221
177
  */
222
178
  declare const isSvmNetwork: (network: X402Network) => boolean;
223
179
  /**
@@ -225,7 +181,6 @@ declare const isSvmNetwork: (network: X402Network) => boolean;
225
181
  * This is only the *default* for the standalone {@link usdToAtomic} helper —
226
182
  * a spend policy never assumes it, and scales each requirement by the decimals of
227
183
  * the asset it actually names (see {@link SpendPolicy.allowedAssets}).
228
- * @experimental
229
184
  */
230
185
  declare const DEFAULT_STABLECOIN_DECIMALS = 6;
231
186
  /**
@@ -238,7 +193,6 @@ declare const DEFAULT_STABLECOIN_DECIMALS = 6;
238
193
  * to authorise a large transfer, so the caller states it per asset. Note
239
194
  * `@x402/evm`'s own `DEFAULT_STABLECOINS` registry is *not* uniformly 6-decimal
240
195
  * (MegaUSD and Mezo USD are 18), which is exactly why it can't be trusted as a gate.
241
- * @experimental
242
196
  */
243
197
  interface AllowedAsset {
244
198
  /** Token contract (EVM) or mint (SVM) address. Matched case-insensitively on EVM, exactly on SVM. */
@@ -260,7 +214,6 @@ interface AllowedAsset {
260
214
  *
261
215
  * `ethereum` (`eip155:1`) is absent — the SDK ships no default stablecoin for it, so
262
216
  * paying there needs an explicit {@link SpendPolicy.allowedAssets} entry.
263
- * @experimental
264
217
  */
265
218
  declare const DEFAULT_ALLOWED_ASSETS: ReadonlyArray<AllowedAsset>;
266
219
  /**
@@ -269,7 +222,6 @@ declare const DEFAULT_ALLOWED_ASSETS: ReadonlyArray<AllowedAsset>;
269
222
  *
270
223
  * Caps are denominated in USD (the stablecoin's dollar value); addresses and
271
224
  * networks are matched against the requirement the server offers.
272
- * @experimental
273
225
  */
274
226
  interface SpendPolicy {
275
227
  /**
@@ -290,16 +242,15 @@ interface SpendPolicy {
290
242
  readonly allowedNetworks?: ReadonlyArray<X402Network>;
291
243
  /** Recipient allowlist. When set, only these `payTo` addresses may be paid. */
292
244
  readonly allowedRecipients?: ReadonlyArray<string>;
293
- /**
294
- * @deprecated One policy-wide decimal count can't describe the assets a server may
295
- * name, and guessing it is what let a small USD cap authorise a large transfer.
296
- * Setting this now throws — put the asset in {@link SpendPolicy.allowedAssets} with
297
- * its own `decimals` instead.
298
- */
299
- readonly decimals?: number;
300
245
  /** Hard ceiling on a single payment, in USD. */
301
246
  readonly maxPerCall?: X402Price;
302
- /** Hard ceiling on cumulative spend across this wallet's lifetime, in USD. */
247
+ /**
248
+ * Hard ceiling on cumulative spend by one pay rail, in USD. The ledger lives
249
+ * in memory on the rail, so the cap covers one `createX402Pay` result, and for
250
+ * `ctx.x402` one function invocation (codegen builds a rail per ctx). It is not
251
+ * a budget across invocations: for that, keep a counter in durable state (a
252
+ * Durable Object, a table) and check it in `onPaymentRequired`.
253
+ */
303
254
  readonly maxPerRun?: X402Price;
304
255
  /**
305
256
  * Approval gate. Called with the selected requirement before signing; return
@@ -308,100 +259,20 @@ interface SpendPolicy {
308
259
  */
309
260
  readonly onPaymentRequired?: (requirement: PaymentRequirements) => Promise<boolean> | boolean;
310
261
  }
311
- /**
312
- * A running spend ledger the per-run cap is measured (and reserved) against.
313
- * @experimental
314
- */
315
- interface SpendState {
316
- /** Reserve a payment (atomic base units) against the running total, before it is signed. */
317
- readonly add: (amount: bigint) => void;
318
- /** Release a previously reserved amount (atomic base units) — e.g. a declined or failed payment. Clamps at 0. */
319
- readonly release: (amount: bigint) => void;
320
- /** Cumulative spend so far, in atomic base units. */
321
- readonly spentAtomic: bigint;
322
- }
323
- /**
324
- * A fresh spend ledger. One per wallet instance; the guard reserves into it and
325
- * releases from it.
326
- * @experimental
327
- */
328
- declare const createSpendState: () => SpendState;
329
262
  /**
330
263
  * Convert a USD amount (`0.01`, `"0.01"`, or the `"$0.01"` shorthand) to atomic
331
264
  * stablecoin base units, exactly — parsed digit-by-digit so no binary-float drift
332
265
  * can round a cap the wrong way. Throws on a malformed amount (including
333
266
  * exponential notation like `"1e-7"`, which a decimal string never needs).
334
- * @experimental
335
267
  */
336
268
  declare const usdToAtomic: (usd: X402Price, decimals?: number) => bigint;
337
- /**
338
- * A `PaymentPolicy` that narrows the server's offered requirements to those a
339
- * bounded wallet may pay: in an allowed asset, within the per-call cap *for that
340
- * asset's decimals*, to an allowed recipient, on an allowed network. An empty result
341
- * means the client cannot pay — fail-closed.
342
- *
343
- * The asset check comes first and is what makes the amount check mean anything. The
344
- * server chooses the token contract the scheme will sign a transfer against, and
345
- * `amount` is in that token's atomic base units — so comparing it against a USD cap
346
- * converted at an assumed decimal count mis-prices any asset that doesn't match the
347
- * assumption. Pinning the asset (and taking its decimals from the policy, not the
348
- * requirement) closes that.
349
- * @experimental
350
- */
351
- declare const buildSpendPolicy: (policy: SpendPolicy) => PaymentPolicy;
352
- /**
353
- * A `BeforePaymentCreationHook` enforcing the stateful bounds the stateless
354
- * {@link buildSpendPolicy} filter can't: the cumulative per-run cap and the async
355
- * confirmation gate. Aborts (no signature) when either would be violated.
356
- *
357
- * The per-run cap is *reserved* into `state` as soon as the check passes — before
358
- * the `await policy.onPaymentRequired` below, and before `@x402/core` ever attempts
359
- * to sign — not recorded afterwards. This closes a check-then-act race: without an
360
- * atomic reserve, N concurrent payments could each read the same `spentAtomic`,
361
- * all pass the cap check, and all record, overspending the cap by up to
362
- * (N−1)×maxPerCall. A declined confirmation releases the reservation before this
363
- * hook returns; {@link releaseSpendOnFailure} releases it if the signature itself
364
- * later fails. The reservation is intentionally *not* released on success — a
365
- * committed payment stays counted.
366
- *
367
- * The asset is re-checked here rather than trusted from {@link buildSpendPolicy}:
368
- * the two are registered on separate client seams, and a guard that assumed the
369
- * filter ran would be one wiring change away from signing an unpinned asset.
370
- * @experimental
371
- */
372
- declare const buildPaymentGuard: (policy: SpendPolicy, state: SpendState) => BeforePaymentCreationHook;
373
- /**
374
- * An `OnPaymentCreationFailureHook` that releases a reservation
375
- * {@link buildPaymentGuard} made when the scheme's signature creation itself
376
- * throws (network error, wallet error, …) after the guard already approved and
377
- * reserved the amount. Without this, a failed signature would permanently
378
- * over-count against the per-run cap for the rest of the run — fail-closed, but
379
- * needlessly so when the client (`wrapFetchWithPayment`) may retry.
380
- * @experimental
381
- */
382
- declare const releaseSpendOnFailure: (state: SpendState) => OnPaymentCreationFailureHook;
383
- /**
384
- * Guard at wallet-build time: refuse a policy with no bound whatsoever. Signing
385
- * money on an agent's behalf with unlimited spend authority is never the intent,
386
- * so this fails loudly rather than defaulting to unbounded.
387
- *
388
- * `allowedNetworks` / `allowedRecipients` / `allowedAssets` narrow *where* a payment
389
- * can go and *in what*, but none caps *how much* — a policy with only allowlists still
390
- * authorises unlimited spend to any recipient it permits. Only `maxPerCall`,
391
- * `maxPerRun`, or a dynamic `onPaymentRequired` gate actually bound spend, so only
392
- * those count here.
393
- * @experimental
394
- */
395
- declare const assertBoundedPolicy: (policy: SpendPolicy) => void;
396
269
  /**
397
270
  * The public, Coinbase-operated facilitator (verify + settle). It needs no API
398
271
  * key. Override with a self-hosted or CDP facilitator via {@link FacilitatorConfig}.
399
- * @experimental
400
272
  */
401
273
  declare const DEFAULT_FACILITATOR_URL = "https://x402.org/facilitator";
402
274
  /**
403
275
  * How to reach a facilitator's `/verify` + `/settle` endpoints.
404
- * @experimental
405
276
  */
406
277
  interface FacilitatorConfig {
407
278
  /** Extra headers for a private facilitator (e.g. a CDP bearer token). */
@@ -415,17 +286,14 @@ interface FacilitatorConfig {
415
286
  * to the network's stablecoin base units (USDC has 6 decimals) at challenge
416
287
  * time. (Kept `number | string` rather than a `` `$${string}` `` template
417
288
  * member — the template is subsumed by `string`, so it only adds noise.)
418
- * @experimental
419
289
  */
420
290
  type X402Price = number | string;
421
291
  /**
422
292
  * An EVM recipient address (the merchant wallet that receives settlement).
423
- * @experimental
424
293
  */
425
294
  type EvmAddress = `0x${string}`;
426
295
  /**
427
296
  * Recipient wallet the facilitator settles payments to, per network family.
428
- * @experimental
429
297
  */
430
298
  interface X402Recipient {
431
299
  /** EVM payout address (required for EVM networks). */
@@ -436,7 +304,6 @@ interface X402Recipient {
436
304
  /**
437
305
  * Server-side (charge rail) config. The server needs only a **recipient
438
306
  * address** — no private key — because the facilitator performs settlement.
439
- * @experimental
440
307
  */
441
308
  interface X402ChargeConfig {
442
309
  readonly facilitator?: FacilitatorConfig;
@@ -458,7 +325,6 @@ interface X402ChargeConfig {
458
325
  * Client-side (pay rail) config. The signer holds spending authority, so the
459
326
  * pay rail is ActionCtx-only and MUST be paired with a spend `policy` — the pay
460
327
  * rail refuses to build if the policy is unbounded.
461
- * @experimental
462
328
  */
463
329
  interface X402PayConfig {
464
330
  /** Network to transact on. Determines the signer family (EVM vs SVM). */
@@ -478,7 +344,6 @@ interface X402PayConfig {
478
344
  * custody is `@coinbase/cdp-sdk`.) EVM only today; for CDP on Solana, build a
479
345
  * `@solana/kit` signer around your CDP account and pass it via the `"signer"`
480
346
  * escape hatch.
481
- * @experimental
482
347
  */
483
348
  interface X402CdpSignerConfig {
484
349
  /** CDP account name to get-or-create and sign with. */
@@ -510,7 +375,6 @@ interface X402CdpSignerConfig {
510
375
  * Wired today: raw-key (EVM + SVM), the user-supplied signer (both families),
511
376
  * and CDP-managed EVM custody. CDP on Solana is not yet wired — use the escape
512
377
  * hatch.
513
- * @experimental
514
378
  */
515
379
  type X402SignerConfig = X402CdpSignerConfig | {
516
380
  /** Name of the `ctx.secrets` entry holding the private key. */
@@ -527,7 +391,6 @@ type X402SignerConfig = X402CdpSignerConfig | {
527
391
  };
528
392
  /**
529
393
  * Resolve a facilitator's base URL, applying the public default.
530
- * @experimental
531
394
  */
532
395
  declare const resolveFacilitatorUrl: (facilitator?: FacilitatorConfig) => string;
533
- export { AllowedAsset as A, FriendlyNetwork as B, type ClientEvmSigner as C, DEFAULT_ALLOWED_ASSETS as D, EvmAddress as E, type FacilitatorConfig as F, SVM_NETWORKS as G, NETWORK_TO_CAIP2 as N, PaymentEventRow as P, type SpendPolicy as S, X402PayConfig as X, ClientSvmSigner as a, Caip2 as b, type DEFAULT_FACILITATOR_URL as c, type DEFAULT_STABLECOIN_DECIMALS as d, type SpendState as e, type X402CdpSignerConfig as f, type X402Network as g, X402Price as h, X402SignerConfig as i, assertBoundedPolicy as j, buildPaymentGuard as k, buildSpendPolicy as l, createSpendState as m, isEvmNetwork as n, isSvmNetwork as o, resolveFacilitatorUrl as p, X402ChargeConfig as q, releaseSpendOnFailure as r, X402Receipt as s, toCaip2 as t, usdToAtomic as u, X402ReceiptSink as v, X402Recipient as w, toPaymentEventRow as x, toReceipt as y, EVM_NETWORKS as z };
396
+ export { AllowedAsset as A, type Caip2 as C, DEFAULT_ALLOWED_ASSETS as D, EvmAddress as E, type FacilitatorConfig as F, NETWORK_TO_CAIP2 as N, PaymentEventRow as P, type SpendPolicy as S, X402PayConfig as X, DEFAULT_FACILITATOR_URL as a, DEFAULT_STABLECOIN_DECIMALS as b, type X402CdpSignerConfig as c, type X402Network as d, type X402Price as e, type X402SignerConfig as f, type isSvmNetwork as g, X402ChargeConfig as h, isEvmNetwork as i, X402Receipt as j, X402ReceiptSink as k, X402Recipient as l, toPaymentEventRow as m, EVM_NETWORKS as n, FriendlyNetwork as o, SVM_NETWORKS as p, resolveFacilitatorUrl as r, toCaip2 as t, usdToAtomic as u };
@@ -1,5 +1,3 @@
1
- import { ProcessSettleSuccessResponse } from '@x402/core/http';
2
- import { BeforePaymentCreationHook, PaymentPolicy, OnPaymentCreationFailureHook } from '@x402/core/client';
3
1
  import { PaymentRequirements } from '@x402/core/types';
4
2
  import { TransactionSigner } from '@solana/accounts';
5
3
  /**
@@ -69,7 +67,6 @@ type ClientSvmSigner = TransactionSigner;
69
67
  * as its exact on-chain atomic-unit string (USDC has 6 decimals) — never coerced
70
68
  * to a fractional-dollar number — so no precision is lost crossing the reporting
71
69
  * seam.
72
- * @experimental
73
70
  */
74
71
  interface X402Receipt {
75
72
  /** Settled amount in the asset's atomic base units (USDC: 6 decimals), as an exact string. */
@@ -95,26 +92,12 @@ interface X402Receipt {
95
92
  * settlement, does not block the paid response on it, and swallows any error it
96
93
  * throws — so a sink must never rely on being awaited or on its failures
97
94
  * surfacing.
98
- * @experimental
99
95
  */
100
96
  type X402ReceiptSink = (receipt: X402Receipt) => Promise<void> | void;
101
- /**
102
- * Normalise a successful facilitator settlement into an {@link X402Receipt}.
103
- * `resource` (the gated URL or procedure id) and `ts` are supplied by the caller —
104
- * the settlement result carries neither. Prefers the actual settled `amount`
105
- * (present for `upto`-scheme partial settlements) and falls back to the route's
106
- * required amount for `exact`.
107
- * @experimental
108
- */
109
- declare const toReceipt: (settlement: ProcessSettleSuccessResponse, context: {
110
- readonly resource: string;
111
- readonly ts: number;
112
- }) => X402Receipt;
113
97
  /**
114
98
  * A row for `@lunora/payment`'s durable `events` table. Deliberately a plain
115
99
  * structural type — building one imports nothing from `@lunora/payment`, so the
116
100
  * rails stay decoupled.
117
- * @experimental
118
101
  */
119
102
  interface PaymentEventRow {
120
103
  /** Epoch milliseconds the settlement was recorded. */
@@ -142,47 +125,25 @@ interface PaymentEventRow {
142
125
  * table (`packages/payment/src/schema.ts`). Amount / from / to / resource are
143
126
  * intentionally not on this row — that card renders none of them; read them off
144
127
  * the {@link X402Receipt} (e.g. into your own revenue table) if you need them.
145
- * @experimental
146
128
  */
147
129
  declare const toPaymentEventRow: (receipt: X402Receipt) => PaymentEventRow;
148
- /**
149
- * Network identity for `@lunora/x402`.
150
- *
151
- * `@x402/core` v2 speaks **CAIP-2** chain ids (`eip155:8453` for Base,
152
- * `solana:5eyk…` for Solana mainnet) — `type Network = ` `${string}:${string}` ``.
153
- * Lunora keeps ergonomic **friendly** names (`"base"`, `"base-sepolia"`) as the
154
- * public surface and maps them to CAIP-2 here, at the single seam where we hand a
155
- * network to the SDK. A raw CAIP-2 string is also accepted as a power-user escape
156
- * hatch (e.g. a chain we don't yet have a friendly alias for).
157
- *
158
- * The friendly set is intentionally scoped to chains `@x402/evm` / `@x402/svm`
159
- * can settle the ergonomic `price:"$0.01"` path on out of the box (i.e. chains in
160
- * their `DEFAULT_STABLECOINS` registry). Notably that excludes Optimism and
161
- * Avalanche today — advertising them would 500 at settlement — so they are not
162
- * friendly aliases; a caller who needs them can still pass a raw CAIP-2 id with an
163
- * explicit asset.
164
- */
165
130
  /**
166
131
  * A CAIP-2 chain identifier, e.g. `"eip155:8453"` (Base) or `"solana:5eyk…"`.
167
- * @experimental
168
132
  */
169
133
  type Caip2 = `${string}:${string}`;
170
134
  /**
171
135
  * Friendly network names Lunora maps to CAIP-2 for `@x402/core`.
172
- * @experimental
173
136
  */
174
137
  type FriendlyNetwork = "arbitrum" | "arbitrum-sepolia" | "base" | "base-sepolia" | "ethereum" | "polygon" | "solana" | "solana-devnet";
175
138
  /**
176
139
  * A network Lunora can settle on: a {@link FriendlyNetwork} alias (mapped to
177
140
  * CAIP-2 internally) or a raw {@link Caip2} id for chains without a friendly name.
178
- * @experimental
179
141
  */
180
142
  type X402Network = Caip2 | FriendlyNetwork;
181
143
  /**
182
144
  * Friendly name → CAIP-2 id. Values verified against `@x402/evm` and `@x402/svm`
183
145
  * `DEFAULT_STABLECOINS` at 2.17.0. `base` / `base-sepolia` are the primary
184
146
  * prod / test pair.
185
- * @experimental
186
147
  */
187
148
  declare const NETWORK_TO_CAIP2: {
188
149
  readonly arbitrum: "eip155:42161";
@@ -196,28 +157,23 @@ declare const NETWORK_TO_CAIP2: {
196
157
  };
197
158
  /**
198
159
  * EVM friendly networks (signed via `@x402/evm` + viem).
199
- * @experimental
200
160
  */
201
161
  declare const EVM_NETWORKS: readonly ["arbitrum", "arbitrum-sepolia", "base", "base-sepolia", "ethereum", "polygon"];
202
162
  /**
203
163
  * Solana friendly networks (signed via `@x402/svm`).
204
- * @experimental
205
164
  */
206
165
  declare const SVM_NETWORKS: readonly ["solana", "solana-devnet"];
207
166
  /**
208
167
  * Resolve a network to its CAIP-2 id. Friendly aliases are looked up; a value
209
168
  * that already looks like CAIP-2 (`namespace:reference`) passes through.
210
- * @experimental
211
169
  */
212
170
  declare const toCaip2: (network: X402Network) => Caip2;
213
171
  /**
214
172
  * True when `network` settles on an EVM chain (viem signer path).
215
- * @experimental
216
173
  */
217
174
  declare const isEvmNetwork: (network: X402Network) => boolean;
218
175
  /**
219
176
  * True when `network` settles on Solana (`@x402/svm` signer path).
220
- * @experimental
221
177
  */
222
178
  declare const isSvmNetwork: (network: X402Network) => boolean;
223
179
  /**
@@ -225,7 +181,6 @@ declare const isSvmNetwork: (network: X402Network) => boolean;
225
181
  * This is only the *default* for the standalone {@link usdToAtomic} helper —
226
182
  * a spend policy never assumes it, and scales each requirement by the decimals of
227
183
  * the asset it actually names (see {@link SpendPolicy.allowedAssets}).
228
- * @experimental
229
184
  */
230
185
  declare const DEFAULT_STABLECOIN_DECIMALS = 6;
231
186
  /**
@@ -238,7 +193,6 @@ declare const DEFAULT_STABLECOIN_DECIMALS = 6;
238
193
  * to authorise a large transfer, so the caller states it per asset. Note
239
194
  * `@x402/evm`'s own `DEFAULT_STABLECOINS` registry is *not* uniformly 6-decimal
240
195
  * (MegaUSD and Mezo USD are 18), which is exactly why it can't be trusted as a gate.
241
- * @experimental
242
196
  */
243
197
  interface AllowedAsset {
244
198
  /** Token contract (EVM) or mint (SVM) address. Matched case-insensitively on EVM, exactly on SVM. */
@@ -260,7 +214,6 @@ interface AllowedAsset {
260
214
  *
261
215
  * `ethereum` (`eip155:1`) is absent — the SDK ships no default stablecoin for it, so
262
216
  * paying there needs an explicit {@link SpendPolicy.allowedAssets} entry.
263
- * @experimental
264
217
  */
265
218
  declare const DEFAULT_ALLOWED_ASSETS: ReadonlyArray<AllowedAsset>;
266
219
  /**
@@ -269,7 +222,6 @@ declare const DEFAULT_ALLOWED_ASSETS: ReadonlyArray<AllowedAsset>;
269
222
  *
270
223
  * Caps are denominated in USD (the stablecoin's dollar value); addresses and
271
224
  * networks are matched against the requirement the server offers.
272
- * @experimental
273
225
  */
274
226
  interface SpendPolicy {
275
227
  /**
@@ -290,16 +242,15 @@ interface SpendPolicy {
290
242
  readonly allowedNetworks?: ReadonlyArray<X402Network>;
291
243
  /** Recipient allowlist. When set, only these `payTo` addresses may be paid. */
292
244
  readonly allowedRecipients?: ReadonlyArray<string>;
293
- /**
294
- * @deprecated One policy-wide decimal count can't describe the assets a server may
295
- * name, and guessing it is what let a small USD cap authorise a large transfer.
296
- * Setting this now throws — put the asset in {@link SpendPolicy.allowedAssets} with
297
- * its own `decimals` instead.
298
- */
299
- readonly decimals?: number;
300
245
  /** Hard ceiling on a single payment, in USD. */
301
246
  readonly maxPerCall?: X402Price;
302
- /** Hard ceiling on cumulative spend across this wallet's lifetime, in USD. */
247
+ /**
248
+ * Hard ceiling on cumulative spend by one pay rail, in USD. The ledger lives
249
+ * in memory on the rail, so the cap covers one `createX402Pay` result, and for
250
+ * `ctx.x402` one function invocation (codegen builds a rail per ctx). It is not
251
+ * a budget across invocations: for that, keep a counter in durable state (a
252
+ * Durable Object, a table) and check it in `onPaymentRequired`.
253
+ */
303
254
  readonly maxPerRun?: X402Price;
304
255
  /**
305
256
  * Approval gate. Called with the selected requirement before signing; return
@@ -308,100 +259,20 @@ interface SpendPolicy {
308
259
  */
309
260
  readonly onPaymentRequired?: (requirement: PaymentRequirements) => Promise<boolean> | boolean;
310
261
  }
311
- /**
312
- * A running spend ledger the per-run cap is measured (and reserved) against.
313
- * @experimental
314
- */
315
- interface SpendState {
316
- /** Reserve a payment (atomic base units) against the running total, before it is signed. */
317
- readonly add: (amount: bigint) => void;
318
- /** Release a previously reserved amount (atomic base units) — e.g. a declined or failed payment. Clamps at 0. */
319
- readonly release: (amount: bigint) => void;
320
- /** Cumulative spend so far, in atomic base units. */
321
- readonly spentAtomic: bigint;
322
- }
323
- /**
324
- * A fresh spend ledger. One per wallet instance; the guard reserves into it and
325
- * releases from it.
326
- * @experimental
327
- */
328
- declare const createSpendState: () => SpendState;
329
262
  /**
330
263
  * Convert a USD amount (`0.01`, `"0.01"`, or the `"$0.01"` shorthand) to atomic
331
264
  * stablecoin base units, exactly — parsed digit-by-digit so no binary-float drift
332
265
  * can round a cap the wrong way. Throws on a malformed amount (including
333
266
  * exponential notation like `"1e-7"`, which a decimal string never needs).
334
- * @experimental
335
267
  */
336
268
  declare const usdToAtomic: (usd: X402Price, decimals?: number) => bigint;
337
- /**
338
- * A `PaymentPolicy` that narrows the server's offered requirements to those a
339
- * bounded wallet may pay: in an allowed asset, within the per-call cap *for that
340
- * asset's decimals*, to an allowed recipient, on an allowed network. An empty result
341
- * means the client cannot pay — fail-closed.
342
- *
343
- * The asset check comes first and is what makes the amount check mean anything. The
344
- * server chooses the token contract the scheme will sign a transfer against, and
345
- * `amount` is in that token's atomic base units — so comparing it against a USD cap
346
- * converted at an assumed decimal count mis-prices any asset that doesn't match the
347
- * assumption. Pinning the asset (and taking its decimals from the policy, not the
348
- * requirement) closes that.
349
- * @experimental
350
- */
351
- declare const buildSpendPolicy: (policy: SpendPolicy) => PaymentPolicy;
352
- /**
353
- * A `BeforePaymentCreationHook` enforcing the stateful bounds the stateless
354
- * {@link buildSpendPolicy} filter can't: the cumulative per-run cap and the async
355
- * confirmation gate. Aborts (no signature) when either would be violated.
356
- *
357
- * The per-run cap is *reserved* into `state` as soon as the check passes — before
358
- * the `await policy.onPaymentRequired` below, and before `@x402/core` ever attempts
359
- * to sign — not recorded afterwards. This closes a check-then-act race: without an
360
- * atomic reserve, N concurrent payments could each read the same `spentAtomic`,
361
- * all pass the cap check, and all record, overspending the cap by up to
362
- * (N−1)×maxPerCall. A declined confirmation releases the reservation before this
363
- * hook returns; {@link releaseSpendOnFailure} releases it if the signature itself
364
- * later fails. The reservation is intentionally *not* released on success — a
365
- * committed payment stays counted.
366
- *
367
- * The asset is re-checked here rather than trusted from {@link buildSpendPolicy}:
368
- * the two are registered on separate client seams, and a guard that assumed the
369
- * filter ran would be one wiring change away from signing an unpinned asset.
370
- * @experimental
371
- */
372
- declare const buildPaymentGuard: (policy: SpendPolicy, state: SpendState) => BeforePaymentCreationHook;
373
- /**
374
- * An `OnPaymentCreationFailureHook` that releases a reservation
375
- * {@link buildPaymentGuard} made when the scheme's signature creation itself
376
- * throws (network error, wallet error, …) after the guard already approved and
377
- * reserved the amount. Without this, a failed signature would permanently
378
- * over-count against the per-run cap for the rest of the run — fail-closed, but
379
- * needlessly so when the client (`wrapFetchWithPayment`) may retry.
380
- * @experimental
381
- */
382
- declare const releaseSpendOnFailure: (state: SpendState) => OnPaymentCreationFailureHook;
383
- /**
384
- * Guard at wallet-build time: refuse a policy with no bound whatsoever. Signing
385
- * money on an agent's behalf with unlimited spend authority is never the intent,
386
- * so this fails loudly rather than defaulting to unbounded.
387
- *
388
- * `allowedNetworks` / `allowedRecipients` / `allowedAssets` narrow *where* a payment
389
- * can go and *in what*, but none caps *how much* — a policy with only allowlists still
390
- * authorises unlimited spend to any recipient it permits. Only `maxPerCall`,
391
- * `maxPerRun`, or a dynamic `onPaymentRequired` gate actually bound spend, so only
392
- * those count here.
393
- * @experimental
394
- */
395
- declare const assertBoundedPolicy: (policy: SpendPolicy) => void;
396
269
  /**
397
270
  * The public, Coinbase-operated facilitator (verify + settle). It needs no API
398
271
  * key. Override with a self-hosted or CDP facilitator via {@link FacilitatorConfig}.
399
- * @experimental
400
272
  */
401
273
  declare const DEFAULT_FACILITATOR_URL = "https://x402.org/facilitator";
402
274
  /**
403
275
  * How to reach a facilitator's `/verify` + `/settle` endpoints.
404
- * @experimental
405
276
  */
406
277
  interface FacilitatorConfig {
407
278
  /** Extra headers for a private facilitator (e.g. a CDP bearer token). */
@@ -415,17 +286,14 @@ interface FacilitatorConfig {
415
286
  * to the network's stablecoin base units (USDC has 6 decimals) at challenge
416
287
  * time. (Kept `number | string` rather than a `` `$${string}` `` template
417
288
  * member — the template is subsumed by `string`, so it only adds noise.)
418
- * @experimental
419
289
  */
420
290
  type X402Price = number | string;
421
291
  /**
422
292
  * An EVM recipient address (the merchant wallet that receives settlement).
423
- * @experimental
424
293
  */
425
294
  type EvmAddress = `0x${string}`;
426
295
  /**
427
296
  * Recipient wallet the facilitator settles payments to, per network family.
428
- * @experimental
429
297
  */
430
298
  interface X402Recipient {
431
299
  /** EVM payout address (required for EVM networks). */
@@ -436,7 +304,6 @@ interface X402Recipient {
436
304
  /**
437
305
  * Server-side (charge rail) config. The server needs only a **recipient
438
306
  * address** — no private key — because the facilitator performs settlement.
439
- * @experimental
440
307
  */
441
308
  interface X402ChargeConfig {
442
309
  readonly facilitator?: FacilitatorConfig;
@@ -458,7 +325,6 @@ interface X402ChargeConfig {
458
325
  * Client-side (pay rail) config. The signer holds spending authority, so the
459
326
  * pay rail is ActionCtx-only and MUST be paired with a spend `policy` — the pay
460
327
  * rail refuses to build if the policy is unbounded.
461
- * @experimental
462
328
  */
463
329
  interface X402PayConfig {
464
330
  /** Network to transact on. Determines the signer family (EVM vs SVM). */
@@ -478,7 +344,6 @@ interface X402PayConfig {
478
344
  * custody is `@coinbase/cdp-sdk`.) EVM only today; for CDP on Solana, build a
479
345
  * `@solana/kit` signer around your CDP account and pass it via the `"signer"`
480
346
  * escape hatch.
481
- * @experimental
482
347
  */
483
348
  interface X402CdpSignerConfig {
484
349
  /** CDP account name to get-or-create and sign with. */
@@ -510,7 +375,6 @@ interface X402CdpSignerConfig {
510
375
  * Wired today: raw-key (EVM + SVM), the user-supplied signer (both families),
511
376
  * and CDP-managed EVM custody. CDP on Solana is not yet wired — use the escape
512
377
  * hatch.
513
- * @experimental
514
378
  */
515
379
  type X402SignerConfig = X402CdpSignerConfig | {
516
380
  /** Name of the `ctx.secrets` entry holding the private key. */
@@ -527,7 +391,6 @@ type X402SignerConfig = X402CdpSignerConfig | {
527
391
  };
528
392
  /**
529
393
  * Resolve a facilitator's base URL, applying the public default.
530
- * @experimental
531
394
  */
532
395
  declare const resolveFacilitatorUrl: (facilitator?: FacilitatorConfig) => string;
533
- export { AllowedAsset as A, FriendlyNetwork as B, type ClientEvmSigner as C, DEFAULT_ALLOWED_ASSETS as D, EvmAddress as E, type FacilitatorConfig as F, SVM_NETWORKS as G, NETWORK_TO_CAIP2 as N, PaymentEventRow as P, type SpendPolicy as S, X402PayConfig as X, ClientSvmSigner as a, Caip2 as b, type DEFAULT_FACILITATOR_URL as c, type DEFAULT_STABLECOIN_DECIMALS as d, type SpendState as e, type X402CdpSignerConfig as f, type X402Network as g, X402Price as h, X402SignerConfig as i, assertBoundedPolicy as j, buildPaymentGuard as k, buildSpendPolicy as l, createSpendState as m, isEvmNetwork as n, isSvmNetwork as o, resolveFacilitatorUrl as p, X402ChargeConfig as q, releaseSpendOnFailure as r, X402Receipt as s, toCaip2 as t, usdToAtomic as u, X402ReceiptSink as v, X402Recipient as w, toPaymentEventRow as x, toReceipt as y, EVM_NETWORKS as z };
396
+ export { AllowedAsset as A, type Caip2 as C, DEFAULT_ALLOWED_ASSETS as D, EvmAddress as E, type FacilitatorConfig as F, NETWORK_TO_CAIP2 as N, PaymentEventRow as P, type SpendPolicy as S, X402PayConfig as X, DEFAULT_FACILITATOR_URL as a, DEFAULT_STABLECOIN_DECIMALS as b, type X402CdpSignerConfig as c, type X402Network as d, type X402Price as e, type X402SignerConfig as f, type isSvmNetwork as g, X402ChargeConfig as h, isEvmNetwork as i, X402Receipt as j, X402ReceiptSink as k, X402Recipient as l, toPaymentEventRow as m, EVM_NETWORKS as n, FriendlyNetwork as o, SVM_NETWORKS as p, resolveFacilitatorUrl as r, toCaip2 as t, usdToAtomic as u };
@@ -1 +1 @@
1
- import{createChargeMiddleware as w}from"./createChargeMiddleware-CCcn8Fg_.mjs";const h=(o,r)=>{let t;return async(n,a)=>{t??=w(o).catch(i=>{throw t=void 0,i});const d=await t,e=n,c=typeof e.waitUntil=="function"?{waitUntil:i=>{e.waitUntil?.(i)}}:void 0;return d.handle(a,()=>r(n,a),c)}};export{h as withX402};
1
+ import{createChargeMiddleware as w}from"./createChargeMiddleware-DyOEuTCT.mjs";const h=(o,r)=>{let t;return async(n,a)=>{t??=w(o).catch(i=>{throw t=void 0,i});const d=await t,e=n,c=typeof e.waitUntil=="function"?{waitUntil:i=>{e.waitUntil?.(i)}}:void 0;return d.handle(a,()=>r(n,a),c)}};export{h as withX402};