@secondlayer/sdk 6.19.0 → 6.21.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/dist/x402.d.ts ADDED
@@ -0,0 +1,159 @@
1
+ import { X402TokenSymbol } from "@secondlayer/shared/x402";
2
+ import { LocalAccount } from "@secondlayer/stacks/accounts";
3
+ import { StacksChain } from "@secondlayer/stacks/chains";
4
+ /**
5
+ * Client for the x402 pay-per-request rail. Turns a 402 challenge into a signed
6
+ * `PAYMENT-SIGNATURE` and retries — gasless (the agent signs origin-only; the
7
+ * facilitator sponsors the STX fee) and accountless (no key/Stripe/session).
8
+ *
9
+ * Three layers:
10
+ * - `withX402(fetch, opts)` — drop-in fetch that auto-pays on 402.
11
+ * - `createX402Client(opts)` — `.get/.post` returning `{ data, payment }`.
12
+ * - `buildSignedX402Payment` / `readX402Challenge` — primitives for custom transports.
13
+ */
14
+ type X402Accept = {
15
+ scheme: "exact"
16
+ network: string
17
+ asset: string
18
+ /** Atomic units. */
19
+ amount: string
20
+ payTo: string
21
+ maxTimeoutSeconds: number
22
+ extra: {
23
+ nonce: string
24
+ }
25
+ };
26
+ type X402Challenge = {
27
+ x402Version: number
28
+ accepts: X402Accept[]
29
+ error?: string
30
+ };
31
+ /** Decoded `PAYMENT-RESPONSE` settlement receipt. */
32
+ type X402Receipt = {
33
+ success: boolean
34
+ /** Settlement tier: `optimistic` (served on broadcast-accept, reconciled
35
+ * async) or `confirmed` (canonical). Absent on older deployments. */
36
+ state?: "optimistic" | "confirmed"
37
+ txid: string
38
+ payer: string
39
+ network: string
40
+ };
41
+ /** Bitcoin-native first — sBTC is the compelling micropay asset; USDCx the
42
+ * dollar peg; STX the fallback. Override via `preferAssets`. */
43
+ declare const DEFAULT_PREFER_ASSETS: X402TokenSymbol[];
44
+ /** Default node for auto-resolving the payer's account nonce (`/v2/accounts`). */
45
+ declare const DEFAULT_NONCE_NODE_URL = "https://api.hiro.so";
46
+ /** Thrown when no offered asset is within the caller's spend guard / preferences. */
47
+ declare class X402SpendGuardError extends Error {
48
+ constructor(message: string);
49
+ }
50
+ /** Read the x402 challenge from a 402 response — prefer the wire header, fall
51
+ * back to the JSON body. */
52
+ declare function readX402Challenge(res: Response): Promise<X402Challenge | null>;
53
+ /** Read the settlement receipt from a paid 200 response. */
54
+ declare function readX402Receipt(res: Response): X402Receipt | null;
55
+ type SelectOfferOptions = {
56
+ preferAssets?: X402TokenSymbol[]
57
+ maxAmountPerCall?: Partial<Record<X402TokenSymbol, bigint>>
58
+ };
59
+ /** Choose an `accepts[]` entry by preference order, skipping any that exceed the
60
+ * per-asset spend cap. Throws {@link X402SpendGuardError} if none qualify. */
61
+ declare function selectOffer(challenge: X402Challenge, opts?: SelectOfferOptions): {
62
+ accept: X402Accept
63
+ symbol: X402TokenSymbol
64
+ };
65
+ /** Fetch the payer account's next nonce from a Stacks node (`/v2/accounts`). */
66
+ declare function resolveAccountNonce(address: string, nodeUrl?: string): Promise<number>;
67
+ type BuildSignedX402PaymentOptions = {
68
+ challenge: X402Challenge
69
+ account: LocalAccount
70
+ /** The payer account's next nonce. */
71
+ accountNonce: bigint | number | string
72
+ /** Preferred asset string (e.g. an sBTC/USDCx id). Defaults to the first offer. */
73
+ asset?: string
74
+ chain?: StacksChain
75
+ };
76
+ /** Build a signed, base64 `PAYMENT-SIGNATURE` header for one `accepts[]` entry. */
77
+ declare function buildSignedX402Payment(opts: BuildSignedX402PaymentOptions): Promise<{
78
+ header: string
79
+ accept: X402Accept
80
+ }>;
81
+ type WithX402Options = SelectOfferOptions & {
82
+ account: LocalAccount
83
+ /** Prepaid-credit token (PAYMENT-BALANCE) from a prior deposit — calls
84
+ * debit the tab server-side instead of settling on-chain per call. */
85
+ balanceToken?: string
86
+ /** Autonomous treasury policy: when the tab's remaining balance (read from
87
+ * X-BALANCE-REMAINING-USD) drops below `whenBelow`, deposit `usd` more in
88
+ * the background (one on-chain payment) and adopt the fresh token. */
89
+ topUp?: {
90
+ usd: number
91
+ whenBelow: number
92
+ }
93
+ /** Override the payer nonce; auto-resolved from `nodeUrl` when omitted. */
94
+ accountNonce?: bigint | number | string
95
+ /** Node for auto-nonce lookup. Defaults to {@link DEFAULT_NONCE_NODE_URL}. */
96
+ nodeUrl?: string
97
+ chain?: StacksChain
98
+ /** Fired just before the paid retry (the call then blocks on confirmed-tier
99
+ * settle, or returns near-instantly on an optimistic surface). */
100
+ onSettling?: (info: {
101
+ asset: string
102
+ amount: string
103
+ }) => void
104
+ /** Abort the paid retry after this long. */
105
+ timeoutMs?: number
106
+ };
107
+ type X402Fetch = (input: string | URL, init?: RequestInit) => Promise<Response>;
108
+ /**
109
+ * Wrap a `fetch` so requests transparently pay on 402: select an offer (by
110
+ * `preferAssets` + `maxAmountPerCall`), resolve the nonce, sign origin-only, and
111
+ * retry once with `PAYMENT-SIGNATURE`. Returns the final `Response` (read the
112
+ * receipt with {@link readX402Receipt}).
113
+ *
114
+ * @example
115
+ * const x402fetch = withX402(fetch, { account });
116
+ * const res = await x402fetch("https://api.secondlayer.tools/v1/index/events?event_type=ft_transfer");
117
+ */
118
+ declare function withX402(baseFetch: typeof fetch, opts: WithX402Options): X402Fetch;
119
+ type X402ClientOptions = WithX402Options & {
120
+ baseUrl: string
121
+ /** Override the underlying fetch (tests). */
122
+ fetch?: typeof fetch
123
+ };
124
+ type X402Result<T = unknown> = {
125
+ data: T
126
+ /** Settlement receipt, or null if the response carried none. */
127
+ payment: X402Receipt | null
128
+ response: Response
129
+ };
130
+ type X402Client = {
131
+ get<T = unknown>(path: string, o?: {
132
+ query?: Record<string, string>
133
+ }): Promise<X402Result<T>>
134
+ post<T = unknown>(path: string, o?: {
135
+ body?: unknown
136
+ }): Promise<X402Result<T>>
137
+ };
138
+ /**
139
+ * A small client over {@link withX402}: `.get/.post` against `baseUrl`, returning
140
+ * parsed JSON plus the settlement receipt.
141
+ *
142
+ * @example
143
+ * const sl = createX402Client({ account, baseUrl: "https://api.secondlayer.tools" });
144
+ * const { data, payment } = await sl.get("/v1/index/events", { query: { event_type: "ft_transfer" } });
145
+ */
146
+ declare function createX402Client(opts: X402ClientOptions): X402Client;
147
+ /** Caller-supplied fetch that re-runs the request with the given extra headers. */
148
+ type X402FetchFn = (extraHeaders: Record<string, string>) => Promise<Response>;
149
+ type PayAndRetryOptions = Omit<WithX402Options, never> & {
150
+ /** Required here (use `withX402` for auto-nonce). */
151
+ accountNonce: bigint | number | string
152
+ };
153
+ /**
154
+ * Low-level: run a request via a caller-controlled fetch; if it 402s, pay and
155
+ * retry once. Prefer {@link withX402} for the common case (it auto-resolves the
156
+ * nonce + selects the asset). Kept for custom transports.
157
+ */
158
+ declare function payAndRetry(doFetch: X402FetchFn, opts: PayAndRetryOptions): Promise<Response>;
159
+ export { withX402, selectOffer, resolveAccountNonce, readX402Receipt, readX402Challenge, payAndRetry, createX402Client, buildSignedX402Payment, X402SpendGuardError, X402Result, X402Receipt, X402FetchFn, X402Fetch, X402ClientOptions, X402Client, X402Challenge, X402Accept, WithX402Options, SelectOfferOptions, PayAndRetryOptions, DEFAULT_PREFER_ASSETS, DEFAULT_NONCE_NODE_URL, BuildSignedX402PaymentOptions };
package/dist/x402.js ADDED
@@ -0,0 +1,230 @@
1
+ // src/x402.ts
2
+ import {
3
+ X402_TOKENS,
4
+ findX402TokenByAsset
5
+ } from "@secondlayer/shared/x402";
6
+ import {
7
+ serializeTransactionHex,
8
+ signTransactionWithAccount
9
+ } from "@secondlayer/stacks/transactions";
10
+ import { buildExactTransfer } from "@secondlayer/stacks/x402";
11
+ var DEFAULT_PREFER_ASSETS = [
12
+ "sBTC",
13
+ "USDCx",
14
+ "STX"
15
+ ];
16
+ var DEFAULT_NONCE_NODE_URL = "https://api.hiro.so";
17
+
18
+ class X402SpendGuardError extends Error {
19
+ constructor(message) {
20
+ super(message);
21
+ this.name = "X402SpendGuardError";
22
+ }
23
+ }
24
+ function b64encode(value) {
25
+ return Buffer.from(JSON.stringify(value), "utf8").toString("base64");
26
+ }
27
+ function b64decodeJson(value) {
28
+ try {
29
+ return JSON.parse(Buffer.from(value, "base64").toString("utf8"));
30
+ } catch {
31
+ return null;
32
+ }
33
+ }
34
+ async function readX402Challenge(res) {
35
+ const header = res.headers.get("PAYMENT-REQUIRED");
36
+ if (header) {
37
+ const decoded = b64decodeJson(header);
38
+ if (decoded)
39
+ return decoded;
40
+ }
41
+ try {
42
+ return await res.clone().json();
43
+ } catch {
44
+ return null;
45
+ }
46
+ }
47
+ function readX402Receipt(res) {
48
+ const header = res.headers.get("PAYMENT-RESPONSE");
49
+ return header ? b64decodeJson(header) : null;
50
+ }
51
+ function selectOffer(challenge, opts = {}) {
52
+ const prefer = opts.preferAssets ?? DEFAULT_PREFER_ASSETS;
53
+ for (const symbol of prefer) {
54
+ const token = X402_TOKENS[symbol];
55
+ const accept = challenge.accepts.find((a) => a.asset === token.asset);
56
+ if (!accept)
57
+ continue;
58
+ const cap = opts.maxAmountPerCall?.[symbol];
59
+ if (cap !== undefined && BigInt(accept.amount) > cap)
60
+ continue;
61
+ return { accept, symbol };
62
+ }
63
+ throw new X402SpendGuardError("no x402 offer matched preferAssets within maxAmountPerCall");
64
+ }
65
+ async function resolveAccountNonce(address, nodeUrl = DEFAULT_NONCE_NODE_URL) {
66
+ const res = await fetch(`${nodeUrl.replace(/\/$/, "")}/v2/accounts/${address}?proof=0`);
67
+ if (!res.ok)
68
+ throw new Error(`x402 nonce lookup failed: ${res.status}`);
69
+ const json = await res.json();
70
+ return json.nonce;
71
+ }
72
+ async function buildSignedX402Payment(opts) {
73
+ const accept = opts.asset ? opts.challenge.accepts.find((a) => a.asset === opts.asset) : opts.challenge.accepts[0];
74
+ if (!accept) {
75
+ throw new Error(`No x402 offer${opts.asset ? ` for asset ${opts.asset}` : ""}`);
76
+ }
77
+ const token = findX402TokenByAsset(accept.asset);
78
+ if (!token)
79
+ throw new Error(`Unknown x402 asset: ${accept.asset}`);
80
+ const asset = token.contractId && token.assetName ? {
81
+ kind: "sip010",
82
+ contractId: token.contractId,
83
+ assetName: token.assetName
84
+ } : { kind: "stx" };
85
+ const tx = buildExactTransfer({
86
+ asset,
87
+ amount: BigInt(accept.amount),
88
+ payTo: accept.payTo,
89
+ payer: opts.account.address,
90
+ payerPublicKey: opts.account.publicKey,
91
+ accountNonce: opts.accountNonce,
92
+ nonce: accept.extra.nonce,
93
+ chain: opts.chain
94
+ });
95
+ const signed = await signTransactionWithAccount(tx, opts.account);
96
+ const header = b64encode({
97
+ x402Version: opts.challenge.x402Version ?? 2,
98
+ scheme: "exact",
99
+ network: accept.network,
100
+ asset: accept.asset,
101
+ payload: { transaction: serializeTransactionHex(signed) },
102
+ extra: { nonce: accept.extra.nonce }
103
+ });
104
+ return { header, accept };
105
+ }
106
+ function withX402(baseFetch, opts) {
107
+ const sessions = new Map;
108
+ let balanceToken = opts.balanceToken ?? null;
109
+ let toppingUp = false;
110
+ const originOf = (input) => {
111
+ try {
112
+ return new URL(String(input)).origin;
113
+ } catch {
114
+ return "";
115
+ }
116
+ };
117
+ const wrapped = async (input, init) => {
118
+ const origin = originOf(input);
119
+ const run = (extra, signal2) => baseFetch(input, {
120
+ ...init,
121
+ headers: { ...init?.headers, ...extra },
122
+ ...signal2 ? { signal: signal2 } : {}
123
+ });
124
+ const maybeTopUp = (res) => {
125
+ const policy = opts.topUp;
126
+ if (!policy || toppingUp || !origin)
127
+ return;
128
+ const remaining = res.headers.get("X-BALANCE-REMAINING-USD");
129
+ if (remaining === null || Number(remaining) >= policy.whenBelow)
130
+ return;
131
+ toppingUp = true;
132
+ (async () => {
133
+ try {
134
+ const dep = await wrapped(`${origin}/v1/x402/deposit?usd=${policy.usd}`, { method: "POST" });
135
+ if (dep.ok) {
136
+ const body = await dep.json();
137
+ if (body.balance_token)
138
+ balanceToken = body.balance_token;
139
+ }
140
+ } catch {} finally {
141
+ toppingUp = false;
142
+ }
143
+ })();
144
+ };
145
+ const remember = (res) => {
146
+ const voucher = res.headers.get("PAYMENT-SESSION");
147
+ if (voucher && origin)
148
+ sessions.set(origin, voucher);
149
+ maybeTopUp(res);
150
+ return res;
151
+ };
152
+ const cached = origin ? sessions.get(origin) : undefined;
153
+ const first = await run({
154
+ ...cached ? { "PAYMENT-SESSION": cached } : {},
155
+ ...balanceToken ? { "PAYMENT-BALANCE": balanceToken } : {}
156
+ });
157
+ if (first.status !== 402)
158
+ return remember(first);
159
+ if (cached && origin)
160
+ sessions.delete(origin);
161
+ const challenge = await readX402Challenge(first);
162
+ if (!challenge)
163
+ return first;
164
+ const { accept } = selectOffer(challenge, opts);
165
+ const accountNonce = opts.accountNonce ?? await resolveAccountNonce(opts.account.address, opts.nodeUrl);
166
+ const { header } = await buildSignedX402Payment({
167
+ challenge,
168
+ account: opts.account,
169
+ accountNonce,
170
+ asset: accept.asset,
171
+ chain: opts.chain
172
+ });
173
+ opts.onSettling?.({ asset: accept.asset, amount: accept.amount });
174
+ const signal = opts.timeoutMs ? AbortSignal.timeout(opts.timeoutMs) : undefined;
175
+ return remember(await run({ "PAYMENT-SIGNATURE": header }, signal));
176
+ };
177
+ return wrapped;
178
+ }
179
+ function createX402Client(opts) {
180
+ const f = withX402(opts.fetch ?? fetch, opts);
181
+ const base = opts.baseUrl.replace(/\/$/, "");
182
+ async function request(method, path, o = {}) {
183
+ const qs = o.query ? `?${new URLSearchParams(o.query).toString()}` : "";
184
+ const init = { method };
185
+ if (o.body !== undefined) {
186
+ init.body = JSON.stringify(o.body);
187
+ init.headers = { "content-type": "application/json" };
188
+ }
189
+ const response = await f(`${base}${path}${qs}`, init);
190
+ const data = await response.json().catch(() => null);
191
+ return { data, payment: readX402Receipt(response), response };
192
+ }
193
+ return {
194
+ get: (path, o) => request("GET", path, o),
195
+ post: (path, o) => request("POST", path, o)
196
+ };
197
+ }
198
+ async function payAndRetry(doFetch, opts) {
199
+ const first = await doFetch({});
200
+ if (first.status !== 402)
201
+ return first;
202
+ const challenge = await readX402Challenge(first);
203
+ if (!challenge)
204
+ return first;
205
+ const { accept } = selectOffer(challenge, opts);
206
+ const { header } = await buildSignedX402Payment({
207
+ challenge,
208
+ account: opts.account,
209
+ accountNonce: opts.accountNonce,
210
+ asset: accept.asset,
211
+ chain: opts.chain
212
+ });
213
+ return doFetch({ "PAYMENT-SIGNATURE": header });
214
+ }
215
+ export {
216
+ withX402,
217
+ selectOffer,
218
+ resolveAccountNonce,
219
+ readX402Receipt,
220
+ readX402Challenge,
221
+ payAndRetry,
222
+ createX402Client,
223
+ buildSignedX402Payment,
224
+ X402SpendGuardError,
225
+ DEFAULT_PREFER_ASSETS,
226
+ DEFAULT_NONCE_NODE_URL
227
+ };
228
+
229
+ //# debugId=264371DAFD103C7564756E2164756E21
230
+ //# sourceMappingURL=x402.js.map
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/x402.ts"],
4
+ "sourcesContent": [
5
+ "import {\n\ttype X402TokenSymbol,\n\tX402_TOKENS,\n\tfindX402TokenByAsset,\n} from \"@secondlayer/shared/x402\";\nimport type { LocalAccount } from \"@secondlayer/stacks/accounts\";\nimport type { StacksChain } from \"@secondlayer/stacks/chains\";\nimport {\n\tserializeTransactionHex,\n\tsignTransactionWithAccount,\n} from \"@secondlayer/stacks/transactions\";\nimport { buildExactTransfer } from \"@secondlayer/stacks/x402\";\n\n/**\n * Client for the x402 pay-per-request rail. Turns a 402 challenge into a signed\n * `PAYMENT-SIGNATURE` and retries — gasless (the agent signs origin-only; the\n * facilitator sponsors the STX fee) and accountless (no key/Stripe/session).\n *\n * Three layers:\n * - `withX402(fetch, opts)` — drop-in fetch that auto-pays on 402.\n * - `createX402Client(opts)` — `.get/.post` returning `{ data, payment }`.\n * - `buildSignedX402Payment` / `readX402Challenge` — primitives for custom transports.\n */\n\nexport type X402Accept = {\n\tscheme: \"exact\";\n\tnetwork: string;\n\tasset: string;\n\t/** Atomic units. */\n\tamount: string;\n\tpayTo: string;\n\tmaxTimeoutSeconds: number;\n\textra: { nonce: string };\n};\n\nexport type X402Challenge = {\n\tx402Version: number;\n\taccepts: X402Accept[];\n\terror?: string;\n};\n\n/** Decoded `PAYMENT-RESPONSE` settlement receipt. */\nexport type X402Receipt = {\n\tsuccess: boolean;\n\t/** Settlement tier: `optimistic` (served on broadcast-accept, reconciled\n\t * async) or `confirmed` (canonical). Absent on older deployments. */\n\tstate?: \"optimistic\" | \"confirmed\";\n\ttxid: string;\n\tpayer: string;\n\tnetwork: string;\n};\n\n/** Bitcoin-native first — sBTC is the compelling micropay asset; USDCx the\n * dollar peg; STX the fallback. Override via `preferAssets`. */\nexport const DEFAULT_PREFER_ASSETS: X402TokenSymbol[] = [\n\t\"sBTC\",\n\t\"USDCx\",\n\t\"STX\",\n];\n\n/** Default node for auto-resolving the payer's account nonce (`/v2/accounts`). */\nexport const DEFAULT_NONCE_NODE_URL = \"https://api.hiro.so\";\n\n/** Thrown when no offered asset is within the caller's spend guard / preferences. */\nexport class X402SpendGuardError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"X402SpendGuardError\";\n\t}\n}\n\nfunction b64encode(value: unknown): string {\n\treturn Buffer.from(JSON.stringify(value), \"utf8\").toString(\"base64\");\n}\n\nfunction b64decodeJson<T>(value: string): T | null {\n\ttry {\n\t\treturn JSON.parse(Buffer.from(value, \"base64\").toString(\"utf8\")) as T;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/** Read the x402 challenge from a 402 response — prefer the wire header, fall\n * back to the JSON body. */\nexport async function readX402Challenge(\n\tres: Response,\n): Promise<X402Challenge | null> {\n\tconst header = res.headers.get(\"PAYMENT-REQUIRED\");\n\tif (header) {\n\t\tconst decoded = b64decodeJson<X402Challenge>(header);\n\t\tif (decoded) return decoded;\n\t}\n\ttry {\n\t\treturn (await res.clone().json()) as X402Challenge;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/** Read the settlement receipt from a paid 200 response. */\nexport function readX402Receipt(res: Response): X402Receipt | null {\n\tconst header = res.headers.get(\"PAYMENT-RESPONSE\");\n\treturn header ? b64decodeJson<X402Receipt>(header) : null;\n}\n\nexport type SelectOfferOptions = {\n\tpreferAssets?: X402TokenSymbol[];\n\tmaxAmountPerCall?: Partial<Record<X402TokenSymbol, bigint>>;\n};\n\n/** Choose an `accepts[]` entry by preference order, skipping any that exceed the\n * per-asset spend cap. Throws {@link X402SpendGuardError} if none qualify. */\nexport function selectOffer(\n\tchallenge: X402Challenge,\n\topts: SelectOfferOptions = {},\n): { accept: X402Accept; symbol: X402TokenSymbol } {\n\tconst prefer = opts.preferAssets ?? DEFAULT_PREFER_ASSETS;\n\tfor (const symbol of prefer) {\n\t\tconst token = X402_TOKENS[symbol];\n\t\tconst accept = challenge.accepts.find((a) => a.asset === token.asset);\n\t\tif (!accept) continue;\n\t\tconst cap = opts.maxAmountPerCall?.[symbol];\n\t\tif (cap !== undefined && BigInt(accept.amount) > cap) continue;\n\t\treturn { accept, symbol };\n\t}\n\tthrow new X402SpendGuardError(\n\t\t\"no x402 offer matched preferAssets within maxAmountPerCall\",\n\t);\n}\n\n/** Fetch the payer account's next nonce from a Stacks node (`/v2/accounts`). */\nexport async function resolveAccountNonce(\n\taddress: string,\n\tnodeUrl: string = DEFAULT_NONCE_NODE_URL,\n): Promise<number> {\n\tconst res = await fetch(\n\t\t`${nodeUrl.replace(/\\/$/, \"\")}/v2/accounts/${address}?proof=0`,\n\t);\n\tif (!res.ok) throw new Error(`x402 nonce lookup failed: ${res.status}`);\n\tconst json = (await res.json()) as { nonce: number };\n\treturn json.nonce;\n}\n\nexport type BuildSignedX402PaymentOptions = {\n\tchallenge: X402Challenge;\n\taccount: LocalAccount;\n\t/** The payer account's next nonce. */\n\taccountNonce: bigint | number | string;\n\t/** Preferred asset string (e.g. an sBTC/USDCx id). Defaults to the first offer. */\n\tasset?: string;\n\tchain?: StacksChain;\n};\n\n/** Build a signed, base64 `PAYMENT-SIGNATURE` header for one `accepts[]` entry. */\nexport async function buildSignedX402Payment(\n\topts: BuildSignedX402PaymentOptions,\n): Promise<{ header: string; accept: X402Accept }> {\n\tconst accept = opts.asset\n\t\t? opts.challenge.accepts.find((a) => a.asset === opts.asset)\n\t\t: opts.challenge.accepts[0];\n\tif (!accept) {\n\t\tthrow new Error(\n\t\t\t`No x402 offer${opts.asset ? ` for asset ${opts.asset}` : \"\"}`,\n\t\t);\n\t}\n\tconst token = findX402TokenByAsset(accept.asset);\n\tif (!token) throw new Error(`Unknown x402 asset: ${accept.asset}`);\n\n\tconst asset =\n\t\ttoken.contractId && token.assetName\n\t\t\t? {\n\t\t\t\t\tkind: \"sip010\" as const,\n\t\t\t\t\tcontractId: token.contractId,\n\t\t\t\t\tassetName: token.assetName,\n\t\t\t\t}\n\t\t\t: { kind: \"stx\" as const };\n\n\tconst tx = buildExactTransfer({\n\t\tasset,\n\t\tamount: BigInt(accept.amount),\n\t\tpayTo: accept.payTo,\n\t\tpayer: opts.account.address,\n\t\tpayerPublicKey: opts.account.publicKey,\n\t\taccountNonce: opts.accountNonce,\n\t\tnonce: accept.extra.nonce,\n\t\tchain: opts.chain,\n\t});\n\tconst signed = await signTransactionWithAccount(tx, opts.account);\n\n\tconst header = b64encode({\n\t\tx402Version: opts.challenge.x402Version ?? 2,\n\t\tscheme: \"exact\",\n\t\tnetwork: accept.network,\n\t\tasset: accept.asset,\n\t\tpayload: { transaction: serializeTransactionHex(signed) },\n\t\textra: { nonce: accept.extra.nonce },\n\t});\n\treturn { header, accept };\n}\n\nexport type WithX402Options = SelectOfferOptions & {\n\taccount: LocalAccount;\n\t/** Prepaid-credit token (PAYMENT-BALANCE) from a prior deposit — calls\n\t * debit the tab server-side instead of settling on-chain per call. */\n\tbalanceToken?: string;\n\t/** Autonomous treasury policy: when the tab's remaining balance (read from\n\t * X-BALANCE-REMAINING-USD) drops below `whenBelow`, deposit `usd` more in\n\t * the background (one on-chain payment) and adopt the fresh token. */\n\ttopUp?: { usd: number; whenBelow: number };\n\t/** Override the payer nonce; auto-resolved from `nodeUrl` when omitted. */\n\taccountNonce?: bigint | number | string;\n\t/** Node for auto-nonce lookup. Defaults to {@link DEFAULT_NONCE_NODE_URL}. */\n\tnodeUrl?: string;\n\tchain?: StacksChain;\n\t/** Fired just before the paid retry (the call then blocks on confirmed-tier\n\t * settle, or returns near-instantly on an optimistic surface). */\n\tonSettling?: (info: { asset: string; amount: string }) => void;\n\t/** Abort the paid retry after this long. */\n\ttimeoutMs?: number;\n};\n\nexport type X402Fetch = (\n\tinput: string | URL,\n\tinit?: RequestInit,\n) => Promise<Response>;\n\n/**\n * Wrap a `fetch` so requests transparently pay on 402: select an offer (by\n * `preferAssets` + `maxAmountPerCall`), resolve the nonce, sign origin-only, and\n * retry once with `PAYMENT-SIGNATURE`. Returns the final `Response` (read the\n * receipt with {@link readX402Receipt}).\n *\n * @example\n * const x402fetch = withX402(fetch, { account });\n * const res = await x402fetch(\"https://api.secondlayer.tools/v1/index/events?event_type=ft_transfer\");\n */\nexport function withX402(\n\tbaseFetch: typeof fetch,\n\topts: WithX402Options,\n): X402Fetch {\n\t// Session vouchers (PAYMENT-SESSION): surfaces with session pricing hand\n\t// back a voucher on settle — replaying it lets subsequent calls ride the\n\t// paid session instead of re-paying per request. Cached per origin; the\n\t// server is authoritative (a 402 despite a voucher just restarts the\n\t// payment cycle and refreshes the cache).\n\tconst sessions = new Map<string, string>();\n\tlet balanceToken = opts.balanceToken ?? null;\n\tlet toppingUp = false;\n\tconst originOf = (input: Parameters<X402Fetch>[0]) => {\n\t\ttry {\n\t\t\treturn new URL(String(input)).origin;\n\t\t} catch {\n\t\t\treturn \"\";\n\t\t}\n\t};\n\n\tconst wrapped: X402Fetch = async (input, init) => {\n\t\tconst origin = originOf(input);\n\t\tconst run = (extra: Record<string, string>, signal?: AbortSignal) =>\n\t\t\tbaseFetch(input, {\n\t\t\t\t...init,\n\t\t\t\theaders: { ...(init?.headers as Record<string, string>), ...extra },\n\t\t\t\t...(signal ? { signal } : {}),\n\t\t\t});\n\n\t\t// Treasury policy: refill the tab in the background before it empties.\n\t\t// The deposit goes through this same wrapper (402 → pay → credited);\n\t\t// its response carries the fresh PAYMENT-BALANCE token.\n\t\tconst maybeTopUp = (res: Response) => {\n\t\t\tconst policy = opts.topUp;\n\t\t\tif (!policy || toppingUp || !origin) return;\n\t\t\tconst remaining = res.headers.get(\"X-BALANCE-REMAINING-USD\");\n\t\t\tif (remaining === null || Number(remaining) >= policy.whenBelow) return;\n\t\t\ttoppingUp = true;\n\t\t\tvoid (async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst dep = await wrapped(\n\t\t\t\t\t\t`${origin}/v1/x402/deposit?usd=${policy.usd}`,\n\t\t\t\t\t\t{ method: \"POST\" },\n\t\t\t\t\t);\n\t\t\t\t\tif (dep.ok) {\n\t\t\t\t\t\tconst body = (await dep.json()) as { balance_token?: string };\n\t\t\t\t\t\tif (body.balance_token) balanceToken = body.balance_token;\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// next sub-threshold response retries the top-up\n\t\t\t\t} finally {\n\t\t\t\t\ttoppingUp = false;\n\t\t\t\t}\n\t\t\t})();\n\t\t};\n\n\t\tconst remember = (res: Response) => {\n\t\t\tconst voucher = res.headers.get(\"PAYMENT-SESSION\");\n\t\t\tif (voucher && origin) sessions.set(origin, voucher);\n\t\t\tmaybeTopUp(res);\n\t\t\treturn res;\n\t\t};\n\n\t\tconst cached = origin ? sessions.get(origin) : undefined;\n\t\tconst first = await run({\n\t\t\t...(cached ? { \"PAYMENT-SESSION\": cached } : {}),\n\t\t\t...(balanceToken ? { \"PAYMENT-BALANCE\": balanceToken } : {}),\n\t\t});\n\t\tif (first.status !== 402) return remember(first);\n\t\tif (cached && origin) sessions.delete(origin);\n\n\t\tconst challenge = await readX402Challenge(first);\n\t\tif (!challenge) return first;\n\n\t\tconst { accept } = selectOffer(challenge, opts);\n\t\tconst accountNonce =\n\t\t\topts.accountNonce ??\n\t\t\t(await resolveAccountNonce(opts.account.address, opts.nodeUrl));\n\t\tconst { header } = await buildSignedX402Payment({\n\t\t\tchallenge,\n\t\t\taccount: opts.account,\n\t\t\taccountNonce,\n\t\t\tasset: accept.asset,\n\t\t\tchain: opts.chain,\n\t\t});\n\n\t\topts.onSettling?.({ asset: accept.asset, amount: accept.amount });\n\t\tconst signal = opts.timeoutMs\n\t\t\t? AbortSignal.timeout(opts.timeoutMs)\n\t\t\t: undefined;\n\t\treturn remember(await run({ \"PAYMENT-SIGNATURE\": header }, signal));\n\t};\n\treturn wrapped;\n}\n\nexport type X402ClientOptions = WithX402Options & {\n\tbaseUrl: string;\n\t/** Override the underlying fetch (tests). */\n\tfetch?: typeof fetch;\n};\n\nexport type X402Result<T = unknown> = {\n\tdata: T;\n\t/** Settlement receipt, or null if the response carried none. */\n\tpayment: X402Receipt | null;\n\tresponse: Response;\n};\n\nexport type X402Client = {\n\tget<T = unknown>(\n\t\tpath: string,\n\t\to?: { query?: Record<string, string> },\n\t): Promise<X402Result<T>>;\n\tpost<T = unknown>(\n\t\tpath: string,\n\t\to?: { body?: unknown },\n\t): Promise<X402Result<T>>;\n};\n\n/**\n * A small client over {@link withX402}: `.get/.post` against `baseUrl`, returning\n * parsed JSON plus the settlement receipt.\n *\n * @example\n * const sl = createX402Client({ account, baseUrl: \"https://api.secondlayer.tools\" });\n * const { data, payment } = await sl.get(\"/v1/index/events\", { query: { event_type: \"ft_transfer\" } });\n */\nexport function createX402Client(opts: X402ClientOptions): X402Client {\n\tconst f = withX402(opts.fetch ?? fetch, opts);\n\tconst base = opts.baseUrl.replace(/\\/$/, \"\");\n\n\tasync function request<T>(\n\t\tmethod: \"GET\" | \"POST\",\n\t\tpath: string,\n\t\to: { query?: Record<string, string>; body?: unknown } = {},\n\t): Promise<X402Result<T>> {\n\t\tconst qs = o.query ? `?${new URLSearchParams(o.query).toString()}` : \"\";\n\t\tconst init: RequestInit = { method };\n\t\tif (o.body !== undefined) {\n\t\t\tinit.body = JSON.stringify(o.body);\n\t\t\tinit.headers = { \"content-type\": \"application/json\" };\n\t\t}\n\t\tconst response = await f(`${base}${path}${qs}`, init);\n\t\tconst data = (await response.json().catch(() => null)) as T;\n\t\treturn { data, payment: readX402Receipt(response), response };\n\t}\n\n\treturn {\n\t\tget: <T = unknown>(path: string, o?: { query?: Record<string, string> }) =>\n\t\t\trequest<T>(\"GET\", path, o),\n\t\tpost: <T = unknown>(path: string, o?: { body?: unknown }) =>\n\t\t\trequest<T>(\"POST\", path, o),\n\t};\n}\n\n/** Caller-supplied fetch that re-runs the request with the given extra headers. */\nexport type X402FetchFn = (\n\textraHeaders: Record<string, string>,\n) => Promise<Response>;\n\nexport type PayAndRetryOptions = Omit<WithX402Options, never> & {\n\t/** Required here (use `withX402` for auto-nonce). */\n\taccountNonce: bigint | number | string;\n};\n\n/**\n * Low-level: run a request via a caller-controlled fetch; if it 402s, pay and\n * retry once. Prefer {@link withX402} for the common case (it auto-resolves the\n * nonce + selects the asset). Kept for custom transports.\n */\nexport async function payAndRetry(\n\tdoFetch: X402FetchFn,\n\topts: PayAndRetryOptions,\n): Promise<Response> {\n\tconst first = await doFetch({});\n\tif (first.status !== 402) return first;\n\tconst challenge = await readX402Challenge(first);\n\tif (!challenge) return first;\n\tconst { accept } = selectOffer(challenge, opts);\n\tconst { header } = await buildSignedX402Payment({\n\t\tchallenge,\n\t\taccount: opts.account,\n\t\taccountNonce: opts.accountNonce,\n\t\tasset: accept.asset,\n\t\tchain: opts.chain,\n\t});\n\treturn doFetch({ \"PAYMENT-SIGNATURE\": header });\n}\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "264371DAFD103C7564756E2164756E21",
9
+ "names": []
10
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@secondlayer/sdk",
3
- "version": "6.19.0",
3
+ "version": "6.21.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -23,6 +23,10 @@
23
23
  "./subgraphs": {
24
24
  "types": "./dist/subgraphs/index.d.ts",
25
25
  "import": "./dist/subgraphs/index.js"
26
+ },
27
+ "./x402": {
28
+ "types": "./dist/x402.d.ts",
29
+ "import": "./dist/x402.js"
26
30
  }
27
31
  },
28
32
  "files": [
@@ -36,9 +40,9 @@
36
40
  "prepublishOnly": "bun run build"
37
41
  },
38
42
  "dependencies": {
39
- "@secondlayer/shared": "^6.28.0",
40
- "@secondlayer/stacks": "^2.4.0",
41
- "@secondlayer/subgraphs": "^3.10.0"
43
+ "@secondlayer/shared": "^6.30.0",
44
+ "@secondlayer/stacks": "^2.5.0",
45
+ "@secondlayer/subgraphs": "^3.11.0"
42
46
  },
43
47
  "devDependencies": {
44
48
  "@types/bun": "latest",