@dexterai/x402 3.8.0 → 3.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +310 -703
- package/dist/adapters/index.cjs +1 -1
- package/dist/adapters/index.d.cts +2 -2
- package/dist/adapters/index.d.ts +2 -2
- package/dist/adapters/index.js +1 -1
- package/dist/batch-settlement/index.d.cts +3 -3
- package/dist/batch-settlement/index.d.ts +3 -3
- package/dist/batch-settlement/seller/index.d.cts +4 -4
- package/dist/batch-settlement/seller/index.d.ts +4 -4
- package/dist/client/index.cjs +1 -1
- package/dist/client/index.d.cts +307 -237
- package/dist/client/index.d.ts +307 -237
- package/dist/client/index.js +1 -1
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.d.cts +12 -4
- package/dist/react/index.d.ts +12 -4
- package/dist/react/index.js +1 -1
- package/dist/server/index.cjs +4 -4
- package/dist/server/index.d.cts +62 -4
- package/dist/server/index.d.ts +62 -4
- package/dist/server/index.js +4 -4
- package/dist/{types-XG8QvfyL.d.cts → types-C8lyIOmX.d.cts} +1 -1
- package/dist/{types-DllrEG_Z.d.ts → types-CTl7yVq6.d.ts} +1 -1
- package/dist/{types-pOwQlGEV.d.cts → types-CiPcPs0w.d.cts} +1 -1
- package/dist/{types-DDBPREEu.d.ts → types-D9VMq7In.d.ts} +1 -1
- package/dist/{types-htvWHuW3.d.cts → types-RxdlGPaG.d.cts} +122 -1
- package/dist/{types-htvWHuW3.d.ts → types-RxdlGPaG.d.ts} +122 -1
- package/dist/{sponsored-access-D96FgkQK.d.ts → x402-client-CHrU2Bs6.d.cts} +114 -63
- package/dist/{sponsored-access-D7H-womP.d.cts → x402-client-CzseAnIt.d.ts} +114 -63
- package/package.json +1 -1
package/dist/client/index.d.ts
CHANGED
|
@@ -1,100 +1,240 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { W as WalletSet, S as SettlementProbe, a as SolanaWallet, E as EvmWallet, A as AccessPassClientConfig, P as PaymentAccept } from '../types-RxdlGPaG.js';
|
|
2
|
+
export { e as AccessPassInfo, d as AccessPassTier, C as ChainAdapter, X as X402Error, b as createEvmAdapter, c as createSolanaAdapter } from '../types-RxdlGPaG.js';
|
|
3
|
+
import { SIWxSigner } from '@x402/extensions/sign-in-with-x';
|
|
4
4
|
import { Keypair } from '@solana/web3.js';
|
|
5
|
+
export { P as PaymentReceipt, d as X402Client, X as X402ClientConfig, c as createX402Client, f as fireImpressionBeacon, b as getPaymentReceipt, a as getSponsoredAccessInfo, g as getSponsoredRecommendations } from '../x402-client-CzseAnIt.js';
|
|
5
6
|
export { FormattedResource as CapabilityAPI, CapabilitySearchOptions, CapabilitySearchResult, NoMatchReason, capabilitySearch } from '@dexterai/x402-core';
|
|
6
|
-
import { SIWxSigner } from '@x402/extensions/sign-in-with-x';
|
|
7
7
|
export { B as BASE_MAINNET, D as DEXTER_FACILITATOR_URL, S as SOLANA_MAINNET, U as USDC_MINT } from '../constants-qU-4U3L-.js';
|
|
8
8
|
export { SponsoredAccessSettlementInfo, SponsoredRecommendation } from '@dexterai/x402-ads-types';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
11
|
+
* Shared contract for the x402 version seam. Both the v1 and v2 strategy
|
|
12
|
+
* modules implement PaymentStrategy. Callers depend ONLY on this file —
|
|
13
|
+
* never on a specific version module.
|
|
12
14
|
*/
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
15
|
+
|
|
16
|
+
/** A network reference, kept in BOTH forms so neither version loses info. */
|
|
17
|
+
interface NetworkRef {
|
|
18
|
+
/** CAIP-2 form, e.g. "eip155:8453", "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp". */
|
|
19
|
+
caip2: string;
|
|
20
|
+
/** Bare form, e.g. "base", "solana". */
|
|
21
|
+
bare: string;
|
|
22
|
+
/** "evm" | "svm" — which signer family. */
|
|
23
|
+
family: 'evm' | 'svm';
|
|
24
|
+
}
|
|
25
|
+
/** One payment option parsed from a 402 challenge, version-normalised. */
|
|
26
|
+
interface ChallengeOption {
|
|
27
|
+
scheme: string;
|
|
28
|
+
network: NetworkRef;
|
|
29
|
+
/** Atomic amount as a string (e.g. "2000"). */
|
|
30
|
+
amount: string;
|
|
31
|
+
asset: string;
|
|
32
|
+
payTo: string;
|
|
33
|
+
/** Optional — v1 challenges may omit it; a strategy supplies a default when absent. */
|
|
34
|
+
maxTimeoutSeconds?: number;
|
|
35
|
+
/** Scheme-specific extras, passed through verbatim from the merchant. */
|
|
36
|
+
extra?: Record<string, unknown>;
|
|
37
|
+
}
|
|
38
|
+
/** A 402 challenge, normalised across v1 and v2. */
|
|
39
|
+
interface PaymentChallenge {
|
|
40
|
+
x402Version: 1 | 2;
|
|
41
|
+
options: ChallengeOption[];
|
|
42
|
+
resourceUrl?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Result of a paid fetch. Never throws for an expected failure.
|
|
46
|
+
*
|
|
47
|
+
* The `ok: true` branch is further discriminated by `paid`:
|
|
48
|
+
* - `paid: true` — the endpoint demanded payment and we paid; `amountPaid`
|
|
49
|
+
* and `network` are present, `txSignature` optional.
|
|
50
|
+
* `response` is usually the merchant's response, but is
|
|
51
|
+
* `undefined` when the payment settled and the merchant
|
|
52
|
+
* never delivered a response before the deadline (a
|
|
53
|
+
* confirmed-but-unanswered payment — see `payment_unconfirmed`
|
|
54
|
+
* below for the unconfirmed counterpart).
|
|
55
|
+
* - `paid: false` — the endpoint returned a non-402 directly; no payment
|
|
56
|
+
* was attempted. Only `response` is present, because no
|
|
57
|
+
* payment-related fields are meaningful in that case.
|
|
58
|
+
*
|
|
59
|
+
* Callers should narrow on `paid` before reading payment fields. Previously
|
|
60
|
+
* (3.8.x and earlier) the dispatcher returned a phantom `network` placeholder
|
|
61
|
+
* on the unpaid branch; the discriminator forces a correct read.
|
|
62
|
+
*/
|
|
63
|
+
type PayResult = {
|
|
64
|
+
ok: true;
|
|
65
|
+
paid: true;
|
|
39
66
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
67
|
+
* The merchant's response. `undefined` when the payment was confirmed
|
|
68
|
+
* settled but the merchant did not respond before the deadline — you
|
|
69
|
+
* paid, the merchant never answered. Always check before use.
|
|
42
70
|
*/
|
|
71
|
+
response: Response | undefined;
|
|
72
|
+
/** Atomic amount actually paid. */
|
|
73
|
+
amountPaid: string;
|
|
74
|
+
network: NetworkRef;
|
|
75
|
+
txSignature?: string;
|
|
76
|
+
} | {
|
|
77
|
+
ok: true;
|
|
78
|
+
paid: false;
|
|
79
|
+
response: Response;
|
|
80
|
+
} | {
|
|
81
|
+
ok: false;
|
|
82
|
+
reason: 'unsupported_network' | 'insufficient_funds'
|
|
83
|
+
/** The merchant rejected the payment itself — bad/declined payload,
|
|
84
|
+
* failed verification. Our side: check the payment. */
|
|
85
|
+
| 'merchant_rejected'
|
|
86
|
+
/** The merchant ACCEPTED the payment shape but their own settlement
|
|
87
|
+
* failed (their facilitator errored). Not our payload — a
|
|
88
|
+
* merchant-side defect. `detail` carries their verbatim error. */
|
|
89
|
+
| 'settlement_failed' | 'no_payment_options'
|
|
90
|
+
/** No payment was sent before the deadline — the unpaid probe (or
|
|
91
|
+
* build/sign) ran past the pre-payment timeout. No money moved;
|
|
92
|
+
* safe to retry. */
|
|
93
|
+
| 'timeout'
|
|
94
|
+
/** The payment authorization WAS sent to the merchant, the merchant
|
|
95
|
+
* did not respond before the deadline, and settlement could not be
|
|
96
|
+
* confirmed. The payment MAY have settled on-chain. DO NOT
|
|
97
|
+
* blind-retry — a retry signs a fresh authorization and can pay
|
|
98
|
+
* again. `detail` explains the state. */
|
|
99
|
+
| 'payment_unconfirmed' | 'budget_exceeded' | 'error';
|
|
100
|
+
detail?: string;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
/** Options for a paid fetch. */
|
|
104
|
+
interface PayAndFetchOptions {
|
|
105
|
+
/** Max total atomic spend for this call. */
|
|
43
106
|
maxAmountAtomic?: string;
|
|
44
107
|
/**
|
|
45
|
-
*
|
|
108
|
+
* Pre-payment timeout in ms — the deadline for the unpaid probe and the
|
|
109
|
+
* build/sign step, i.e. everything BEFORE the payment authorization is
|
|
110
|
+
* sent. Exceeding it yields `reason: 'timeout'` (no money moved, safe to
|
|
111
|
+
* retry). Default 15000.
|
|
112
|
+
*
|
|
113
|
+
* This does NOT bound the wait for the merchant's response once payment
|
|
114
|
+
* has been dispatched — see `responseTimeoutMs`. The two phases have
|
|
115
|
+
* separate deadlines on purpose: once the payment is out the door,
|
|
116
|
+
* aborting the wait does not un-spend the money.
|
|
46
117
|
*/
|
|
47
|
-
|
|
118
|
+
timeoutMs?: number;
|
|
48
119
|
/**
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
120
|
+
* Post-payment timeout in ms — the deadline for the merchant's response
|
|
121
|
+
* AFTER the payment authorization has been sent. Exceeding it does not
|
|
122
|
+
* yield `'timeout'`; it yields `'payment_unconfirmed'` (or, once on-chain
|
|
123
|
+
* confirmation lands, a confirmed `paid: true`). Default 120000.
|
|
52
124
|
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* walletPrivateKey: process.env.SOLANA_PRIVATE_KEY!,
|
|
57
|
-
* accessPass: { preferTier: '1h', maxSpend: '1.00' },
|
|
58
|
-
* });
|
|
59
|
-
* // First call: auto-buys 1-hour pass
|
|
60
|
-
* // All subsequent calls: uses cached pass (no payment)
|
|
61
|
-
* ```
|
|
125
|
+
* Generous by design: research / scout / agent endpoints routinely take
|
|
126
|
+
* tens of seconds, and the money is already committed once this phase
|
|
127
|
+
* begins — there is no benefit to a tight deadline here.
|
|
62
128
|
*/
|
|
63
|
-
|
|
129
|
+
responseTimeoutMs?: number;
|
|
64
130
|
/**
|
|
65
|
-
*
|
|
66
|
-
*
|
|
131
|
+
* Solana RPC endpoint for v1 SVM payment signing. v1 Solana `exact`
|
|
132
|
+
* signing builds a real transaction and needs RPC access (mint lookup,
|
|
133
|
+
* recent blockhash). Ignored for EVM-only flows. Defaults to the public
|
|
134
|
+
* Solana RPC when omitted — callers should pass their own for
|
|
135
|
+
* reliability.
|
|
67
136
|
*/
|
|
68
|
-
|
|
137
|
+
solanaRpcUrl?: string;
|
|
69
138
|
}
|
|
70
139
|
/**
|
|
71
|
-
*
|
|
140
|
+
* The contract each version module implements.
|
|
72
141
|
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
142
|
+
* parseChallenge: given a raw 402 Response, extract the challenge — or
|
|
143
|
+
* null if this strategy does not recognise it as its version.
|
|
144
|
+
* pay: given a parsed challenge, sign + send the paid request, return
|
|
145
|
+
* the merchant's response.
|
|
146
|
+
*/
|
|
147
|
+
interface PaymentStrategy {
|
|
148
|
+
readonly version: 1 | 2;
|
|
149
|
+
parseChallenge(res: Response): Promise<PaymentChallenge | null>;
|
|
150
|
+
pay(url: string, requestInit: RequestInit, challenge: PaymentChallenge, wallets: WalletSet, opts: PayAndFetchOptions): Promise<PayResult>;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* The x402 version dispatcher — the ONLY code in the stack that decides
|
|
155
|
+
* v1 vs v2. It probes the endpoint once; if the response is a 402, it
|
|
156
|
+
* asks each strategy to parse it (v2 first, since v2 is current) and
|
|
157
|
+
* routes to whichever recognises it. Callers use payAndFetch and never
|
|
158
|
+
* branch on protocol version themselves.
|
|
159
|
+
*/
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Given a 402 Response, return the strategy that recognises it, or null.
|
|
163
|
+
* Exported for testing; payAndFetch is the normal entrypoint.
|
|
164
|
+
*/
|
|
165
|
+
declare function detectStrategy(res: Response): Promise<PaymentStrategy | null>;
|
|
166
|
+
/**
|
|
167
|
+
* Pay for and fetch a resource. Probes once; if the endpoint demands
|
|
168
|
+
* payment, detects the protocol version, and pays via the matching
|
|
169
|
+
* strategy. Returns a typed PayResult — never throws for an expected
|
|
170
|
+
* failure.
|
|
171
|
+
*/
|
|
172
|
+
declare function payAndFetch(url: string, requestInit: RequestInit, wallets: WalletSet, opts: PayAndFetchOptions): Promise<PayResult>;
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Two-way map between CAIP-2 network identifiers (x402 v2) and bare
|
|
176
|
+
* network names (x402 v1). The verifier's old bug was a one-way, lossy
|
|
177
|
+
* rewrite to bare names. This map is lossless: a NetworkRef always
|
|
178
|
+
* carries BOTH forms, so a v1 signer can use the bare name internally
|
|
179
|
+
* while the wire payload keeps whatever the merchant advertised.
|
|
180
|
+
*/
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Resolve a network string — CAIP-2 or bare — to a NetworkRef.
|
|
184
|
+
* Only networks in the canonical ENTRIES table resolve. An
|
|
185
|
+
* unrecognised network (including an unmapped eip155:* / solana:*
|
|
186
|
+
* chain) returns null — callers must not receive a half-resolved,
|
|
187
|
+
* misleading NetworkRef.
|
|
188
|
+
*/
|
|
189
|
+
declare function toNetworkRef(network: string): NetworkRef | null;
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Map a WalletSet to a SIWxSigner for wrapFetchWithSIWx, or null when
|
|
193
|
+
* neither wallet can sign SIW-X proofs.
|
|
194
|
+
*/
|
|
195
|
+
declare function toSiwxSigner(wallets: WalletSet): SIWxSigner | null;
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Standalone v1 X-PAYMENT header builder.
|
|
76
199
|
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
200
|
+
* Extracted from v1-strategy so that external consumers that manage their
|
|
201
|
+
* own fetch (e.g. a dexter-api payment route) can build a v1 header without
|
|
202
|
+
* pulling in the full PaymentStrategy machinery or the upstream `x402` lib.
|
|
80
203
|
*
|
|
81
|
-
*
|
|
82
|
-
|
|
83
|
-
|
|
204
|
+
* MUST NOT import v2-strategy or v1-strategy (seam isolation).
|
|
205
|
+
*/
|
|
206
|
+
|
|
207
|
+
/** Result of building a v1 X-PAYMENT header value. Never thrown. */
|
|
208
|
+
type V1HeaderResult = {
|
|
209
|
+
ok: true;
|
|
210
|
+
headerValue: string;
|
|
211
|
+
option: ChallengeOption;
|
|
212
|
+
/**
|
|
213
|
+
* Data to confirm settlement on-chain if a post-payment timeout fires.
|
|
214
|
+
* `undefined` for schemes with no on-chain confirmation check.
|
|
215
|
+
*/
|
|
216
|
+
settlementProbe?: SettlementProbe;
|
|
217
|
+
} | {
|
|
218
|
+
ok: false;
|
|
219
|
+
reason: 'unsupported_network' | 'budget_exceeded' | 'merchant_rejected' | 'error';
|
|
220
|
+
detail?: string;
|
|
221
|
+
};
|
|
222
|
+
/**
|
|
223
|
+
* Build a v1 `X-PAYMENT` header value for one of a challenge's options.
|
|
84
224
|
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
225
|
+
* This is the v1 payment-construction seam: it picks the first option
|
|
226
|
+
* whose chain family has a usable wallet, signs the v1 `exact` payload
|
|
227
|
+
* (EIP-3009 for EVM; a partially-signed Solana transaction for SVM),
|
|
228
|
+
* and base64-encodes the v1 PaymentPayload. It does NOT send a request —
|
|
229
|
+
* the caller owns the fetch. payAndFetch's v1 strategy uses this; so do
|
|
230
|
+
* external consumers that manage their own request flow.
|
|
87
231
|
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
* maxAmountAtomic: '1000000', // Max $1.00 per request
|
|
93
|
-
* verbose: true,
|
|
94
|
-
* });
|
|
95
|
-
* ```
|
|
232
|
+
* Returns a typed result; never throws for an expected failure.
|
|
233
|
+
*
|
|
234
|
+
* NO NETWORK REWRITE: the `network` field on the wire is the merchant's
|
|
235
|
+
* advertised v1 bare name verbatim (option.network.bare).
|
|
96
236
|
*/
|
|
97
|
-
declare function
|
|
237
|
+
declare function buildV1PaymentHeader(challenge: PaymentChallenge, wallets: WalletSet, opts: PayAndFetchOptions): Promise<V1HeaderResult>;
|
|
98
238
|
|
|
99
239
|
/**
|
|
100
240
|
* Keypair Wallet for Node.js
|
|
@@ -236,6 +376,101 @@ declare function createEvmKeypairWallet(privateKey: string): Promise<EvmWallet>;
|
|
|
236
376
|
*/
|
|
237
377
|
declare function isEvmKeypairWallet(wallet: unknown): wallet is EvmWallet;
|
|
238
378
|
|
|
379
|
+
/**
|
|
380
|
+
* Options for wrapFetch
|
|
381
|
+
*/
|
|
382
|
+
interface WrapFetchOptions {
|
|
383
|
+
/**
|
|
384
|
+
* Solana private key (base58 string or JSON array)
|
|
385
|
+
* Required for Solana payments.
|
|
386
|
+
*/
|
|
387
|
+
walletPrivateKey?: string | number[] | Uint8Array;
|
|
388
|
+
/**
|
|
389
|
+
* EVM private key (hex string with or without 0x prefix)
|
|
390
|
+
* Required for Base/EVM payments.
|
|
391
|
+
* Note: EVM support requires viem - import from '@dexterai/x402/adapters'
|
|
392
|
+
*/
|
|
393
|
+
evmPrivateKey?: string;
|
|
394
|
+
/**
|
|
395
|
+
* Preferred network when multiple options are available
|
|
396
|
+
* @default 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp' (Solana mainnet)
|
|
397
|
+
*/
|
|
398
|
+
preferredNetwork?: string;
|
|
399
|
+
/**
|
|
400
|
+
* Facilitator URL
|
|
401
|
+
* @default 'https://x402.dexter.cash'
|
|
402
|
+
*/
|
|
403
|
+
facilitatorUrl?: string;
|
|
404
|
+
/**
|
|
405
|
+
* Custom RPC URLs by network
|
|
406
|
+
*/
|
|
407
|
+
rpcUrls?: Record<string, string>;
|
|
408
|
+
/**
|
|
409
|
+
* Maximum payment amount in atomic units
|
|
410
|
+
* Rejects payments exceeding this amount.
|
|
411
|
+
*/
|
|
412
|
+
maxAmountAtomic?: string;
|
|
413
|
+
/**
|
|
414
|
+
* Enable verbose logging
|
|
415
|
+
*/
|
|
416
|
+
verbose?: boolean;
|
|
417
|
+
/**
|
|
418
|
+
* Access pass configuration.
|
|
419
|
+
* When provided, the client prefers purchasing time-limited passes
|
|
420
|
+
* over per-request payments. One payment grants unlimited requests.
|
|
421
|
+
*
|
|
422
|
+
* @example
|
|
423
|
+
* ```typescript
|
|
424
|
+
* const x402Fetch = wrapFetch(fetch, {
|
|
425
|
+
* walletPrivateKey: process.env.SOLANA_PRIVATE_KEY!,
|
|
426
|
+
* accessPass: { preferTier: '1h', maxSpend: '1.00' },
|
|
427
|
+
* });
|
|
428
|
+
* // First call: auto-buys 1-hour pass
|
|
429
|
+
* // All subsequent calls: uses cached pass (no payment)
|
|
430
|
+
* ```
|
|
431
|
+
*/
|
|
432
|
+
accessPass?: AccessPassClientConfig;
|
|
433
|
+
/**
|
|
434
|
+
* Called before signing a payment. Return true to proceed, false to reject.
|
|
435
|
+
* Used internally by Budget Accounts — can also be set directly.
|
|
436
|
+
*/
|
|
437
|
+
onPaymentRequired?: (requirements: PaymentAccept) => boolean | Promise<boolean>;
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Wrap fetch with automatic x402 payment handling
|
|
441
|
+
*
|
|
442
|
+
* @deprecated Slated for removal in `@dexterai/x402` 5.0. Use `payAndFetch`
|
|
443
|
+
* instead — it's version-agnostic across x402 v1 and v2 and returns a
|
|
444
|
+
* discriminated union that separates merchant rejection from settlement
|
|
445
|
+
* failure. Migration: `wrapFetch(fetch, { walletPrivateKey })` →
|
|
446
|
+
* `payAndFetch(url, init, { solana: createKeypairWallet(pk) })`.
|
|
447
|
+
*
|
|
448
|
+
* @param fetchImpl - The fetch function to wrap (usually `fetch` or `node-fetch`)
|
|
449
|
+
* @param options - Configuration options
|
|
450
|
+
* @returns A fetch function that handles x402 payments automatically
|
|
451
|
+
*
|
|
452
|
+
* @example Basic usage
|
|
453
|
+
* ```typescript
|
|
454
|
+
* import { wrapFetch } from '@dexterai/x402/client';
|
|
455
|
+
*
|
|
456
|
+
* const x402Fetch = wrapFetch(fetch, {
|
|
457
|
+
* walletPrivateKey: process.env.SOLANA_PRIVATE_KEY!,
|
|
458
|
+
* });
|
|
459
|
+
*
|
|
460
|
+
* const response = await x402Fetch('https://api.example.com/protected');
|
|
461
|
+
* ```
|
|
462
|
+
*
|
|
463
|
+
* @example With options
|
|
464
|
+
* ```typescript
|
|
465
|
+
* const x402Fetch = wrapFetch(fetch, {
|
|
466
|
+
* walletPrivateKey: process.env.SOLANA_PRIVATE_KEY!,
|
|
467
|
+
* maxAmountAtomic: '1000000', // Max $1.00 per request
|
|
468
|
+
* verbose: true,
|
|
469
|
+
* });
|
|
470
|
+
* ```
|
|
471
|
+
*/
|
|
472
|
+
declare function wrapFetch(fetchImpl: typeof globalThis.fetch, options: WrapFetchOptions): typeof globalThis.fetch;
|
|
473
|
+
|
|
239
474
|
/**
|
|
240
475
|
* Budget Account — Autonomous Agent Spending Controls
|
|
241
476
|
*
|
|
@@ -321,169 +556,4 @@ interface BudgetAccount {
|
|
|
321
556
|
*/
|
|
322
557
|
declare function createBudgetAccount(config: BudgetAccountConfig): BudgetAccount;
|
|
323
558
|
|
|
324
|
-
/**
|
|
325
|
-
* Shared contract for the x402 version seam. Both the v1 and v2 strategy
|
|
326
|
-
* modules implement PaymentStrategy. Callers depend ONLY on this file —
|
|
327
|
-
* never on a specific version module.
|
|
328
|
-
*/
|
|
329
|
-
|
|
330
|
-
/** A network reference, kept in BOTH forms so neither version loses info. */
|
|
331
|
-
interface NetworkRef {
|
|
332
|
-
/** CAIP-2 form, e.g. "eip155:8453", "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp". */
|
|
333
|
-
caip2: string;
|
|
334
|
-
/** Bare form, e.g. "base", "solana". */
|
|
335
|
-
bare: string;
|
|
336
|
-
/** "evm" | "svm" — which signer family. */
|
|
337
|
-
family: 'evm' | 'svm';
|
|
338
|
-
}
|
|
339
|
-
/** One payment option parsed from a 402 challenge, version-normalised. */
|
|
340
|
-
interface ChallengeOption {
|
|
341
|
-
scheme: string;
|
|
342
|
-
network: NetworkRef;
|
|
343
|
-
/** Atomic amount as a string (e.g. "2000"). */
|
|
344
|
-
amount: string;
|
|
345
|
-
asset: string;
|
|
346
|
-
payTo: string;
|
|
347
|
-
/** Optional — v1 challenges may omit it; a strategy supplies a default when absent. */
|
|
348
|
-
maxTimeoutSeconds?: number;
|
|
349
|
-
/** Scheme-specific extras, passed through verbatim from the merchant. */
|
|
350
|
-
extra?: Record<string, unknown>;
|
|
351
|
-
}
|
|
352
|
-
/** A 402 challenge, normalised across v1 and v2. */
|
|
353
|
-
interface PaymentChallenge {
|
|
354
|
-
x402Version: 1 | 2;
|
|
355
|
-
options: ChallengeOption[];
|
|
356
|
-
resourceUrl?: string;
|
|
357
|
-
}
|
|
358
|
-
/** Result of a paid fetch. Never throws for an expected failure. */
|
|
359
|
-
type PayResult = {
|
|
360
|
-
ok: true;
|
|
361
|
-
response: Response;
|
|
362
|
-
/** Atomic amount actually paid. */
|
|
363
|
-
amountPaid: string;
|
|
364
|
-
network: NetworkRef;
|
|
365
|
-
txSignature?: string;
|
|
366
|
-
} | {
|
|
367
|
-
ok: false;
|
|
368
|
-
reason: 'unsupported_network' | 'insufficient_funds'
|
|
369
|
-
/** The merchant rejected the payment itself — bad/declined payload,
|
|
370
|
-
* failed verification. Our side: check the payment. */
|
|
371
|
-
| 'merchant_rejected'
|
|
372
|
-
/** The merchant ACCEPTED the payment shape but their own settlement
|
|
373
|
-
* failed (their facilitator errored). Not our payload — a
|
|
374
|
-
* merchant-side defect. `detail` carries their verbatim error. */
|
|
375
|
-
| 'settlement_failed' | 'no_payment_options' | 'timeout' | 'budget_exceeded' | 'error';
|
|
376
|
-
detail?: string;
|
|
377
|
-
};
|
|
378
|
-
|
|
379
|
-
/** Options for a paid fetch. */
|
|
380
|
-
interface PayAndFetchOptions {
|
|
381
|
-
/** Max total atomic spend for this call. */
|
|
382
|
-
maxAmountAtomic?: string;
|
|
383
|
-
/** Per-request timeout in ms. Default 15000. */
|
|
384
|
-
timeoutMs?: number;
|
|
385
|
-
/**
|
|
386
|
-
* Solana RPC endpoint for v1 SVM payment signing. v1 Solana `exact`
|
|
387
|
-
* signing builds a real transaction and needs RPC access (mint lookup,
|
|
388
|
-
* recent blockhash). Ignored for EVM-only flows. Defaults to the public
|
|
389
|
-
* Solana RPC when omitted — callers should pass their own for
|
|
390
|
-
* reliability.
|
|
391
|
-
*/
|
|
392
|
-
solanaRpcUrl?: string;
|
|
393
|
-
}
|
|
394
|
-
/**
|
|
395
|
-
* The contract each version module implements.
|
|
396
|
-
*
|
|
397
|
-
* parseChallenge: given a raw 402 Response, extract the challenge — or
|
|
398
|
-
* null if this strategy does not recognise it as its version.
|
|
399
|
-
* pay: given a parsed challenge, sign + send the paid request, return
|
|
400
|
-
* the merchant's response.
|
|
401
|
-
*/
|
|
402
|
-
interface PaymentStrategy {
|
|
403
|
-
readonly version: 1 | 2;
|
|
404
|
-
parseChallenge(res: Response): Promise<PaymentChallenge | null>;
|
|
405
|
-
pay(url: string, requestInit: RequestInit, challenge: PaymentChallenge, wallets: WalletSet, opts: PayAndFetchOptions): Promise<PayResult>;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
/**
|
|
409
|
-
* The x402 version dispatcher — the ONLY code in the stack that decides
|
|
410
|
-
* v1 vs v2. It probes the endpoint once; if the response is a 402, it
|
|
411
|
-
* asks each strategy to parse it (v2 first, since v2 is current) and
|
|
412
|
-
* routes to whichever recognises it. Callers use payAndFetch and never
|
|
413
|
-
* branch on protocol version themselves.
|
|
414
|
-
*/
|
|
415
|
-
|
|
416
|
-
/**
|
|
417
|
-
* Given a 402 Response, return the strategy that recognises it, or null.
|
|
418
|
-
* Exported for testing; payAndFetch is the normal entrypoint.
|
|
419
|
-
*/
|
|
420
|
-
declare function detectStrategy(res: Response): Promise<PaymentStrategy | null>;
|
|
421
|
-
/**
|
|
422
|
-
* Pay for and fetch a resource. Probes once; if the endpoint demands
|
|
423
|
-
* payment, detects the protocol version, and pays via the matching
|
|
424
|
-
* strategy. Returns a typed PayResult — never throws for an expected
|
|
425
|
-
* failure.
|
|
426
|
-
*/
|
|
427
|
-
declare function payAndFetch(url: string, requestInit: RequestInit, wallets: WalletSet, opts: PayAndFetchOptions): Promise<PayResult>;
|
|
428
|
-
|
|
429
|
-
/**
|
|
430
|
-
* Two-way map between CAIP-2 network identifiers (x402 v2) and bare
|
|
431
|
-
* network names (x402 v1). The verifier's old bug was a one-way, lossy
|
|
432
|
-
* rewrite to bare names. This map is lossless: a NetworkRef always
|
|
433
|
-
* carries BOTH forms, so a v1 signer can use the bare name internally
|
|
434
|
-
* while the wire payload keeps whatever the merchant advertised.
|
|
435
|
-
*/
|
|
436
|
-
|
|
437
|
-
/**
|
|
438
|
-
* Resolve a network string — CAIP-2 or bare — to a NetworkRef.
|
|
439
|
-
* Only networks in the canonical ENTRIES table resolve. An
|
|
440
|
-
* unrecognised network (including an unmapped eip155:* / solana:*
|
|
441
|
-
* chain) returns null — callers must not receive a half-resolved,
|
|
442
|
-
* misleading NetworkRef.
|
|
443
|
-
*/
|
|
444
|
-
declare function toNetworkRef(network: string): NetworkRef | null;
|
|
445
|
-
|
|
446
|
-
/**
|
|
447
|
-
* Map a WalletSet to a SIWxSigner for wrapFetchWithSIWx, or null when
|
|
448
|
-
* neither wallet can sign SIW-X proofs.
|
|
449
|
-
*/
|
|
450
|
-
declare function toSiwxSigner(wallets: WalletSet): SIWxSigner | null;
|
|
451
|
-
|
|
452
|
-
/**
|
|
453
|
-
* Standalone v1 X-PAYMENT header builder.
|
|
454
|
-
*
|
|
455
|
-
* Extracted from v1-strategy so that external consumers that manage their
|
|
456
|
-
* own fetch (e.g. a dexter-api payment route) can build a v1 header without
|
|
457
|
-
* pulling in the full PaymentStrategy machinery or the upstream `x402` lib.
|
|
458
|
-
*
|
|
459
|
-
* MUST NOT import v2-strategy or v1-strategy (seam isolation).
|
|
460
|
-
*/
|
|
461
|
-
|
|
462
|
-
/** Result of building a v1 X-PAYMENT header value. Never thrown. */
|
|
463
|
-
type V1HeaderResult = {
|
|
464
|
-
ok: true;
|
|
465
|
-
headerValue: string;
|
|
466
|
-
option: ChallengeOption;
|
|
467
|
-
} | {
|
|
468
|
-
ok: false;
|
|
469
|
-
reason: 'unsupported_network' | 'budget_exceeded' | 'merchant_rejected' | 'error';
|
|
470
|
-
detail?: string;
|
|
471
|
-
};
|
|
472
|
-
/**
|
|
473
|
-
* Build a v1 `X-PAYMENT` header value for one of a challenge's options.
|
|
474
|
-
*
|
|
475
|
-
* This is the v1 payment-construction seam: it picks the first option
|
|
476
|
-
* whose chain family has a usable wallet, signs the v1 `exact` payload
|
|
477
|
-
* (EIP-3009 for EVM; a partially-signed Solana transaction for SVM),
|
|
478
|
-
* and base64-encodes the v1 PaymentPayload. It does NOT send a request —
|
|
479
|
-
* the caller owns the fetch. payAndFetch's v1 strategy uses this; so do
|
|
480
|
-
* external consumers that manage their own request flow.
|
|
481
|
-
*
|
|
482
|
-
* Returns a typed result; never throws for an expected failure.
|
|
483
|
-
*
|
|
484
|
-
* NO NETWORK REWRITE: the `network` field on the wire is the merchant's
|
|
485
|
-
* advertised v1 bare name verbatim (option.network.bare).
|
|
486
|
-
*/
|
|
487
|
-
declare function buildV1PaymentHeader(challenge: PaymentChallenge, wallets: WalletSet, opts: PayAndFetchOptions): Promise<V1HeaderResult>;
|
|
488
|
-
|
|
489
559
|
export { AccessPassClientConfig, type BudgetAccount, type BudgetAccountConfig, type BudgetConfig, type ChallengeOption, KEYPAIR_SYMBOL, type KeypairWallet, type NetworkRef, type PayAndFetchOptions, type PayResult, type PaymentChallenge, type PaymentRecord, type PaymentStrategy, type V1HeaderResult, WalletSet, type WrapFetchOptions, buildV1PaymentHeader, createBudgetAccount, createEvmKeypairWallet, createKeypairWallet, detectStrategy, isEvmKeypairWallet, isKeypairWallet, payAndFetch, toNetworkRef, toSiwxSigner, wrapFetch };
|