@t2000/sui-x402 10.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +28 -0
- package/dist/index.cjs +347 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +234 -0
- package/dist/index.d.ts +234 -0
- package/dist/index.js +324 -0
- package/dist/index.js.map +1 -0
- package/package.json +55 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { ClientWithCoreApi } from '@mysten/sui/client';
|
|
2
|
+
import { Signer } from '@mysten/sui/cryptography';
|
|
3
|
+
|
|
4
|
+
interface Currency {
|
|
5
|
+
type: string;
|
|
6
|
+
decimals: number;
|
|
7
|
+
}
|
|
8
|
+
declare const SUI_USDC_TYPE = "0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC";
|
|
9
|
+
declare const SUI_USDC_TESTNET_TYPE = "0xa1ec7fc00a6f40db9693ad1415d0c193ad3906494428cf252621037bd7117e29::usdc::USDC";
|
|
10
|
+
declare const USDC: {
|
|
11
|
+
readonly type: "0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC";
|
|
12
|
+
readonly decimals: 6;
|
|
13
|
+
};
|
|
14
|
+
declare const USDC_TESTNET: {
|
|
15
|
+
readonly type: "0xa1ec7fc00a6f40db9693ad1415d0c193ad3906494428cf252621037bd7117e29::usdc::USDC";
|
|
16
|
+
readonly decimals: 6;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
interface DigestStore {
|
|
20
|
+
has(digest: string): Promise<boolean>;
|
|
21
|
+
set(digest: string): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
/** What a successful settlement reports to the host (ops / activity hooks). */
|
|
24
|
+
interface PaymentReport {
|
|
25
|
+
digest: string;
|
|
26
|
+
sender?: string;
|
|
27
|
+
recipient: string;
|
|
28
|
+
amount: string;
|
|
29
|
+
currency: string;
|
|
30
|
+
network: string;
|
|
31
|
+
}
|
|
32
|
+
/** Dev/test store — per-process, TTL-evicted. Production sellers supply a
|
|
33
|
+
* durable DigestStore (Redis, Postgres); replay windows must survive
|
|
34
|
+
* restarts. */
|
|
35
|
+
declare class InMemoryDigestStore implements DigestStore {
|
|
36
|
+
private store;
|
|
37
|
+
private readonly ttlMs;
|
|
38
|
+
constructor(ttlMs?: number);
|
|
39
|
+
has(digest: string): Promise<boolean>;
|
|
40
|
+
set(digest: string): Promise<void>;
|
|
41
|
+
private evict;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Parse a string amount to raw bigint units without floating-point math.
|
|
46
|
+
* "0.01" with 6 decimals → 10000n
|
|
47
|
+
*/
|
|
48
|
+
declare function parseAmountToRaw(amount: string, decimals: number): bigint;
|
|
49
|
+
/**
|
|
50
|
+
* Retry an async function with linear backoff.
|
|
51
|
+
* Throws the last error if all attempts fail.
|
|
52
|
+
*/
|
|
53
|
+
declare function withRetry<T>(fn: () => Promise<T>, { attempts, baseDelayMs, }?: {
|
|
54
|
+
attempts?: number;
|
|
55
|
+
baseDelayMs?: number;
|
|
56
|
+
}): Promise<T>;
|
|
57
|
+
|
|
58
|
+
declare const X402_SCHEME: "exact";
|
|
59
|
+
declare const X402_VERSION: 1;
|
|
60
|
+
/** Request header carrying the signed payment (x402 standard). */
|
|
61
|
+
declare const X402_PAYMENT_HEADER = "X-PAYMENT";
|
|
62
|
+
/** Response header carrying the settlement result (x402 standard). */
|
|
63
|
+
declare const X402_PAYMENT_RESPONSE_HEADER = "X-PAYMENT-RESPONSE";
|
|
64
|
+
type X402Network = `sui:${'mainnet' | 'testnet' | 'devnet' | 'localnet'}`;
|
|
65
|
+
interface X402Requirements {
|
|
66
|
+
scheme: typeof X402_SCHEME;
|
|
67
|
+
network: X402Network;
|
|
68
|
+
/** Full Sui coin type of the payment asset. */
|
|
69
|
+
asset: string;
|
|
70
|
+
/** Atomic units (e.g. USDC 6dp) as a decimal string. */
|
|
71
|
+
maxAmountRequired: string;
|
|
72
|
+
payTo: string;
|
|
73
|
+
resource: string;
|
|
74
|
+
maxTimeoutSeconds: number;
|
|
75
|
+
extra: {
|
|
76
|
+
suimpp: {
|
|
77
|
+
/** The mppx challenge id this payment must bind to (single-use). */
|
|
78
|
+
challengeId: string;
|
|
79
|
+
/** u32 derived from challengeId — goes into ValidDuring.nonce. */
|
|
80
|
+
nonce: number;
|
|
81
|
+
/** Chain identifier string for ValidDuring (genesis digest). */
|
|
82
|
+
chain: string;
|
|
83
|
+
minEpoch: string;
|
|
84
|
+
maxEpoch: string;
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
interface X402EscrowTerms {
|
|
89
|
+
/** Time the seller commits to deliver within, in ms from job creation. */
|
|
90
|
+
deliverWithinMs: number;
|
|
91
|
+
/** Buyer's accept/reject window after delivery, in ms. Lapse = release. */
|
|
92
|
+
reviewWindowMs: number;
|
|
93
|
+
/** Buyer's share in basis points if they reject (0–10000). Fixed at job
|
|
94
|
+
* creation — neither side can move the goalposts later. */
|
|
95
|
+
rejectSplitBps: number;
|
|
96
|
+
/** The escrow Move package the seller verifies jobs against
|
|
97
|
+
* (`a2a_escrow::escrow` on the advertised network). */
|
|
98
|
+
packageId?: string;
|
|
99
|
+
/** Optional pointer (URL or short note) describing the expected job-spec
|
|
100
|
+
* format the buyer should hash into the job's `spec_hash`. */
|
|
101
|
+
specSchema?: string;
|
|
102
|
+
}
|
|
103
|
+
/** A job-class `accepts[]` entry. Same base fields as the instant entry
|
|
104
|
+
* (`maxAmountRequired` = the job price) but NO settlement challenge —
|
|
105
|
+
* `extra.escrow` replaces `extra.suimpp`. */
|
|
106
|
+
interface X402EscrowRequirements {
|
|
107
|
+
scheme: typeof X402_SCHEME;
|
|
108
|
+
network: X402Network;
|
|
109
|
+
asset: string;
|
|
110
|
+
/** The job price in atomic units (decimal string). */
|
|
111
|
+
maxAmountRequired: string;
|
|
112
|
+
/** The seller wallet the Job must pay (and the claimed Agent ID wallet). */
|
|
113
|
+
payTo: string;
|
|
114
|
+
resource: string;
|
|
115
|
+
maxTimeoutSeconds: number;
|
|
116
|
+
extra: {
|
|
117
|
+
escrow: X402EscrowTerms;
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/** Discriminate a job-class entry inside a mixed accepts[] array. */
|
|
121
|
+
declare function isX402EscrowRequirements(entry: unknown): entry is X402EscrowRequirements;
|
|
122
|
+
/** Discriminate escrow vs instant X-PAYMENT credentials without throwing —
|
|
123
|
+
* sellers serving both classes route on this before parsing. */
|
|
124
|
+
declare function isX402EscrowHeader(headerValue: string): boolean;
|
|
125
|
+
interface X402PaymentPayload {
|
|
126
|
+
x402Version: typeof X402_VERSION;
|
|
127
|
+
scheme: typeof X402_SCHEME;
|
|
128
|
+
network: X402Network;
|
|
129
|
+
payload: {
|
|
130
|
+
senderAddress: string;
|
|
131
|
+
/** base64 BCS TransactionData — fully signed-ready bytes. */
|
|
132
|
+
txBytes: string;
|
|
133
|
+
/** Sender signature over txBytes (Ed25519 / secp / zkLogin). */
|
|
134
|
+
senderSignature: string;
|
|
135
|
+
challengeId: string;
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
interface X402SettleResponse {
|
|
139
|
+
success: boolean;
|
|
140
|
+
network: X402Network;
|
|
141
|
+
/** Settled transaction digest. */
|
|
142
|
+
transaction: string;
|
|
143
|
+
payer: string;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Derive the ValidDuring nonce (u32) from a challenge id. FNV-1a 32-bit —
|
|
147
|
+
* dependency-free and browser-safe. The nonce provides per-challenge
|
|
148
|
+
* UNIQUENESS (distinct digests for otherwise-identical payments); it is not
|
|
149
|
+
* a secret and carries no security on its own.
|
|
150
|
+
*/
|
|
151
|
+
declare function challengeNonce(challengeId: string): number;
|
|
152
|
+
declare function x402Network(network: 'mainnet' | 'testnet' | 'devnet' | 'localnet'): X402Network;
|
|
153
|
+
interface CreateRequirementsOptions {
|
|
154
|
+
challengeId: string;
|
|
155
|
+
/** Human-units amount string from the challenge (e.g. "0.02"). */
|
|
156
|
+
amount: string;
|
|
157
|
+
currency: Currency;
|
|
158
|
+
recipient: string;
|
|
159
|
+
resource: string;
|
|
160
|
+
network: 'mainnet' | 'testnet' | 'devnet' | 'localnet';
|
|
161
|
+
/** Chain identifier string (genesis digest) for ValidDuring. */
|
|
162
|
+
chain: string;
|
|
163
|
+
/** Current epoch — requirements are valid for [epoch, epoch + 1]. */
|
|
164
|
+
currentEpoch: bigint | number | string;
|
|
165
|
+
maxTimeoutSeconds?: number;
|
|
166
|
+
}
|
|
167
|
+
declare function createX402Requirements(options: CreateRequirementsOptions): X402Requirements;
|
|
168
|
+
interface BuildSignedPaymentOptions {
|
|
169
|
+
requirements: X402Requirements;
|
|
170
|
+
signer: Signer;
|
|
171
|
+
/**
|
|
172
|
+
* Optional client for build-time resolution. The canonical stateless
|
|
173
|
+
* shape (address-balance withdrawal → redeem_funds → send_funds) has no
|
|
174
|
+
* object inputs, so the build is offline when omitted.
|
|
175
|
+
*/
|
|
176
|
+
client?: ClientWithCoreApi;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Build the canonical stateless payment transaction, sign it, and return the
|
|
180
|
+
* `X-PAYMENT` header value + parsed payload. Never submits — settlement is
|
|
181
|
+
* the server's job (`settleX402Payment`).
|
|
182
|
+
*/
|
|
183
|
+
declare function buildX402SignedPayment(options: BuildSignedPaymentOptions): Promise<{
|
|
184
|
+
header: string;
|
|
185
|
+
payment: X402PaymentPayload;
|
|
186
|
+
}>;
|
|
187
|
+
declare function encodeX402Header(payment: X402PaymentPayload): string;
|
|
188
|
+
declare function parseX402Header(headerValue: string): X402PaymentPayload;
|
|
189
|
+
interface VerifyX402Options {
|
|
190
|
+
payment: X402PaymentPayload;
|
|
191
|
+
/** The terms this payment must match (from the original challenge). */
|
|
192
|
+
expected: {
|
|
193
|
+
challengeId: string;
|
|
194
|
+
amount: string;
|
|
195
|
+
currency: Currency;
|
|
196
|
+
recipient: string;
|
|
197
|
+
network: 'mainnet' | 'testnet' | 'devnet' | 'localnet';
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Structural pre-settle verification: the signed bytes must be the canonical
|
|
202
|
+
* gasless payment for OUR terms before we relay them. Catches wrong-terms /
|
|
203
|
+
* relay-abuse payloads without an RPC call.
|
|
204
|
+
*
|
|
205
|
+
* SCOPE (Phase 1): this is a STRUCTURAL check — it does NOT verify
|
|
206
|
+
* `senderSignature`. Signature authority is the chain at `settleX402Payment`
|
|
207
|
+
* (a bad signature fails `executeTransaction`, and under settle-then-serve
|
|
208
|
+
* the upstream is never called), plus the post-settle balance-change check.
|
|
209
|
+
* A standalone Phase-3 public `/verify` endpoint adds an explicit async
|
|
210
|
+
* signature check (needs a client for zkLogin) on top of this.
|
|
211
|
+
*/
|
|
212
|
+
declare function verifyX402Payment(options: VerifyX402Options): {
|
|
213
|
+
txBytes: Uint8Array;
|
|
214
|
+
nonce: number;
|
|
215
|
+
};
|
|
216
|
+
interface SettleX402Options {
|
|
217
|
+
payment: X402PaymentPayload;
|
|
218
|
+
client: ClientWithCoreApi;
|
|
219
|
+
/** Digest replay store — shared with the legacy dialect. */
|
|
220
|
+
store: DigestStore;
|
|
221
|
+
expected: VerifyX402Options['expected'];
|
|
222
|
+
onPayment?: (report: PaymentReport) => void;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Settle-then-serve: verify structurally, submit the client-signed bytes,
|
|
226
|
+
* confirm the on-chain balance change, record the digest. Throws (and the
|
|
227
|
+
* host returns 402) without serving if anything fails — and because the
|
|
228
|
+
* host only calls the upstream AFTER this resolves, a failed upstream can
|
|
229
|
+
* void/refund before any service value is lost.
|
|
230
|
+
*/
|
|
231
|
+
declare function settleX402Payment(options: SettleX402Options): Promise<X402SettleResponse>;
|
|
232
|
+
declare function encodeX402Response(response: X402SettleResponse): string;
|
|
233
|
+
|
|
234
|
+
export { type BuildSignedPaymentOptions, type CreateRequirementsOptions, type Currency, type DigestStore, InMemoryDigestStore, type PaymentReport, SUI_USDC_TESTNET_TYPE, SUI_USDC_TYPE, type SettleX402Options, USDC, USDC_TESTNET, type VerifyX402Options, type X402EscrowRequirements, type X402EscrowTerms, type X402Network, type X402PaymentPayload, type X402Requirements, type X402SettleResponse, X402_PAYMENT_HEADER, X402_PAYMENT_RESPONSE_HEADER, X402_SCHEME, X402_VERSION, buildX402SignedPayment, challengeNonce, createX402Requirements, encodeX402Header, encodeX402Response, isX402EscrowHeader, isX402EscrowRequirements, parseAmountToRaw, parseX402Header, settleX402Payment, verifyX402Payment, withRetry, x402Network };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { ClientWithCoreApi } from '@mysten/sui/client';
|
|
2
|
+
import { Signer } from '@mysten/sui/cryptography';
|
|
3
|
+
|
|
4
|
+
interface Currency {
|
|
5
|
+
type: string;
|
|
6
|
+
decimals: number;
|
|
7
|
+
}
|
|
8
|
+
declare const SUI_USDC_TYPE = "0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC";
|
|
9
|
+
declare const SUI_USDC_TESTNET_TYPE = "0xa1ec7fc00a6f40db9693ad1415d0c193ad3906494428cf252621037bd7117e29::usdc::USDC";
|
|
10
|
+
declare const USDC: {
|
|
11
|
+
readonly type: "0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC";
|
|
12
|
+
readonly decimals: 6;
|
|
13
|
+
};
|
|
14
|
+
declare const USDC_TESTNET: {
|
|
15
|
+
readonly type: "0xa1ec7fc00a6f40db9693ad1415d0c193ad3906494428cf252621037bd7117e29::usdc::USDC";
|
|
16
|
+
readonly decimals: 6;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
interface DigestStore {
|
|
20
|
+
has(digest: string): Promise<boolean>;
|
|
21
|
+
set(digest: string): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
/** What a successful settlement reports to the host (ops / activity hooks). */
|
|
24
|
+
interface PaymentReport {
|
|
25
|
+
digest: string;
|
|
26
|
+
sender?: string;
|
|
27
|
+
recipient: string;
|
|
28
|
+
amount: string;
|
|
29
|
+
currency: string;
|
|
30
|
+
network: string;
|
|
31
|
+
}
|
|
32
|
+
/** Dev/test store — per-process, TTL-evicted. Production sellers supply a
|
|
33
|
+
* durable DigestStore (Redis, Postgres); replay windows must survive
|
|
34
|
+
* restarts. */
|
|
35
|
+
declare class InMemoryDigestStore implements DigestStore {
|
|
36
|
+
private store;
|
|
37
|
+
private readonly ttlMs;
|
|
38
|
+
constructor(ttlMs?: number);
|
|
39
|
+
has(digest: string): Promise<boolean>;
|
|
40
|
+
set(digest: string): Promise<void>;
|
|
41
|
+
private evict;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Parse a string amount to raw bigint units without floating-point math.
|
|
46
|
+
* "0.01" with 6 decimals → 10000n
|
|
47
|
+
*/
|
|
48
|
+
declare function parseAmountToRaw(amount: string, decimals: number): bigint;
|
|
49
|
+
/**
|
|
50
|
+
* Retry an async function with linear backoff.
|
|
51
|
+
* Throws the last error if all attempts fail.
|
|
52
|
+
*/
|
|
53
|
+
declare function withRetry<T>(fn: () => Promise<T>, { attempts, baseDelayMs, }?: {
|
|
54
|
+
attempts?: number;
|
|
55
|
+
baseDelayMs?: number;
|
|
56
|
+
}): Promise<T>;
|
|
57
|
+
|
|
58
|
+
declare const X402_SCHEME: "exact";
|
|
59
|
+
declare const X402_VERSION: 1;
|
|
60
|
+
/** Request header carrying the signed payment (x402 standard). */
|
|
61
|
+
declare const X402_PAYMENT_HEADER = "X-PAYMENT";
|
|
62
|
+
/** Response header carrying the settlement result (x402 standard). */
|
|
63
|
+
declare const X402_PAYMENT_RESPONSE_HEADER = "X-PAYMENT-RESPONSE";
|
|
64
|
+
type X402Network = `sui:${'mainnet' | 'testnet' | 'devnet' | 'localnet'}`;
|
|
65
|
+
interface X402Requirements {
|
|
66
|
+
scheme: typeof X402_SCHEME;
|
|
67
|
+
network: X402Network;
|
|
68
|
+
/** Full Sui coin type of the payment asset. */
|
|
69
|
+
asset: string;
|
|
70
|
+
/** Atomic units (e.g. USDC 6dp) as a decimal string. */
|
|
71
|
+
maxAmountRequired: string;
|
|
72
|
+
payTo: string;
|
|
73
|
+
resource: string;
|
|
74
|
+
maxTimeoutSeconds: number;
|
|
75
|
+
extra: {
|
|
76
|
+
suimpp: {
|
|
77
|
+
/** The mppx challenge id this payment must bind to (single-use). */
|
|
78
|
+
challengeId: string;
|
|
79
|
+
/** u32 derived from challengeId — goes into ValidDuring.nonce. */
|
|
80
|
+
nonce: number;
|
|
81
|
+
/** Chain identifier string for ValidDuring (genesis digest). */
|
|
82
|
+
chain: string;
|
|
83
|
+
minEpoch: string;
|
|
84
|
+
maxEpoch: string;
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
interface X402EscrowTerms {
|
|
89
|
+
/** Time the seller commits to deliver within, in ms from job creation. */
|
|
90
|
+
deliverWithinMs: number;
|
|
91
|
+
/** Buyer's accept/reject window after delivery, in ms. Lapse = release. */
|
|
92
|
+
reviewWindowMs: number;
|
|
93
|
+
/** Buyer's share in basis points if they reject (0–10000). Fixed at job
|
|
94
|
+
* creation — neither side can move the goalposts later. */
|
|
95
|
+
rejectSplitBps: number;
|
|
96
|
+
/** The escrow Move package the seller verifies jobs against
|
|
97
|
+
* (`a2a_escrow::escrow` on the advertised network). */
|
|
98
|
+
packageId?: string;
|
|
99
|
+
/** Optional pointer (URL or short note) describing the expected job-spec
|
|
100
|
+
* format the buyer should hash into the job's `spec_hash`. */
|
|
101
|
+
specSchema?: string;
|
|
102
|
+
}
|
|
103
|
+
/** A job-class `accepts[]` entry. Same base fields as the instant entry
|
|
104
|
+
* (`maxAmountRequired` = the job price) but NO settlement challenge —
|
|
105
|
+
* `extra.escrow` replaces `extra.suimpp`. */
|
|
106
|
+
interface X402EscrowRequirements {
|
|
107
|
+
scheme: typeof X402_SCHEME;
|
|
108
|
+
network: X402Network;
|
|
109
|
+
asset: string;
|
|
110
|
+
/** The job price in atomic units (decimal string). */
|
|
111
|
+
maxAmountRequired: string;
|
|
112
|
+
/** The seller wallet the Job must pay (and the claimed Agent ID wallet). */
|
|
113
|
+
payTo: string;
|
|
114
|
+
resource: string;
|
|
115
|
+
maxTimeoutSeconds: number;
|
|
116
|
+
extra: {
|
|
117
|
+
escrow: X402EscrowTerms;
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/** Discriminate a job-class entry inside a mixed accepts[] array. */
|
|
121
|
+
declare function isX402EscrowRequirements(entry: unknown): entry is X402EscrowRequirements;
|
|
122
|
+
/** Discriminate escrow vs instant X-PAYMENT credentials without throwing —
|
|
123
|
+
* sellers serving both classes route on this before parsing. */
|
|
124
|
+
declare function isX402EscrowHeader(headerValue: string): boolean;
|
|
125
|
+
interface X402PaymentPayload {
|
|
126
|
+
x402Version: typeof X402_VERSION;
|
|
127
|
+
scheme: typeof X402_SCHEME;
|
|
128
|
+
network: X402Network;
|
|
129
|
+
payload: {
|
|
130
|
+
senderAddress: string;
|
|
131
|
+
/** base64 BCS TransactionData — fully signed-ready bytes. */
|
|
132
|
+
txBytes: string;
|
|
133
|
+
/** Sender signature over txBytes (Ed25519 / secp / zkLogin). */
|
|
134
|
+
senderSignature: string;
|
|
135
|
+
challengeId: string;
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
interface X402SettleResponse {
|
|
139
|
+
success: boolean;
|
|
140
|
+
network: X402Network;
|
|
141
|
+
/** Settled transaction digest. */
|
|
142
|
+
transaction: string;
|
|
143
|
+
payer: string;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Derive the ValidDuring nonce (u32) from a challenge id. FNV-1a 32-bit —
|
|
147
|
+
* dependency-free and browser-safe. The nonce provides per-challenge
|
|
148
|
+
* UNIQUENESS (distinct digests for otherwise-identical payments); it is not
|
|
149
|
+
* a secret and carries no security on its own.
|
|
150
|
+
*/
|
|
151
|
+
declare function challengeNonce(challengeId: string): number;
|
|
152
|
+
declare function x402Network(network: 'mainnet' | 'testnet' | 'devnet' | 'localnet'): X402Network;
|
|
153
|
+
interface CreateRequirementsOptions {
|
|
154
|
+
challengeId: string;
|
|
155
|
+
/** Human-units amount string from the challenge (e.g. "0.02"). */
|
|
156
|
+
amount: string;
|
|
157
|
+
currency: Currency;
|
|
158
|
+
recipient: string;
|
|
159
|
+
resource: string;
|
|
160
|
+
network: 'mainnet' | 'testnet' | 'devnet' | 'localnet';
|
|
161
|
+
/** Chain identifier string (genesis digest) for ValidDuring. */
|
|
162
|
+
chain: string;
|
|
163
|
+
/** Current epoch — requirements are valid for [epoch, epoch + 1]. */
|
|
164
|
+
currentEpoch: bigint | number | string;
|
|
165
|
+
maxTimeoutSeconds?: number;
|
|
166
|
+
}
|
|
167
|
+
declare function createX402Requirements(options: CreateRequirementsOptions): X402Requirements;
|
|
168
|
+
interface BuildSignedPaymentOptions {
|
|
169
|
+
requirements: X402Requirements;
|
|
170
|
+
signer: Signer;
|
|
171
|
+
/**
|
|
172
|
+
* Optional client for build-time resolution. The canonical stateless
|
|
173
|
+
* shape (address-balance withdrawal → redeem_funds → send_funds) has no
|
|
174
|
+
* object inputs, so the build is offline when omitted.
|
|
175
|
+
*/
|
|
176
|
+
client?: ClientWithCoreApi;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Build the canonical stateless payment transaction, sign it, and return the
|
|
180
|
+
* `X-PAYMENT` header value + parsed payload. Never submits — settlement is
|
|
181
|
+
* the server's job (`settleX402Payment`).
|
|
182
|
+
*/
|
|
183
|
+
declare function buildX402SignedPayment(options: BuildSignedPaymentOptions): Promise<{
|
|
184
|
+
header: string;
|
|
185
|
+
payment: X402PaymentPayload;
|
|
186
|
+
}>;
|
|
187
|
+
declare function encodeX402Header(payment: X402PaymentPayload): string;
|
|
188
|
+
declare function parseX402Header(headerValue: string): X402PaymentPayload;
|
|
189
|
+
interface VerifyX402Options {
|
|
190
|
+
payment: X402PaymentPayload;
|
|
191
|
+
/** The terms this payment must match (from the original challenge). */
|
|
192
|
+
expected: {
|
|
193
|
+
challengeId: string;
|
|
194
|
+
amount: string;
|
|
195
|
+
currency: Currency;
|
|
196
|
+
recipient: string;
|
|
197
|
+
network: 'mainnet' | 'testnet' | 'devnet' | 'localnet';
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Structural pre-settle verification: the signed bytes must be the canonical
|
|
202
|
+
* gasless payment for OUR terms before we relay them. Catches wrong-terms /
|
|
203
|
+
* relay-abuse payloads without an RPC call.
|
|
204
|
+
*
|
|
205
|
+
* SCOPE (Phase 1): this is a STRUCTURAL check — it does NOT verify
|
|
206
|
+
* `senderSignature`. Signature authority is the chain at `settleX402Payment`
|
|
207
|
+
* (a bad signature fails `executeTransaction`, and under settle-then-serve
|
|
208
|
+
* the upstream is never called), plus the post-settle balance-change check.
|
|
209
|
+
* A standalone Phase-3 public `/verify` endpoint adds an explicit async
|
|
210
|
+
* signature check (needs a client for zkLogin) on top of this.
|
|
211
|
+
*/
|
|
212
|
+
declare function verifyX402Payment(options: VerifyX402Options): {
|
|
213
|
+
txBytes: Uint8Array;
|
|
214
|
+
nonce: number;
|
|
215
|
+
};
|
|
216
|
+
interface SettleX402Options {
|
|
217
|
+
payment: X402PaymentPayload;
|
|
218
|
+
client: ClientWithCoreApi;
|
|
219
|
+
/** Digest replay store — shared with the legacy dialect. */
|
|
220
|
+
store: DigestStore;
|
|
221
|
+
expected: VerifyX402Options['expected'];
|
|
222
|
+
onPayment?: (report: PaymentReport) => void;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Settle-then-serve: verify structurally, submit the client-signed bytes,
|
|
226
|
+
* confirm the on-chain balance change, record the digest. Throws (and the
|
|
227
|
+
* host returns 402) without serving if anything fails — and because the
|
|
228
|
+
* host only calls the upstream AFTER this resolves, a failed upstream can
|
|
229
|
+
* void/refund before any service value is lost.
|
|
230
|
+
*/
|
|
231
|
+
declare function settleX402Payment(options: SettleX402Options): Promise<X402SettleResponse>;
|
|
232
|
+
declare function encodeX402Response(response: X402SettleResponse): string;
|
|
233
|
+
|
|
234
|
+
export { type BuildSignedPaymentOptions, type CreateRequirementsOptions, type Currency, type DigestStore, InMemoryDigestStore, type PaymentReport, SUI_USDC_TESTNET_TYPE, SUI_USDC_TYPE, type SettleX402Options, USDC, USDC_TESTNET, type VerifyX402Options, type X402EscrowRequirements, type X402EscrowTerms, type X402Network, type X402PaymentPayload, type X402Requirements, type X402SettleResponse, X402_PAYMENT_HEADER, X402_PAYMENT_RESPONSE_HEADER, X402_SCHEME, X402_VERSION, buildX402SignedPayment, challengeNonce, createX402Requirements, encodeX402Header, encodeX402Response, isX402EscrowHeader, isX402EscrowRequirements, parseAmountToRaw, parseX402Header, settleX402Payment, verifyX402Payment, withRetry, x402Network };
|