@lunora/x402 1.0.0-alpha.2 → 1.0.0-alpha.21

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.
Files changed (35) hide show
  1. package/README.md +2 -0
  2. package/dist/charge/index.d.mts +110 -47
  3. package/dist/charge/index.d.ts +110 -47
  4. package/dist/charge/index.mjs +1 -7
  5. package/dist/index.d.mts +1 -1
  6. package/dist/index.d.ts +1 -1
  7. package/dist/index.mjs +1 -2
  8. package/dist/packem_shared/DEFAULT_ALLOWED_ASSETS-BIIP_mdG.mjs +1 -0
  9. package/dist/packem_shared/DEFAULT_FACILITATOR_URL-lUtljfJI.mjs +1 -0
  10. package/dist/packem_shared/EVM_NETWORKS-XOms9Rtk.mjs +1 -0
  11. package/dist/packem_shared/config.d-Dki_2r9a.d.mts +472 -0
  12. package/dist/packem_shared/config.d-Dki_2r9a.d.ts +472 -0
  13. package/dist/packem_shared/createChargeMiddleware-MQhSA6Wt.mjs +1 -0
  14. package/dist/packem_shared/createFacilitatorClient-Dj4Ll9xQ.mjs +1 -0
  15. package/dist/packem_shared/createPayFetch-B6A51xPI.mjs +1 -0
  16. package/dist/packem_shared/createProcedureChargeGate-Cfm5mD2y.mjs +1 -0
  17. package/dist/packem_shared/registerWallet-Cu4qF5tj.mjs +1 -0
  18. package/dist/packem_shared/toPaymentEventRow-D_kRVcb3.mjs +1 -0
  19. package/dist/packem_shared/withX402-D10895ct.mjs +1 -0
  20. package/dist/pay/index.d.mts +61 -43
  21. package/dist/pay/index.d.ts +61 -43
  22. package/dist/pay/index.mjs +1 -21
  23. package/package.json +8 -8
  24. package/dist/packem_shared/DEFAULT_FACILITATOR_URL-Cbz6kIqa.mjs +0 -4
  25. package/dist/packem_shared/DEFAULT_STABLECOIN_DECIMALS-CSu5b5lD.mjs +0 -85
  26. package/dist/packem_shared/EVM_NETWORKS-BhnYWUQ4.mjs +0 -26
  27. package/dist/packem_shared/config.d-CddwCiBm.d.mts +0 -325
  28. package/dist/packem_shared/config.d-CddwCiBm.d.ts +0 -325
  29. package/dist/packem_shared/createChargeMiddleware-BJkYJeFf.mjs +0 -148
  30. package/dist/packem_shared/createFacilitatorClient-rXHBnCZm.mjs +0 -16
  31. package/dist/packem_shared/createPayFetch-O2vkvM1v.mjs +0 -17
  32. package/dist/packem_shared/createProcedureChargeGate-CV8ITlQP.mjs +0 -19
  33. package/dist/packem_shared/registerWallet-I4pVwq65.mjs +0 -109
  34. package/dist/packem_shared/toPaymentEventRow-DW4O9N7Y.mjs +0 -22
  35. package/dist/packem_shared/withX402-rUq0voT8.mjs +0 -15
@@ -0,0 +1,472 @@
1
+ import { ClientEvmSigner } from '@x402/evm';
2
+ import { ClientSvmSigner } from '@x402/svm';
3
+ import { ProcessSettleSuccessResponse } from '@x402/core/http';
4
+ import { BeforePaymentCreationHook, PaymentPolicy, OnPaymentCreationFailureHook } from '@x402/core/client';
5
+ import { PaymentRequirements } from '@x402/core/types';
6
+ /**
7
+ * A normalised record of one settled x402 payment. The settled `amount` is kept
8
+ * as its exact on-chain atomic-unit string (USDC has 6 decimals) — never coerced
9
+ * to a fractional-dollar number — so no precision is lost crossing the reporting
10
+ * seam.
11
+ * @experimental
12
+ */
13
+ interface X402Receipt {
14
+ /** Settled amount in the asset's atomic base units (USDC: 6 decimals), as an exact string. */
15
+ readonly amount: string;
16
+ /** The settled asset's contract / mint address (e.g. Base USDC). */
17
+ readonly asset: string;
18
+ /** The payer's wallet address, when the facilitator reports it. */
19
+ readonly from: string | undefined;
20
+ /** The settlement network as a CAIP-2 id (e.g. `eip155:8453`). */
21
+ readonly network: string;
22
+ /** The gated resource this payment bought (a URL, or a procedure's `file:function` id). */
23
+ readonly resource: string;
24
+ /** The payout wallet the funds settled to (the merchant recipient). */
25
+ readonly to: string;
26
+ /** When the receipt was produced (epoch milliseconds). */
27
+ readonly ts: number;
28
+ /** On-chain settlement transaction id / hash. */
29
+ readonly tx: string;
30
+ }
31
+ /**
32
+ * A one-way, opt-in sink for settled-payment receipts. Wire it via
33
+ * `config.onReceipt`. It is best-effort telemetry — the middleware fires it after
34
+ * settlement, does not block the paid response on it, and swallows any error it
35
+ * throws — so a sink must never rely on being awaited or on its failures
36
+ * surfacing.
37
+ * @experimental
38
+ */
39
+ type X402ReceiptSink = (receipt: X402Receipt) => Promise<void> | void;
40
+ /**
41
+ * Normalise a successful facilitator settlement into an {@link X402Receipt}.
42
+ * `resource` (the gated URL or procedure id) and `ts` are supplied by the caller —
43
+ * the settlement result carries neither. Prefers the actual settled `amount`
44
+ * (present for `upto`-scheme partial settlements) and falls back to the route's
45
+ * required amount for `exact`.
46
+ * @experimental
47
+ */
48
+ declare const toReceipt: (settlement: ProcessSettleSuccessResponse, context: {
49
+ readonly resource: string;
50
+ readonly ts: number;
51
+ }) => X402Receipt;
52
+ /**
53
+ * A row for `@lunora/payment`'s durable `events` table. Deliberately a plain
54
+ * structural type — building one imports nothing from `@lunora/payment`, so the
55
+ * rails stay decoupled.
56
+ * @experimental
57
+ */
58
+ interface PaymentEventRow {
59
+ /** Epoch milliseconds the settlement was recorded. */
60
+ readonly processedAt: number;
61
+ /** The rail that produced the event. */
62
+ readonly provider: "x402";
63
+ /** The settlement tx hash — the natural unique event id (the table is unique on `(provider, providerEventId)`). */
64
+ readonly providerEventId: string;
65
+ /** The event kind, namespaced to the x402 rail. */
66
+ readonly type: "x402.settled";
67
+ }
68
+ /**
69
+ * Shape a receipt as a row for `@lunora/payment`'s durable `events` table, so a
70
+ * settled x402 payment shows in Studio's Payments panel (its recent-events card)
71
+ * with ZERO coupling: this returns a plain object matching that table's
72
+ * documented column contract (`provider` / `providerEventId` / `type` /
73
+ * `processedAt`, unique on `(provider, providerEventId)`) and imports nothing
74
+ * from `@lunora/payment`. Insert it from a mutation ctx:
75
+ *
76
+ * ```ts
77
+ * onReceipt: (receipt) => ctx.db.insert("events", toPaymentEventRow(receipt)),
78
+ * ```
79
+ *
80
+ * The source of truth for the column contract is `@lunora/payment`'s `events`
81
+ * table (`packages/payment/src/schema.ts`). Amount / from / to / resource are
82
+ * intentionally not on this row — that card renders none of them; read them off
83
+ * the {@link X402Receipt} (e.g. into your own revenue table) if you need them.
84
+ * @experimental
85
+ */
86
+ declare const toPaymentEventRow: (receipt: X402Receipt) => PaymentEventRow;
87
+ /**
88
+ * Network identity for `@lunora/x402`.
89
+ *
90
+ * `@x402/core` v2 speaks **CAIP-2** chain ids (`eip155:8453` for Base,
91
+ * `solana:5eyk…` for Solana mainnet) — `type Network = ` `${string}:${string}` ``.
92
+ * Lunora keeps ergonomic **friendly** names (`"base"`, `"base-sepolia"`) as the
93
+ * public surface and maps them to CAIP-2 here, at the single seam where we hand a
94
+ * network to the SDK. A raw CAIP-2 string is also accepted as a power-user escape
95
+ * hatch (e.g. a chain we don't yet have a friendly alias for).
96
+ *
97
+ * The friendly set is intentionally scoped to chains `@x402/evm` / `@x402/svm`
98
+ * can settle the ergonomic `price:"$0.01"` path on out of the box (i.e. chains in
99
+ * their `DEFAULT_STABLECOINS` registry). Notably that excludes Optimism and
100
+ * Avalanche today — advertising them would 500 at settlement — so they are not
101
+ * friendly aliases; a caller who needs them can still pass a raw CAIP-2 id with an
102
+ * explicit asset.
103
+ */
104
+ /**
105
+ * A CAIP-2 chain identifier, e.g. `"eip155:8453"` (Base) or `"solana:5eyk…"`.
106
+ * @experimental
107
+ */
108
+ type Caip2 = `${string}:${string}`;
109
+ /**
110
+ * Friendly network names Lunora maps to CAIP-2 for `@x402/core`.
111
+ * @experimental
112
+ */
113
+ type FriendlyNetwork = "arbitrum" | "arbitrum-sepolia" | "base" | "base-sepolia" | "ethereum" | "polygon" | "solana" | "solana-devnet";
114
+ /**
115
+ * A network Lunora can settle on: a {@link FriendlyNetwork} alias (mapped to
116
+ * CAIP-2 internally) or a raw {@link Caip2} id for chains without a friendly name.
117
+ * @experimental
118
+ */
119
+ type X402Network = Caip2 | FriendlyNetwork;
120
+ /**
121
+ * Friendly name → CAIP-2 id. Values verified against `@x402/evm` and `@x402/svm`
122
+ * `DEFAULT_STABLECOINS` at 2.17.0. `base` / `base-sepolia` are the primary
123
+ * prod / test pair.
124
+ * @experimental
125
+ */
126
+ declare const NETWORK_TO_CAIP2: {
127
+ readonly arbitrum: "eip155:42161";
128
+ readonly "arbitrum-sepolia": "eip155:421614";
129
+ readonly base: "eip155:8453";
130
+ readonly "base-sepolia": "eip155:84532";
131
+ readonly ethereum: "eip155:1";
132
+ readonly polygon: "eip155:137";
133
+ readonly solana: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
134
+ readonly "solana-devnet": "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1";
135
+ };
136
+ /**
137
+ * EVM friendly networks (signed via `@x402/evm` + viem).
138
+ * @experimental
139
+ */
140
+ declare const EVM_NETWORKS: readonly ["arbitrum", "arbitrum-sepolia", "base", "base-sepolia", "ethereum", "polygon"];
141
+ /**
142
+ * Solana friendly networks (signed via `@x402/svm`).
143
+ * @experimental
144
+ */
145
+ declare const SVM_NETWORKS: readonly ["solana", "solana-devnet"];
146
+ /**
147
+ * Resolve a network to its CAIP-2 id. Friendly aliases are looked up; a value
148
+ * that already looks like CAIP-2 (`namespace:reference`) passes through.
149
+ * @experimental
150
+ */
151
+ declare const toCaip2: (network: X402Network) => Caip2;
152
+ /**
153
+ * True when `network` settles on an EVM chain (viem signer path).
154
+ * @experimental
155
+ */
156
+ declare const isEvmNetwork: (network: X402Network) => boolean;
157
+ /**
158
+ * True when `network` settles on Solana (`@x402/svm` signer path).
159
+ * @experimental
160
+ */
161
+ declare const isSvmNetwork: (network: X402Network) => boolean;
162
+ /**
163
+ * USDC uses 6 decimals, so a USD price converts to atomic base units at `10 ** 6`.
164
+ * This is only the *default* for the standalone {@link usdToAtomic} helper —
165
+ * a spend policy never assumes it, and scales each requirement by the decimals of
166
+ * the asset it actually names (see {@link SpendPolicy.allowedAssets}).
167
+ * @experimental
168
+ */
169
+ declare const DEFAULT_STABLECOIN_DECIMALS = 6;
170
+ /**
171
+ * A stablecoin an agent wallet may pay in, and the decimals its atomic amounts are
172
+ * denominated in.
173
+ *
174
+ * `decimals` is required and explicit: a 402 server names the token contract to
175
+ * transfer, and the same atomic amount means a wildly different sum in a 6-decimal
176
+ * versus an 18-decimal token. Assuming a decimal count is how a tiny USD cap comes
177
+ * to authorise a large transfer, so the caller states it per asset. Note
178
+ * `@x402/evm`'s own `DEFAULT_STABLECOINS` registry is *not* uniformly 6-decimal
179
+ * (MegaUSD and Mezo USD are 18), which is exactly why it can't be trusted as a gate.
180
+ * @experimental
181
+ */
182
+ interface AllowedAsset {
183
+ /** Token contract (EVM) or mint (SVM) address. Matched case-insensitively on EVM, exactly on SVM. */
184
+ readonly asset: string;
185
+ /** Atomic base-unit decimals for this asset. Used to scale the USD caps — must match the token on chain. */
186
+ readonly decimals: number;
187
+ /** The network this asset lives on. Friendly names are resolved to CAIP-2. */
188
+ readonly network: X402Network;
189
+ }
190
+ /**
191
+ * The assets a policy allows when it doesn't name its own — the canonical
192
+ * 6-decimal, dollar-pegged USDC on each network Lunora has a friendly alias for.
193
+ *
194
+ * Deliberately a small hand-mirrored table rather than `@x402/evm`'s
195
+ * `DEFAULT_STABLECOINS`: that registry mixes 6- and 18-decimal assets, and importing
196
+ * it would pull viem into every bundle that touches a policy (the scheme modules are
197
+ * dynamically imported for exactly that reason — see `wallet.ts`). Addresses verified
198
+ * against `@x402/evm` `DEFAULT_STABLECOINS` and `@x402/svm` `USDC_*_ADDRESS` at 2.19.0.
199
+ *
200
+ * `ethereum` (`eip155:1`) is absent — the SDK ships no default stablecoin for it, so
201
+ * paying there needs an explicit {@link SpendPolicy.allowedAssets} entry.
202
+ * @experimental
203
+ */
204
+ declare const DEFAULT_ALLOWED_ASSETS: ReadonlyArray<AllowedAsset>;
205
+ /**
206
+ * Spend limits and approval gates for an agent wallet. At least one bound must be
207
+ * set — see {@link assertBoundedPolicy} — or the pay rail refuses to build.
208
+ *
209
+ * Caps are denominated in USD (the stablecoin's dollar value); addresses and
210
+ * networks are matched against the requirement the server offers.
211
+ * @experimental
212
+ */
213
+ interface SpendPolicy {
214
+ /**
215
+ * Asset allowlist, each entry carrying its own `decimals` (defaults to
216
+ * {@link DEFAULT_ALLOWED_ASSETS} — canonical USDC per friendly network).
217
+ *
218
+ * This is a **security gate, not a convenience**: the server picks which token
219
+ * contract gets transferred, so a policy that only caps a USD amount caps nothing
220
+ * until the asset behind that amount is pinned. A requirement naming an asset
221
+ * outside this list is refused, and the USD caps are scaled by the matched entry's
222
+ * `decimals` — never by an assumed decimal count.
223
+ *
224
+ * Every entry must be dollar-pegged: the caps are USD, and the per-run ledger sums
225
+ * atomic units across payments, so a non-$1 asset silently mis-prices both.
226
+ */
227
+ readonly allowedAssets?: ReadonlyArray<AllowedAsset>;
228
+ /** Network allowlist. When set, only these networks may be paid on. */
229
+ readonly allowedNetworks?: ReadonlyArray<X402Network>;
230
+ /** Recipient allowlist. When set, only these `payTo` addresses may be paid. */
231
+ readonly allowedRecipients?: ReadonlyArray<string>;
232
+ /**
233
+ * @deprecated One policy-wide decimal count can't describe the assets a server may
234
+ * name, and guessing it is what let a small USD cap authorise a large transfer.
235
+ * Setting this now throws — put the asset in {@link SpendPolicy.allowedAssets} with
236
+ * its own `decimals` instead.
237
+ */
238
+ readonly decimals?: number;
239
+ /** Hard ceiling on a single payment, in USD. */
240
+ readonly maxPerCall?: X402Price;
241
+ /** Hard ceiling on cumulative spend across this wallet's lifetime, in USD. */
242
+ readonly maxPerRun?: X402Price;
243
+ /**
244
+ * Approval gate. Called with the selected requirement before signing; return
245
+ * `false` (or reject) to refuse the payment. Use for human-in-the-loop or any
246
+ * dynamic rule the static caps can't express.
247
+ */
248
+ readonly onPaymentRequired?: (requirement: PaymentRequirements) => Promise<boolean> | boolean;
249
+ }
250
+ /**
251
+ * A running spend ledger the per-run cap is measured (and reserved) against.
252
+ * @experimental
253
+ */
254
+ interface SpendState {
255
+ /** Reserve a payment (atomic base units) against the running total, before it is signed. */
256
+ readonly add: (amount: bigint) => void;
257
+ /** Release a previously reserved amount (atomic base units) — e.g. a declined or failed payment. Clamps at 0. */
258
+ readonly release: (amount: bigint) => void;
259
+ /** Cumulative spend so far, in atomic base units. */
260
+ readonly spentAtomic: bigint;
261
+ }
262
+ /**
263
+ * A fresh spend ledger. One per wallet instance; the guard reserves into it and
264
+ * releases from it.
265
+ * @experimental
266
+ */
267
+ declare const createSpendState: () => SpendState;
268
+ /**
269
+ * Convert a USD amount (`0.01`, `"0.01"`, or the `"$0.01"` shorthand) to atomic
270
+ * stablecoin base units, exactly — parsed digit-by-digit so no binary-float drift
271
+ * can round a cap the wrong way. Throws on a malformed amount (including
272
+ * exponential notation like `"1e-7"`, which a decimal string never needs).
273
+ * @experimental
274
+ */
275
+ declare const usdToAtomic: (usd: X402Price, decimals?: number) => bigint;
276
+ /**
277
+ * A `PaymentPolicy` that narrows the server's offered requirements to those a
278
+ * bounded wallet may pay: in an allowed asset, within the per-call cap *for that
279
+ * asset's decimals*, to an allowed recipient, on an allowed network. An empty result
280
+ * means the client cannot pay — fail-closed.
281
+ *
282
+ * The asset check comes first and is what makes the amount check mean anything. The
283
+ * server chooses the token contract the scheme will sign a transfer against, and
284
+ * `amount` is in that token's atomic base units — so comparing it against a USD cap
285
+ * converted at an assumed decimal count mis-prices any asset that doesn't match the
286
+ * assumption. Pinning the asset (and taking its decimals from the policy, not the
287
+ * requirement) closes that.
288
+ * @experimental
289
+ */
290
+ declare const buildSpendPolicy: (policy: SpendPolicy) => PaymentPolicy;
291
+ /**
292
+ * A `BeforePaymentCreationHook` enforcing the stateful bounds the stateless
293
+ * {@link buildSpendPolicy} filter can't: the cumulative per-run cap and the async
294
+ * confirmation gate. Aborts (no signature) when either would be violated.
295
+ *
296
+ * The per-run cap is *reserved* into `state` as soon as the check passes — before
297
+ * the `await policy.onPaymentRequired` below, and before `@x402/core` ever attempts
298
+ * to sign — not recorded afterwards. This closes a check-then-act race: without an
299
+ * atomic reserve, N concurrent payments could each read the same `spentAtomic`,
300
+ * all pass the cap check, and all record, overspending the cap by up to
301
+ * (N−1)×maxPerCall. A declined confirmation releases the reservation before this
302
+ * hook returns; {@link releaseSpendOnFailure} releases it if the signature itself
303
+ * later fails. The reservation is intentionally *not* released on success — a
304
+ * committed payment stays counted.
305
+ *
306
+ * The asset is re-checked here rather than trusted from {@link buildSpendPolicy}:
307
+ * the two are registered on separate client seams, and a guard that assumed the
308
+ * filter ran would be one wiring change away from signing an unpinned asset.
309
+ * @experimental
310
+ */
311
+ declare const buildPaymentGuard: (policy: SpendPolicy, state: SpendState) => BeforePaymentCreationHook;
312
+ /**
313
+ * An `OnPaymentCreationFailureHook` that releases a reservation
314
+ * {@link buildPaymentGuard} made when the scheme's signature creation itself
315
+ * throws (network error, wallet error, …) after the guard already approved and
316
+ * reserved the amount. Without this, a failed signature would permanently
317
+ * over-count against the per-run cap for the rest of the run — fail-closed, but
318
+ * needlessly so when the client (`wrapFetchWithPayment`) may retry.
319
+ * @experimental
320
+ */
321
+ declare const releaseSpendOnFailure: (state: SpendState) => OnPaymentCreationFailureHook;
322
+ /**
323
+ * Guard at wallet-build time: refuse a policy with no bound whatsoever. Signing
324
+ * money on an agent's behalf with unlimited spend authority is never the intent,
325
+ * so this fails loudly rather than defaulting to unbounded.
326
+ *
327
+ * `allowedNetworks` / `allowedRecipients` / `allowedAssets` narrow *where* a payment
328
+ * can go and *in what*, but none caps *how much* — a policy with only allowlists still
329
+ * authorises unlimited spend to any recipient it permits. Only `maxPerCall`,
330
+ * `maxPerRun`, or a dynamic `onPaymentRequired` gate actually bound spend, so only
331
+ * those count here.
332
+ * @experimental
333
+ */
334
+ declare const assertBoundedPolicy: (policy: SpendPolicy) => void;
335
+ /**
336
+ * The public, Coinbase-operated facilitator (verify + settle). It needs no API
337
+ * key. Override with a self-hosted or CDP facilitator via {@link FacilitatorConfig}.
338
+ * @experimental
339
+ */
340
+ declare const DEFAULT_FACILITATOR_URL = "https://x402.org/facilitator";
341
+ /**
342
+ * How to reach a facilitator's `/verify` + `/settle` endpoints.
343
+ * @experimental
344
+ */
345
+ interface FacilitatorConfig {
346
+ /** Extra headers for a private facilitator (e.g. a CDP bearer token). */
347
+ readonly headers?: Record<string, string>;
348
+ /** Base URL. Defaults to {@link DEFAULT_FACILITATOR_URL}. */
349
+ readonly url?: string;
350
+ }
351
+ /**
352
+ * A resource's price, as a USD-denominated decimal string (`"0.01"`, or the
353
+ * `"$0.01"` shorthand) or a number of dollars (`0.01`). The scheme resolves it
354
+ * to the network's stablecoin base units (USDC has 6 decimals) at challenge
355
+ * time. (Kept `number | string` rather than a `` `$${string}` `` template
356
+ * member — the template is subsumed by `string`, so it only adds noise.)
357
+ * @experimental
358
+ */
359
+ type X402Price = number | string;
360
+ /**
361
+ * An EVM recipient address (the merchant wallet that receives settlement).
362
+ * @experimental
363
+ */
364
+ type EvmAddress = `0x${string}`;
365
+ /**
366
+ * Recipient wallet the facilitator settles payments to, per network family.
367
+ * @experimental
368
+ */
369
+ interface X402Recipient {
370
+ /** EVM payout address (required for EVM networks). */
371
+ readonly evm?: EvmAddress;
372
+ /** Solana payout address, base58 (required for SVM networks). */
373
+ readonly svm?: string;
374
+ }
375
+ /**
376
+ * Server-side (charge rail) config. The server needs only a **recipient
377
+ * address** — no private key — because the facilitator performs settlement.
378
+ * @experimental
379
+ */
380
+ interface X402ChargeConfig {
381
+ readonly facilitator?: FacilitatorConfig;
382
+ /** Network this resource settles on. */
383
+ readonly network: X402Network;
384
+ /**
385
+ * Opt-in, one-way telemetry sink fired once per settled payment. Best-effort:
386
+ * it runs after settlement, never blocks the paid response, and its errors are
387
+ * swallowed. Use it to mirror x402 revenue into a durable table / `@lunora/payment`'s
388
+ * `events` table (see `toPaymentEventRow`) so it surfaces in Studio.
389
+ */
390
+ readonly onReceipt?: X402ReceiptSink;
391
+ /** Default price for a gated resource; per-resource overrides win. */
392
+ readonly price: X402Price;
393
+ /** Payout wallet(s). */
394
+ readonly recipient: X402Recipient;
395
+ }
396
+ /**
397
+ * Client-side (pay rail) config. The signer holds spending authority, so the
398
+ * pay rail is ActionCtx-only and MUST be paired with a spend `policy` — the pay
399
+ * rail refuses to build if the policy is unbounded.
400
+ * @experimental
401
+ */
402
+ interface X402PayConfig {
403
+ /** Network to transact on. Determines the signer family (EVM vs SVM). */
404
+ readonly network: X402Network;
405
+ /** Mandatory spend limits + approval gates. An unbounded policy is refused. */
406
+ readonly policy: SpendPolicy;
407
+ /** How the agent wallet is custodied (raw key, a user-supplied signer, or CDP-managed). */
408
+ readonly signer: X402SignerConfig;
409
+ }
410
+ /**
411
+ * CDP-managed wallet custody via `@coinbase/cdp-sdk` (an optional peer). The SDK
412
+ * gets-or-creates a named server account and signs the x402 EIP-712 payment
413
+ * authorization with it — no private key ever leaves Coinbase. Needs three CDP
414
+ * credentials, read from `ctx.secrets` under names that default to the SDK's own
415
+ * env-var names; override them if your secrets are named differently. (Note
416
+ * `@coinbase/x402` is a facilitator-auth helper, not a signer provider — CDP
417
+ * custody is `@coinbase/cdp-sdk`.) EVM only today; for CDP on Solana, build a
418
+ * `@solana/kit` signer around your CDP account and pass it via the `"signer"`
419
+ * escape hatch.
420
+ * @experimental
421
+ */
422
+ interface X402CdpSignerConfig {
423
+ /** CDP account name to get-or-create and sign with. */
424
+ readonly account: string;
425
+ /** `ctx.secrets` name for the CDP API key id. Default `"CDP_API_KEY_ID"`. */
426
+ readonly apiKeyIdSecretName?: string;
427
+ /** `ctx.secrets` name for the CDP API key secret. Default `"CDP_API_KEY_SECRET"`. */
428
+ readonly apiKeySecretName?: string;
429
+ readonly type: "cdp";
430
+ /** `ctx.secrets` name for the CDP wallet secret. Default `"CDP_WALLET_SECRET"`. */
431
+ readonly walletSecretName?: string;
432
+ }
433
+ /**
434
+ * Wallet custody for the pay rail — three shapes.
435
+ *
436
+ * `"raw-key"` resolves a private key from `ctx.secrets` (viem for EVM, a
437
+ * `@solana/kit` keypair for Solana) — simplest, self-custodied.
438
+ *
439
+ * `"signer"` is the escape hatch: hand in a signer you already built — any
440
+ * `@x402/evm` `ClientEvmSigner` (a viem account from Turnkey, Privy, an AWS/GCP
441
+ * KMS `toAccount`, CDP's viem adapter, …) on an EVM network, or an `@x402/svm`
442
+ * `ClientSvmSigner` (a `@solana/kit` `TransactionSigner`) on Solana. Adapt any
443
+ * custody provider to the structural signer and pass it here; `@lunora/x402`
444
+ * takes no dependency on the provider's SDK.
445
+ *
446
+ * `"cdp"` is a Coinbase-managed wallet via `@coinbase/cdp-sdk`
447
+ * ({@link X402CdpSignerConfig}).
448
+ *
449
+ * Wired today: raw-key (EVM + SVM), the user-supplied signer (both families),
450
+ * and CDP-managed EVM custody. CDP on Solana is not yet wired — use the escape
451
+ * hatch.
452
+ * @experimental
453
+ */
454
+ type X402SignerConfig = X402CdpSignerConfig | {
455
+ /** Name of the `ctx.secrets` entry holding the private key. */
456
+ readonly secretName: string;
457
+ readonly type: "raw-key";
458
+ } | {
459
+ /**
460
+ * A pre-built signer you own: an EVM `ClientEvmSigner` (viem account) on
461
+ * an EVM network, or an SVM `ClientSvmSigner` (`@solana/kit`
462
+ * `TransactionSigner`) on Solana. Must match the config `network`'s family.
463
+ */
464
+ readonly signer: ClientEvmSigner | ClientSvmSigner;
465
+ readonly type: "signer";
466
+ };
467
+ /**
468
+ * Resolve a facilitator's base URL, applying the public default.
469
+ * @experimental
470
+ */
471
+ declare const resolveFacilitatorUrl: (facilitator?: FacilitatorConfig) => string;
472
+ export { AllowedAsset as A, Caip2 as C, DEFAULT_FACILITATOR_URL as D, EVM_NETWORKS as E, FacilitatorConfig as F, NETWORK_TO_CAIP2 as N, PaymentEventRow as P, SVM_NETWORKS as S, X402CdpSignerConfig as X, EvmAddress as a, FriendlyNetwork as b, X402ChargeConfig as c, X402Network as d, X402PayConfig as e, X402Price as f, X402Receipt as g, X402ReceiptSink as h, X402Recipient as i, X402SignerConfig as j, isEvmNetwork as k, isSvmNetwork as l, DEFAULT_ALLOWED_ASSETS as m, DEFAULT_STABLECOIN_DECIMALS as n, SpendPolicy as o, SpendState as p, assertBoundedPolicy as q, resolveFacilitatorUrl as r, buildPaymentGuard as s, toCaip2 as t, buildSpendPolicy as u, createSpendState as v, releaseSpendOnFailure as w, usdToAtomic as x, toPaymentEventRow as y, toReceipt as z };