@piprail/sdk 2.7.0 → 2.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/CHANGELOG.md +96 -0
- package/README.md +5 -3
- package/dist/{algorand-WB6PBJU4.js → algorand-AA3WXKW4.js} +1 -1
- package/dist/{algorand-TMA62DN2.cjs → algorand-FCEECDG6.cjs} +32 -32
- package/dist/{aptos-JQMZNTMD.cjs → aptos-GHJPO6JJ.cjs} +31 -31
- package/dist/{aptos-QAAXIUY3.js → aptos-LY67Q6QF.js} +1 -1
- package/dist/{chunk-JG6KRAW6.cjs → chunk-MWBT7MCE.cjs} +13 -1
- package/dist/chunk-O4UQOZ4Z.cjs +14 -0
- package/dist/{chunk-7XK22JSQ.js → chunk-SC2ZYDHD.js} +12 -0
- package/dist/chunk-SK3CB7UA.js +14 -0
- package/dist/index.cjs +754 -238
- package/dist/index.d.cts +2386 -2577
- package/dist/index.d.ts +2386 -2577
- package/dist/index.js +595 -79
- package/dist/ledger-BtzrfO-3.d.cts +658 -0
- package/dist/ledger-BtzrfO-3.d.ts +658 -0
- package/dist/{near-H5AQ253I.cjs → near-6KAQVVG2.cjs} +26 -26
- package/dist/{near-OTPQD6BI.js → near-FZBUICCS.js} +1 -1
- package/dist/node.cjs +38 -0
- package/dist/node.d.cts +16 -0
- package/dist/node.d.ts +16 -0
- package/dist/node.js +38 -0
- package/dist/{solana-3FMCWSEE.js → solana-ELUWO6N5.js} +33 -2
- package/dist/{solana-M3VOHCMO.cjs → solana-MYF4HBO4.cjs} +64 -33
- package/dist/{stellar-U5NCRIOJ.js → stellar-BEMT7UYF.js} +1 -1
- package/dist/{stellar-FW6C6FBE.cjs → stellar-SUKASK4N.cjs} +20 -20
- package/dist/{sui-Y53M4GUM.js → sui-F5JQ2N6I.js} +1 -1
- package/dist/{sui-47C2KEZI.cjs → sui-VE5LT7BL.cjs} +16 -16
- package/dist/{ton-5ZPT5PSP.js → ton-7GKCTC5H.js} +11 -7
- package/dist/{ton-MMPKWT6N.cjs → ton-AOR3EURW.cjs} +25 -21
- package/dist/{tron-JOT4STIG.cjs → tron-EMFXDFHW.cjs} +24 -24
- package/dist/{tron-WYS4X2I5.js → tron-ZZZS3FNN.js} +1 -1
- package/dist/{xrpl-2MZEOIFY.js → xrpl-DD7TJL5L.js} +1 -1
- package/dist/{xrpl-PECT4IMX.cjs → xrpl-Y6SQNYLC.cjs} +20 -20
- package/package.json +11 -1
|
@@ -0,0 +1,658 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The on-the-wire payment protocol. Self-contained — it runs entirely
|
|
3
|
+
* between the agent and your server, with nothing hosted in between.
|
|
4
|
+
*
|
|
5
|
+
* Lowercase headers, no `X-` prefix:
|
|
6
|
+
* - payment-required (server → client, base64 JSON challenge)
|
|
7
|
+
* - payment-signature (client → server, base64 JSON proof)
|
|
8
|
+
* - payment-response (server → client, base64 JSON receipt on 200)
|
|
9
|
+
*
|
|
10
|
+
* Scheme is `onchain-proof`: the agent pays on-chain and hands back a proof
|
|
11
|
+
* reference (an EVM tx hash, a Solana signature, …); the server verifies
|
|
12
|
+
* that transaction itself, locally, against its own RPC. No third party.
|
|
13
|
+
*
|
|
14
|
+
* This file is CHAIN-AGNOSTIC. Identifiers are plain strings in CAIP-2 /
|
|
15
|
+
* base-unit form so any family (EVM, Solana, …) round-trips through the same
|
|
16
|
+
* envelopes. Each PaymentDriver interprets them for its own chain.
|
|
17
|
+
*
|
|
18
|
+
* Wire format targets x402 v2 — github.com/coinbase/x402, specs/x402-specification-v2.md
|
|
19
|
+
* (v2.0, 2025-12-9) + specs/transports-v2/http.md. The ENVELOPE is v2-conformant
|
|
20
|
+
* (PaymentPayload carries `accepted`; SettlementResponse has `success` + `transaction`).
|
|
21
|
+
* The SETTLEMENT SCHEME is our own `onchain-proof` (client pays on-chain first, proves
|
|
22
|
+
* with a tx ref, server verifies locally) — permitted by spec §6 (a scheme owns its
|
|
23
|
+
* `payload`) + §7 (self-hosted verification), but it does NOT interoperate with the
|
|
24
|
+
* built-in `exact` scheme (which is signature + facilitator-broadcast). Deliberate.
|
|
25
|
+
*/
|
|
26
|
+
/** A CAIP-2 network id, e.g. `eip155:8453` or `solana:5eykt4Us…`. */
|
|
27
|
+
type Caip2 = `${string}:${string}`;
|
|
28
|
+
/** An asset id — chain-specific: an EVM `0x…` address, a Solana base58 mint, a
|
|
29
|
+
* TON jetton master, a Stellar `CODE:ISSUER`, or `'native'`. */
|
|
30
|
+
type AssetId = string;
|
|
31
|
+
/** An account id — chain-specific: an EVM `0x…` address, a Solana base58 pubkey,
|
|
32
|
+
* a TON address, or a Stellar `G…` account. */
|
|
33
|
+
type AddressId = string;
|
|
34
|
+
interface X402ResourceObject {
|
|
35
|
+
url: string;
|
|
36
|
+
description?: string;
|
|
37
|
+
/** The resource's response content-type, e.g. 'application/json' (v2 ResourceInfo, optional). */
|
|
38
|
+
mimeType?: string;
|
|
39
|
+
}
|
|
40
|
+
interface X402AcceptEntry {
|
|
41
|
+
scheme: 'onchain-proof';
|
|
42
|
+
network: Caip2;
|
|
43
|
+
/** Amount in the token's base units (already scaled by decimals). */
|
|
44
|
+
amount: string;
|
|
45
|
+
/** ERC-20 address / SPL mint, or 'native' for the chain's native coin. */
|
|
46
|
+
asset: AssetId;
|
|
47
|
+
payTo: AddressId;
|
|
48
|
+
/** Payment is only accepted if mined within this many seconds of now. */
|
|
49
|
+
maxTimeoutSeconds: number;
|
|
50
|
+
extra: {
|
|
51
|
+
/** Single-use id echoed back in the proof. */
|
|
52
|
+
nonce: string;
|
|
53
|
+
/** Token decimals, so the client can render the amount. */
|
|
54
|
+
decimals: number;
|
|
55
|
+
/** Confirmations the client should wait before retrying. */
|
|
56
|
+
minConfirmations: number;
|
|
57
|
+
/** Human-readable amount, e.g. "0.05". */
|
|
58
|
+
amountFormatted: string;
|
|
59
|
+
symbol?: string;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* A standard x402 `exact` rail (EVM / EIP-3009) — the interop rail a PipRail gate
|
|
64
|
+
* advertises ALONGSIDE its `onchain-proof` rail (dual-advertise) so any standard
|
|
65
|
+
* x402 client can pay it. Same v2 PaymentRequirements skeleton as
|
|
66
|
+
* {@link X402AcceptEntry}; only `scheme` and `extra` differ. The `extra` carries
|
|
67
|
+
* the EIP-712 domain a payer signs over — `name`/`version` are READ from the token
|
|
68
|
+
* contract by the gate (never assumed), since e.g. USDC's domain name is "USD Coin",
|
|
69
|
+
* not the "USDC" symbol.
|
|
70
|
+
*/
|
|
71
|
+
interface X402ExactAcceptEntry {
|
|
72
|
+
scheme: 'exact';
|
|
73
|
+
network: Caip2;
|
|
74
|
+
amount: string;
|
|
75
|
+
asset: AssetId;
|
|
76
|
+
payTo: AddressId;
|
|
77
|
+
maxTimeoutSeconds: number;
|
|
78
|
+
extra: {
|
|
79
|
+
/** The exact transfer method. EVM: `'eip3009'` for tokens with native
|
|
80
|
+
* `transferWithAuthorization`, or `'permit2'` for tokens WITHOUT it (e.g.
|
|
81
|
+
* Binance-Peg USDC on BNB) — the payer signs a Permit2 witness transfer whose
|
|
82
|
+
* `spender` is the canonical x402ExactPermit2Proxy and whose `witness.to` binds the
|
|
83
|
+
* recipient. **Solana (SVM): `'svm'`** — the payer partial-signs an SPL
|
|
84
|
+
* `TransferChecked` transaction whose fee payer is the merchant (`feePayer` below),
|
|
85
|
+
* and the gate co-signs as fee payer + broadcasts. **Algorand: `'algorand'`** — the payer
|
|
86
|
+
* signs an ASA `axfer` to `payTo` at fee 0, atomically grouped with a 0-ALGO `pay` from
|
|
87
|
+
* the `feePayer` that pools the group fee (per `scheme_exact_algo.md`); the gate (or a
|
|
88
|
+
* keyless facilitator) signs that fee txn + submits. **Aptos: `'aptos'`** — the payer signs a
|
|
89
|
+
* fee-payer (sponsored) `primary_fungible_store::transfer` to `payTo` (per
|
|
90
|
+
* `scheme_exact_aptos.md`); the gate (or a keyless facilitator) adds the fee-payer signature
|
|
91
|
+
* + submits, paying gas. **NEAR: `'near'`** — the payer signs a NEP-366 `SignedDelegateAction`
|
|
92
|
+
* authorizing exactly one NEP-141 `ft_transfer` to `payTo` (per `scheme_exact_near.md`); a
|
|
93
|
+
* facilitator-selected relayer (`feePayer` below) prepays gas + the 1 yoctoNEAR and submits, so
|
|
94
|
+
* the buyer holds zero NEAR. PipRail self-settles ALL. */
|
|
95
|
+
assetTransferMethod: 'eip3009' | 'permit2' | 'svm' | 'algorand' | 'aptos' | 'near';
|
|
96
|
+
/** EIP-712 domain name of the token. OPTIONAL per the exact-EVM scheme (only
|
|
97
|
+
* `assetTransferMethod` is required) — a foreign rail may omit it. NEVER assumed
|
|
98
|
+
* from the symbol (USDC's on-chain name() is "USD Coin", not "USDC"); a PipRail gate
|
|
99
|
+
* READS it on-chain, and the PipRail buyer RE-DERIVES it on-chain and ignores this. */
|
|
100
|
+
name?: string;
|
|
101
|
+
/** EIP-712 domain version of the token (USDC: "2"). OPTIONAL (see `name`); read/re-derived on-chain. */
|
|
102
|
+
version?: string;
|
|
103
|
+
/** **SVM / Algorand / Aptos** — the fee-payer (gas sponsor) address. The buyer builds the
|
|
104
|
+
* transaction with this account as the gas payer (so the buyer spends ZERO native coin),
|
|
105
|
+
* leaving its signature for whoever sponsors; the gate (self mode) or a keyless facilitator
|
|
106
|
+
* fills it and submits. On **SVM** it must differ from `payTo` (the fee payer must never
|
|
107
|
+
* appear in an instruction — a MUST-rule); on **Algorand/Aptos** the fee txn/signature is
|
|
108
|
+
* separate from the transfer, so `feePayer === payTo` is allowed. */
|
|
109
|
+
feePayer?: string;
|
|
110
|
+
/** **SVM only, OPTIONAL** — a ≤256-byte reconciliation memo the buyer attaches to the
|
|
111
|
+
* transaction (the SVM scheme's optional `extra.memo`). */
|
|
112
|
+
memo?: string;
|
|
113
|
+
/** **SVM only** — which SPL token program the mint belongs to, so both the buyer and
|
|
114
|
+
* the gate derive the SAME associated-token-account address (an ATA's address depends
|
|
115
|
+
* on the token program). Defaults to `'spl-token'` (classic) when absent — the
|
|
116
|
+
* built-in USDC/USDT are classic. */
|
|
117
|
+
tokenProgram?: 'spl-token' | 'token-2022';
|
|
118
|
+
/** Confirmations the gate waits for before granting access — mirrors the gate's
|
|
119
|
+
* `minConfirmations`, so the exact rail honours the same reorg safety as onchain-proof.
|
|
120
|
+
* A PipRail convenience (standard clients ignore unknown keys). */
|
|
121
|
+
minConfirmations?: number;
|
|
122
|
+
/** Token decimals — a PipRail convenience (standard clients ignore unknown keys). */
|
|
123
|
+
decimals?: number;
|
|
124
|
+
/** Human-readable amount, e.g. "0.05" — a PipRail convenience. */
|
|
125
|
+
amountFormatted?: string;
|
|
126
|
+
symbol?: string;
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/** A challenge `accepts[]` entry — either PipRail's `onchain-proof` rail or a standard `exact` rail. */
|
|
130
|
+
type X402AnyAccept = X402AcceptEntry | X402ExactAcceptEntry;
|
|
131
|
+
interface X402Challenge {
|
|
132
|
+
x402Version: 2;
|
|
133
|
+
/**
|
|
134
|
+
* Optional human-readable reason (v2 `error?: string`). PipRail EMITS it only on a
|
|
135
|
+
* rejected-proof re-challenge (omitted on a fresh challenge). Typed to also tolerate
|
|
136
|
+
* `null` when PARSING a foreign challenge — some deployed servers send `error: null`.
|
|
137
|
+
*/
|
|
138
|
+
error?: string | null;
|
|
139
|
+
resource: X402ResourceObject;
|
|
140
|
+
accepts: X402AnyAccept[];
|
|
141
|
+
/** v2 optional extensions. PipRail stamps the machine-readable rejection reason here on a
|
|
142
|
+
* rejected-proof re-challenge: `{ piprail: { code, detail } }`. Omitted otherwise. */
|
|
143
|
+
extensions?: Record<string, unknown>;
|
|
144
|
+
}
|
|
145
|
+
interface X402PaymentSignature {
|
|
146
|
+
x402Version: 2;
|
|
147
|
+
/**
|
|
148
|
+
* x402 v2 PaymentPayload: the full PaymentRequirements entry the client chose
|
|
149
|
+
* (carries `scheme` + `network`), echoed back from the challenge's `accepts[]`.
|
|
150
|
+
*/
|
|
151
|
+
accepted: X402AcceptEntry;
|
|
152
|
+
/**
|
|
153
|
+
* Scheme-defined payload. For `onchain-proof`: the challenge nonce + the proof
|
|
154
|
+
* ref (`txHash` — a chain-specific id: an EVM tx hash, a Solana signature, a
|
|
155
|
+
* TON locator, or a Stellar tx hash).
|
|
156
|
+
*/
|
|
157
|
+
payload: {
|
|
158
|
+
nonce: string;
|
|
159
|
+
txHash: string;
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* The EIP-3009 authorization a payer signs for a standard `exact` rail. All
|
|
164
|
+
* numeric fields are DECIMAL strings on the wire (value, validAfter, validBefore);
|
|
165
|
+
* `nonce` is a 0x-prefixed 32-byte hex. Identical shape across x402 v1 and v2.
|
|
166
|
+
*/
|
|
167
|
+
interface ExactAuthorizationWire {
|
|
168
|
+
from: string;
|
|
169
|
+
to: string;
|
|
170
|
+
value: string;
|
|
171
|
+
validAfter: string;
|
|
172
|
+
validBefore: string;
|
|
173
|
+
nonce: string;
|
|
174
|
+
}
|
|
175
|
+
/** The `payload` a client sends for an `exact` rail: an EIP-3009 signature + its authorization. */
|
|
176
|
+
interface ExactPaymentPayload {
|
|
177
|
+
signature: string;
|
|
178
|
+
authorization: ExactAuthorizationWire;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* The `permit2Authorization` a payer signs for the `permit2` variant of the x402
|
|
182
|
+
* `exact` EVM scheme (tokens without EIP-3009 — e.g. Binance-Peg USDC on BNB). It is
|
|
183
|
+
* an EIP-712 `PermitWitnessTransferFrom` over the canonical Permit2 contract, whose
|
|
184
|
+
* `spender` is the canonical **x402ExactPermit2Proxy** and whose **witness** binds the
|
|
185
|
+
* recipient (`to`) + an activation time (`validAfter`). All numeric fields are DECIMAL
|
|
186
|
+
* strings on the wire (`permitted.amount`, `nonce`, `deadline`, `witness.validAfter`).
|
|
187
|
+
*/
|
|
188
|
+
interface Permit2Authorization {
|
|
189
|
+
/** What may be pulled: the ERC-20 token + the exact base-unit amount. */
|
|
190
|
+
permitted: {
|
|
191
|
+
token: string;
|
|
192
|
+
amount: string;
|
|
193
|
+
};
|
|
194
|
+
/** The payer (token owner). */
|
|
195
|
+
from: string;
|
|
196
|
+
/** The signature's allowed spender — the canonical x402ExactPermit2Proxy. */
|
|
197
|
+
spender: string;
|
|
198
|
+
/** Permit2 unordered nonce (a uint256, decimal string). Single-use via its bitmap. */
|
|
199
|
+
nonce: string;
|
|
200
|
+
/** Unix-seconds signature expiry. */
|
|
201
|
+
deadline: string;
|
|
202
|
+
/** The proxy-enforced witness: funds go ONLY to `to`, and not before `validAfter`. */
|
|
203
|
+
witness: {
|
|
204
|
+
to: string;
|
|
205
|
+
validAfter: string;
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
/** The `payload` a client sends for the `permit2` exact variant: a signature + its Permit2 authorization. */
|
|
209
|
+
interface Permit2PaymentPayload {
|
|
210
|
+
signature: string;
|
|
211
|
+
permit2Authorization: Permit2Authorization;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* The `payload` a client sends for the **SVM (Solana) `exact`** variant: a base64-encoded,
|
|
215
|
+
* serialized, **partially-signed** versioned Solana transaction (the buyer's `TransferChecked`
|
|
216
|
+
* with the merchant as fee payer; the fee-payer signature slot is left empty for the gate to
|
|
217
|
+
* fill). Per `scheme_exact_svm.md`. The transaction itself IS the proof — there's no separate
|
|
218
|
+
* authorization object (the SVM analogue of EIP-3009's `authorization`).
|
|
219
|
+
*/
|
|
220
|
+
interface ExactSvmPaymentPayload {
|
|
221
|
+
transaction: string;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* The `payload` a client sends for the **Algorand `exact`** variant, per
|
|
225
|
+
* `scheme_exact_algo.md`: an atomically-grouped set of base64-encoded msgpack transactions,
|
|
226
|
+
* and the index within it of the transaction that pays the resource server. The buyer's ASA
|
|
227
|
+
* `axfer` (to `payTo`, fee 0) is SIGNED; a 0-ALGO `pay` from the `feePayer` that pools the
|
|
228
|
+
* group fee is left UNSIGNED for whoever sponsors (the gate's relayer in self mode, or a
|
|
229
|
+
* keyless facilitator). The group itself IS the proof — there's no separate authorization
|
|
230
|
+
* object (the Algorand analogue of EIP-3009's `authorization` / SVM's `transaction`).
|
|
231
|
+
*/
|
|
232
|
+
interface ExactAlgorandPaymentPayload {
|
|
233
|
+
/** Index into `paymentGroup` of the txn that pays the resource server (the buyer's `axfer`). */
|
|
234
|
+
paymentIndex: number;
|
|
235
|
+
/** The atomic group: each element is a base64-encoded, msgpack-encoded (signed or unsigned)
|
|
236
|
+
* Algorand transaction. ≤ 16 elements (the protocol's atomic-group cap). */
|
|
237
|
+
paymentGroup: string[];
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* The `payload` a client sends for the **Aptos `exact`** variant, per `scheme_exact_aptos.md`:
|
|
241
|
+
* a fee-payer (sponsored, AIP-39) `primary_fungible_store::transfer`. `transaction` is the base64
|
|
242
|
+
* BCS-serialized `SimpleTransaction` (raw tx + the bound `feePayerAddress`); `senderAuth` is the
|
|
243
|
+
* base64 BCS-serialized buyer (sender) authenticator. The buyer leaves the fee-payer signature for
|
|
244
|
+
* whoever sponsors (the gate's relayer in self mode, or a keyless facilitator), who adds it +
|
|
245
|
+
* submits. The (tx + sender authenticator) IS the proof — there's no separate `authorization`
|
|
246
|
+
* object (the Aptos analogue of EIP-3009's `authorization` / SVM's `transaction`). The two-field
|
|
247
|
+
* shape (a `senderAuth` alongside `transaction`) also distinguishes it from the SVM payload.
|
|
248
|
+
*/
|
|
249
|
+
interface ExactAptosPaymentPayload {
|
|
250
|
+
/** Base64 BCS-serialized `SimpleTransaction` (raw transaction + the bound `feePayerAddress`). */
|
|
251
|
+
transaction: string;
|
|
252
|
+
/** Base64 BCS-serialized buyer (sender) `AccountAuthenticator`. */
|
|
253
|
+
senderAuth: string;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* The `payload` a client sends for the **NEAR `exact`** variant, per `scheme_exact_near.md`:
|
|
257
|
+
* a base64-encoded, Borsh-serialized NEP-366 `SignedDelegateAction` whose single delegated action
|
|
258
|
+
* is one NEP-141 `ft_transfer` (to `payTo`, the exact `amount`, `deposit: 1` yoctoNEAR). The buyer
|
|
259
|
+
* signs the delegate action with a FULL-ACCESS key (a function-call key can't attach the 1 yocto and
|
|
260
|
+
* is rejected); a facilitator-selected relayer wraps it, prepays gas + the yocto, and submits. The
|
|
261
|
+
* signed delegate action IS the proof — there's no separate authorization object (the NEAR analogue
|
|
262
|
+
* of EIP-3009's `authorization` / SVM's `transaction`). Its single self-contained string field also
|
|
263
|
+
* distinguishes it from every other family's payload shape.
|
|
264
|
+
*/
|
|
265
|
+
interface ExactNearPaymentPayload {
|
|
266
|
+
/** Base64 of the Borsh-encoded NEP-366 `SignedDelegateAction` (one `ft_transfer`). */
|
|
267
|
+
signedDelegateAction: string;
|
|
268
|
+
}
|
|
269
|
+
/** Any `exact`-rail payload shape — EIP-3009 (`authorization`), Permit2 (`permit2Authorization`),
|
|
270
|
+
* SVM (`transaction`), Algorand (`paymentGroup`), Aptos (`transaction` + `senderAuth`), or NEAR
|
|
271
|
+
* (`signedDelegateAction`). */
|
|
272
|
+
type ExactPaymentPayloadAny = ExactPaymentPayload | Permit2PaymentPayload | ExactSvmPaymentPayload | ExactAlgorandPaymentPayload | ExactAptosPaymentPayload | ExactNearPaymentPayload;
|
|
273
|
+
interface ParsedExactBase {
|
|
274
|
+
x402Version: number;
|
|
275
|
+
/** The client's claimed network (slug or CAIP-2) — for matching, not trust. */
|
|
276
|
+
network: string;
|
|
277
|
+
/** The client's claimed asset, if present (v2 `accepted.asset`). */
|
|
278
|
+
asset?: string;
|
|
279
|
+
/** The full decoded PaymentPayload, for verbatim forwarding to a facilitator (Mode B). */
|
|
280
|
+
raw: Record<string, unknown>;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* What {@link parseExactPaymentHeader} extracts from an inbound `exact` payment,
|
|
284
|
+
* normalised across the v1 (`X-PAYMENT`, flat `{scheme,network,payload}`, network slug)
|
|
285
|
+
* and v2 (`PAYMENT-SIGNATURE`, `{accepted,payload}`, CAIP-2 network) wire shapes.
|
|
286
|
+
* `network`/`asset` are the CLIENT's claim — used only to MATCH an offered rail; the gate
|
|
287
|
+
* re-derives every verified field from its own trusted rail. A discriminated union on
|
|
288
|
+
* `method`, so narrowing on `method` narrows `payload`: `'eip3009'` → {@link ExactPaymentPayload}
|
|
289
|
+
* (`authorization`), `'permit2'` → {@link Permit2PaymentPayload} (`permit2Authorization`),
|
|
290
|
+
* `'svm'` → {@link ExactSvmPaymentPayload} (`transaction`), `'algorand'` →
|
|
291
|
+
* {@link ExactAlgorandPaymentPayload} (`paymentGroup`); `'aptos'` →
|
|
292
|
+
* {@link ExactAptosPaymentPayload} (`transaction` + `senderAuth`); `'near'` →
|
|
293
|
+
* {@link ExactNearPaymentPayload} (`signedDelegateAction`).
|
|
294
|
+
*/
|
|
295
|
+
type ParsedExactPayment = (ParsedExactBase & {
|
|
296
|
+
method: 'eip3009';
|
|
297
|
+
payload: ExactPaymentPayload;
|
|
298
|
+
}) | (ParsedExactBase & {
|
|
299
|
+
method: 'permit2';
|
|
300
|
+
payload: Permit2PaymentPayload;
|
|
301
|
+
}) | (ParsedExactBase & {
|
|
302
|
+
method: 'svm';
|
|
303
|
+
payload: ExactSvmPaymentPayload;
|
|
304
|
+
}) | (ParsedExactBase & {
|
|
305
|
+
method: 'algorand';
|
|
306
|
+
payload: ExactAlgorandPaymentPayload;
|
|
307
|
+
}) | (ParsedExactBase & {
|
|
308
|
+
method: 'aptos';
|
|
309
|
+
payload: ExactAptosPaymentPayload;
|
|
310
|
+
}) | (ParsedExactBase & {
|
|
311
|
+
method: 'near';
|
|
312
|
+
payload: ExactNearPaymentPayload;
|
|
313
|
+
});
|
|
314
|
+
interface X402Receipt {
|
|
315
|
+
scheme: 'onchain-proof' | 'exact';
|
|
316
|
+
/**
|
|
317
|
+
* x402 v2 SettlementResponse: settlement succeeded. Always `true` here — a
|
|
318
|
+
* failed verification returns a 402, never a receipt.
|
|
319
|
+
*/
|
|
320
|
+
success: true;
|
|
321
|
+
network: Caip2;
|
|
322
|
+
/**
|
|
323
|
+
* x402 v2 SettlementResponse: the on-chain transaction id of the SETTLED
|
|
324
|
+
* payment — a chain-specific id (an EVM/Tron/Stellar/XRPL/NEAR tx hash, a
|
|
325
|
+
* Solana signature, or a Sui digest). This is the verified tx itself, NOT the
|
|
326
|
+
* submit-time proof ref in `payload.txHash` (which can be a composite locator
|
|
327
|
+
* on TON/NEAR). (Was `txHash` before v2 envelope conformance.)
|
|
328
|
+
*/
|
|
329
|
+
transaction: string;
|
|
330
|
+
asset: AssetId;
|
|
331
|
+
amount: string;
|
|
332
|
+
payer: AddressId;
|
|
333
|
+
payTo: AddressId;
|
|
334
|
+
verifiedAt: string;
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* The settled-payment record handed to a gate's `onPaid` hook — the wire
|
|
338
|
+
* {@link X402Receipt} plus the merchant-facing extras the gate already computed
|
|
339
|
+
* for the challenge, so a receipt handler never needs a second lookup to display
|
|
340
|
+
* or reconcile it: the token's `decimals`/`symbol`, the human `amountFormatted`
|
|
341
|
+
* (derived from the SETTLED base-unit `amount`, not the requested price), and a
|
|
342
|
+
* stable `idempotencyKey`.
|
|
343
|
+
*
|
|
344
|
+
* **Delivery contract — read this before persisting receipts.** `onPaid` is
|
|
345
|
+
* **at-least-once**: with a single in-memory replay store it fires exactly once
|
|
346
|
+
* per proof, but across instances sharing a custom `isUsed`/`markUsed` store two
|
|
347
|
+
* nodes can settle the same proof in a race and each fire once. Always **dedupe on
|
|
348
|
+
* `idempotencyKey`** (a unique index / upsert). It is also fire-and-forget by
|
|
349
|
+
* default — the gate does not block the response on it and a process crash between
|
|
350
|
+
* settlement and your side-effect drops that receipt. For durability either set
|
|
351
|
+
* `awaitOnPaid` (record before the 200) or push to a durable queue inside the hook;
|
|
352
|
+
* for a webhook, use {@link deliverReceipt} (signed, retried, idempotent).
|
|
353
|
+
*/
|
|
354
|
+
interface PaidReceipt extends X402Receipt {
|
|
355
|
+
/** The token's on-chain decimals — pairs with `amount` so you can format without a lookup. */
|
|
356
|
+
decimals: number;
|
|
357
|
+
/** The token symbol when the gate knows it (e.g. `USDC`, `FDUSD`). */
|
|
358
|
+
symbol?: string;
|
|
359
|
+
/** Human-readable settled amount, e.g. `"0.05"` — `amount` / 10**`decimals`. */
|
|
360
|
+
amountFormatted: string;
|
|
361
|
+
/**
|
|
362
|
+
* A stable, unique key for this settlement (the settled `transaction` id). `onPaid`
|
|
363
|
+
* is at-least-once across instances — dedupe persistence and webhook delivery on this.
|
|
364
|
+
*/
|
|
365
|
+
idempotencyKey: string;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Why a verification failed — a closed, chain-agnostic vocabulary. Every code a
|
|
369
|
+
* driver returns is in this union; a client/agent branches on it rather than
|
|
370
|
+
* parsing prose. Surfaced to the agent in the 402 body's `error` field with a
|
|
371
|
+
* human-readable `detail`. Some codes are family-specific (annotated below):
|
|
372
|
+
* e.g. account-watch chains (TON, Stellar) can't distinguish "wrong recipient"
|
|
373
|
+
* from "no payment", so both collapse to `transfer_not_found`.
|
|
374
|
+
*
|
|
375
|
+
* `transient` = the proof may simply not have propagated to the server's RPC
|
|
376
|
+
* node yet; `definitive` = retrying won't change it. These labels are
|
|
377
|
+
* informational for consumers — the built-in client retries EVERY code up to
|
|
378
|
+
* `maxPaymentRetries` (a short backoff absorbs RPC lag); it does not branch on
|
|
379
|
+
* the code.
|
|
380
|
+
*/
|
|
381
|
+
type VerifyErrorCode = 'tx_not_found' | 'insufficient_confirmations' | 'tx_reverted' | 'no_meta' | 'wrong_recipient' | 'amount_too_low' | 'transfer_not_found' | 'payment_expired' | 'tx_already_used' | 'signature_invalid';
|
|
382
|
+
/** The shape every driver's `verify()` returns. Shared by drivers + protocol. */
|
|
383
|
+
type VerifyResult = {
|
|
384
|
+
ok: true;
|
|
385
|
+
receipt: X402Receipt;
|
|
386
|
+
} | {
|
|
387
|
+
ok: false;
|
|
388
|
+
error: VerifyErrorCode;
|
|
389
|
+
detail: string;
|
|
390
|
+
};
|
|
391
|
+
declare const HEADER_REQUIRED = "payment-required";
|
|
392
|
+
declare const HEADER_SIGNATURE = "payment-signature";
|
|
393
|
+
declare const HEADER_RESPONSE = "payment-response";
|
|
394
|
+
declare const HEADER_SIGNATURE_V1 = "x-payment";
|
|
395
|
+
declare const HEADER_RESPONSE_V1 = "x-payment-response";
|
|
396
|
+
declare function buildChallengeHeader(challenge: X402Challenge): string;
|
|
397
|
+
declare function buildReceiptHeader(receipt: X402Receipt): string;
|
|
398
|
+
declare function buildSignatureHeader(signature: X402PaymentSignature): string;
|
|
399
|
+
/**
|
|
400
|
+
* Build the v2 PAYMENT-SIGNATURE header value for a standard x402 `exact` payment:
|
|
401
|
+
* base64 of `{ x402Version: 2, accepted, payload }`. `accepted` is the chosen rail
|
|
402
|
+
* echoed back VERBATIM from the challenge's `accepts[]` (preserving any extra keys a
|
|
403
|
+
* facilitator needs); `payload` is the EIP-3009 `{ signature, authorization }` the
|
|
404
|
+
* buyer's EVM driver produced. Chain-agnostic (pure JSON/base64) — the driver owns
|
|
405
|
+
* the signing, this only frames it for the wire. Round-trips through
|
|
406
|
+
* {@link parseExactPaymentHeader}. (The `onchain-proof` counterpart is
|
|
407
|
+
* {@link buildSignatureHeader}; the v1 flat-shape utility is `encodeXPaymentHeader`.)
|
|
408
|
+
*/
|
|
409
|
+
declare function buildExactSignatureHeader(input: {
|
|
410
|
+
accepted: X402ExactAcceptEntry;
|
|
411
|
+
payload: ExactPaymentPayloadAny;
|
|
412
|
+
}): string;
|
|
413
|
+
/**
|
|
414
|
+
* Parse the PAYMENT-REQUIRED challenge from a 402 response. Prefers the
|
|
415
|
+
* `payment-required` header, falls back to the JSON body.
|
|
416
|
+
*/
|
|
417
|
+
declare function parseChallenge(response: Response): Promise<X402Challenge | null>;
|
|
418
|
+
/** Parse the PAYMENT-RESPONSE receipt header on a 200 settlement. Reads the v2
|
|
419
|
+
* `payment-response` header, falling back to the v1 `x-payment-response` a foreign
|
|
420
|
+
* server may set. Returns a fully-formed {@link X402Receipt} only (a bare foreign
|
|
421
|
+
* exact SettleResponse without a `payer` is read by {@link parseSettleResponse}). */
|
|
422
|
+
declare function parseReceipt(response: Response): X402Receipt | null;
|
|
423
|
+
/**
|
|
424
|
+
* A standard x402 SettleResponse as the BUYER reads it off a settled (non-402)
|
|
425
|
+
* response. The `success` flag is authoritative: `false` is an EXPLICIT facilitator/
|
|
426
|
+
* server REJECTION (the buyer must NOT record a spend), `true` is an affirmative
|
|
427
|
+
* settlement. `transaction` is the on-chain settle tx the facilitator broadcast.
|
|
428
|
+
*/
|
|
429
|
+
interface SettleOutcome {
|
|
430
|
+
success: boolean;
|
|
431
|
+
transaction?: string;
|
|
432
|
+
network?: string;
|
|
433
|
+
payer?: string;
|
|
434
|
+
errorReason?: string;
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Read a standard x402 SettleResponse for the BUYER, from the v2 `payment-response`
|
|
438
|
+
* header (or the v1 `x-payment-response` fallback). Returns `null` when neither
|
|
439
|
+
* header is present, unparseable, or carries no boolean `success` — i.e. when the
|
|
440
|
+
* server served the resource WITHOUT echoing a settle result, which the exact buyer
|
|
441
|
+
* treats as an affirmative 2xx settlement (receipt-less). When a body IS present with
|
|
442
|
+
* a boolean `success`, that flag is returned verbatim: ONLY an explicit
|
|
443
|
+
* `success: false` is a rejection. Used by the exact pay path to tell a real
|
|
444
|
+
* settlement from a phantom one (never record a spend on `success:false`).
|
|
445
|
+
*/
|
|
446
|
+
declare function parseSettleResponse(response: Response): SettleOutcome | null;
|
|
447
|
+
/** Parse a PAYMENT-SIGNATURE header value (server side). */
|
|
448
|
+
declare function parseSignatureHeader(value: string): X402PaymentSignature | null;
|
|
449
|
+
/**
|
|
450
|
+
* Parse an inbound `exact` payment from a base64 header value (`PAYMENT-SIGNATURE`
|
|
451
|
+
* v2 or `X-PAYMENT` v1). Tolerant of BOTH wire shapes — the inner
|
|
452
|
+
* `{ signature, authorization }` payload is identical across versions, so we read
|
|
453
|
+
* `scheme`/`network` from either the v2 `accepted` object or the v1 flat fields.
|
|
454
|
+
* Returns null when the value isn't a recognisable `exact` payment (e.g. it's an
|
|
455
|
+
* `onchain-proof` proof, or malformed).
|
|
456
|
+
*/
|
|
457
|
+
declare function parseExactPaymentHeader(value: string): ParsedExactPayment | null;
|
|
458
|
+
/**
|
|
459
|
+
* Pick the first accepts[] entry on the `onchain-proof` scheme whose network
|
|
460
|
+
* satisfies `matches` (any chain family). Returns null if none match.
|
|
461
|
+
*/
|
|
462
|
+
declare function pickAccept(challenge: X402Challenge, matches: (network: string) => boolean): X402AcceptEntry | null;
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Durable spend store — the pluggable seam that lets a client's budget SURVIVE a
|
|
466
|
+
* restart, mirroring the gate's replay-protection `isUsed`/`markUsed` hook.
|
|
467
|
+
*
|
|
468
|
+
* The {@link SpendLedger} is in-memory by default (the session IS the process). Pass
|
|
469
|
+
* a `SpendStore` to {@link PipRailClientOptions.spendStore} (or to
|
|
470
|
+
* `MultiChainPayer.fromWallets`) and the ledger HYDRATES from `load()` at
|
|
471
|
+
* construction and `append()`s every settled payment — so `maxTotal`,
|
|
472
|
+
* `maxTotalPerDenom`, and the payment-count caps resume where they left off after a
|
|
473
|
+
* crash or redeploy, with NO PipRail backend (you own the store, exactly like the
|
|
474
|
+
* replay set).
|
|
475
|
+
*
|
|
476
|
+
* Contract:
|
|
477
|
+
* - `load()` is read ONCE, synchronously, at ledger construction (the log is small
|
|
478
|
+
* — one line per payment). Return `[]` for a fresh store.
|
|
479
|
+
* - `append(record)` persists ONE settled payment. It is called on the hot path, so
|
|
480
|
+
* it MUST NOT throw and SHOULD NOT block (ERRORS.md §: store I/O never throws — a
|
|
481
|
+
* failed append is swallowed so a disk hiccup can't abort a confirmed payment).
|
|
482
|
+
* - Round-trip the WHOLE `SpendRecord` (incl. `decimals` + `denom`) so totals and
|
|
483
|
+
* the grand-total rebuild exactly on reload — the built-in stores below do.
|
|
484
|
+
*
|
|
485
|
+
* PURE + browser-safe: this module has zero Node/chain imports. The Node-only
|
|
486
|
+
* {@link fileSpendStore} (a one-line local JSONL log) lives in `@piprail/sdk/node`.
|
|
487
|
+
*/
|
|
488
|
+
|
|
489
|
+
interface SpendStore {
|
|
490
|
+
/** Hydrate the ledger at construction — every previously-settled payment, in order.
|
|
491
|
+
* Read once, synchronously. Return `[]` for a fresh store. */
|
|
492
|
+
load(): SpendRecord[];
|
|
493
|
+
/** Persist one settled payment. MUST NOT throw (failures are swallowed by the ledger). */
|
|
494
|
+
append(record: SpendRecord): void;
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* An in-memory {@link SpendStore} — useful for tests and for sharing a seed across
|
|
498
|
+
* clients in one process. Not durable (it's the default behaviour made explicit);
|
|
499
|
+
* for restart-survival use `fileSpendStore` from `@piprail/sdk/node` or your own.
|
|
500
|
+
*/
|
|
501
|
+
declare function memorySpendStore(seed?: SpendRecord[]): SpendStore;
|
|
502
|
+
|
|
503
|
+
interface SpendRecord {
|
|
504
|
+
url: string;
|
|
505
|
+
host: string;
|
|
506
|
+
network: Caip2;
|
|
507
|
+
asset: string;
|
|
508
|
+
/** Base units paid (already scaled by decimals). */
|
|
509
|
+
amountBase: string;
|
|
510
|
+
/** Human-readable amount, e.g. '0.05'. */
|
|
511
|
+
amountFormatted: string;
|
|
512
|
+
symbol?: string;
|
|
513
|
+
/** TRUE token decimals. Carried on the record so a {@link SpendStore} can rebuild
|
|
514
|
+
* exact totals + the grand total on reload (the client stamps it on every settle). */
|
|
515
|
+
decimals?: number;
|
|
516
|
+
/** The DENOMINATION this payment counts toward in the cross-token grand total
|
|
517
|
+
* (e.g. `'USD'`), or absent for a token with no denomination. Stamped by the
|
|
518
|
+
* client from the policy at settle time so it round-trips through persistence. */
|
|
519
|
+
denom?: string;
|
|
520
|
+
/** Proof ref (EVM tx hash, Solana signature, TON locator, Stellar tx hash). */
|
|
521
|
+
ref: string;
|
|
522
|
+
/** ISO timestamp of settlement. */
|
|
523
|
+
at: string;
|
|
524
|
+
}
|
|
525
|
+
interface SpendAssetTotal {
|
|
526
|
+
network: Caip2;
|
|
527
|
+
asset: string;
|
|
528
|
+
symbol?: string;
|
|
529
|
+
decimals: number;
|
|
530
|
+
totalBase: string;
|
|
531
|
+
totalFormatted: string;
|
|
532
|
+
count: number;
|
|
533
|
+
}
|
|
534
|
+
/** Cumulative spend in one DENOMINATION (a unit of account), summed across every
|
|
535
|
+
* token of that denomination and every chain — the cross-token grand total. */
|
|
536
|
+
interface SpendDenomTotal {
|
|
537
|
+
/** The denomination, e.g. `'USD'`. */
|
|
538
|
+
denom: string;
|
|
539
|
+
/** Total spent, scaled to {@link DENOM_PRECISION} (the accumulator's base), as a string. */
|
|
540
|
+
totalScaled: string;
|
|
541
|
+
/** Human-readable denomination total, e.g. '12.34'. */
|
|
542
|
+
totalFormatted: string;
|
|
543
|
+
/** Number of payments (across all tokens + chains) that contributed to this denom. */
|
|
544
|
+
count: number;
|
|
545
|
+
}
|
|
546
|
+
interface SpendSummary {
|
|
547
|
+
/** Total number of settled payments (across every chain + token). */
|
|
548
|
+
count: number;
|
|
549
|
+
/** Cumulative spend per distinct (network, asset). */
|
|
550
|
+
byAsset: SpendAssetTotal[];
|
|
551
|
+
/** Cumulative spend per DENOMINATION — the cross-token grand total (empty when no
|
|
552
|
+
* payment carried a denomination). NEVER a price-converted figure: a sum of tokens
|
|
553
|
+
* grouped as one unit, each 1:1. */
|
|
554
|
+
byDenom: SpendDenomTotal[];
|
|
555
|
+
/** Every settled payment, in order. */
|
|
556
|
+
records: SpendRecord[];
|
|
557
|
+
}
|
|
558
|
+
declare class SpendLedger {
|
|
559
|
+
private readonly records;
|
|
560
|
+
private readonly buckets;
|
|
561
|
+
/** Per-denomination running total, scaled to {@link DENOM_PRECISION}. Keyed by the
|
|
562
|
+
* UPPERCASE denomination so lookups are case-insensitive. */
|
|
563
|
+
private readonly denomTotals;
|
|
564
|
+
/** Threshold keys already warned (`warnAtFraction` fires once per crossing per cap).
|
|
565
|
+
* Lives on the LEDGER — not the client — so clients SHARING one (a cross-chain
|
|
566
|
+
* MultiChainPayer) dedupe together: a denomination/count threshold fires once across the
|
|
567
|
+
* whole shared budget, not once per chain. */
|
|
568
|
+
private readonly warned;
|
|
569
|
+
private readonly store?;
|
|
570
|
+
/**
|
|
571
|
+
* Session clock origin (epoch-ms) — process/session start = ledger
|
|
572
|
+
* construction. In-memory; a new process is a new session. The client reads it
|
|
573
|
+
* to compute the `ttlSeconds` deadline and the rolling-window slice.
|
|
574
|
+
*/
|
|
575
|
+
readonly sessionStart: number;
|
|
576
|
+
/**
|
|
577
|
+
* @param store Optional durable {@link SpendStore}. When supplied, the ledger
|
|
578
|
+
* HYDRATES from `store.load()` here (so prior spend resumes after a restart) and
|
|
579
|
+
* `append()`s every settled payment. A throwing/absent store fails SAFE to an
|
|
580
|
+
* empty in-memory ledger — it never blocks construction (ERRORS.md: never throw).
|
|
581
|
+
*/
|
|
582
|
+
constructor(store?: SpendStore);
|
|
583
|
+
/**
|
|
584
|
+
* A record is safe to tally iff its `amountBase` is a non-negative integer STRING and its
|
|
585
|
+
* `decimals` is an integer in `[0, MAX_DECIMALS]`. The live `record()` path always passes
|
|
586
|
+
* (the client validated the quote), but a hydrated record comes from an UNTRUSTED store
|
|
587
|
+
* (a tampered/corrupt/future-version JSONL line), so we gate it here — a bad record is
|
|
588
|
+
* dropped rather than allowed to throw `BigInt(...)`/`formatUnits(...)` later and brick a
|
|
589
|
+
* read or the constructor.
|
|
590
|
+
*/
|
|
591
|
+
private isTallyable;
|
|
592
|
+
/** Apply a record to the in-memory tallies (records + per-asset bucket + denom total).
|
|
593
|
+
* Shared by {@link record} and constructor hydration; does NOT persist. Returns the
|
|
594
|
+
* stored record, or `null` when the record is corrupt and was skipped. */
|
|
595
|
+
private ingest;
|
|
596
|
+
/** Record a settled payment. `decimals` is the TRUE token decimals (for the
|
|
597
|
+
* per-asset running total + the formatted summary). `denom` is the unit-of-account
|
|
598
|
+
* the payment counts toward in the grand total (or omit for none). Persists to the
|
|
599
|
+
* {@link SpendStore} when one is configured (a failed append never throws). */
|
|
600
|
+
record(r: SpendRecord, decimals: number, denom?: string): void;
|
|
601
|
+
/** Running total (base units) already spent on this (network, asset). */
|
|
602
|
+
totalFor(network: string, asset: string): bigint;
|
|
603
|
+
/**
|
|
604
|
+
* Running grand total for a DENOMINATION, scaled to {@link DENOM_PRECISION} (so
|
|
605
|
+
* tokens of different decimals add up exactly). Summed across every token of that
|
|
606
|
+
* denomination and every chain this ledger has seen. Powers `maxTotalPerDenom`.
|
|
607
|
+
* `0n` for a denomination never spent on. Case-insensitive.
|
|
608
|
+
*/
|
|
609
|
+
totalForDenom(denom: string): bigint;
|
|
610
|
+
/** Total number of settled payments (across every chain + token). Powers `maxPayments`. */
|
|
611
|
+
count(): number;
|
|
612
|
+
/** Mark a `warnAtFraction` threshold key as fired; returns `true` the FIRST time (so the
|
|
613
|
+
* caller emits the `budget-threshold` event once) and `false` thereafter. Shared across
|
|
614
|
+
* every client on this ledger, so a cross-chain threshold fires once for the whole budget. */
|
|
615
|
+
markWarned(key: string): boolean;
|
|
616
|
+
/**
|
|
617
|
+
* Number of settled payments whose `at` (ISO) is at or after `sinceMs` (epoch-ms),
|
|
618
|
+
* across every chain + token. Backs the rolling payment-count cap
|
|
619
|
+
* (`maxPaymentsPerWindow`, `sinceMs = now - windowSeconds*1000`). Linear scan —
|
|
620
|
+
* negligible at agent-session cardinality and only when a window count cap is set.
|
|
621
|
+
*/
|
|
622
|
+
countSince(sinceMs: number): number;
|
|
623
|
+
/**
|
|
624
|
+
* Sum of base-unit amounts for (network, asset) whose record `at` (ISO
|
|
625
|
+
* timestamp) is at or after `sinceMs` (epoch-ms). Backs the rolling window
|
|
626
|
+
* (`sinceMs = now - windowSeconds*1000`). A linear scan of `records` —
|
|
627
|
+
* agent-session cardinality is small (tens), and it only runs when a window
|
|
628
|
+
* policy is set, so it's negligible against the network round-trip.
|
|
629
|
+
*/
|
|
630
|
+
totalSince(network: string, asset: string, sinceMs: number): bigint;
|
|
631
|
+
/**
|
|
632
|
+
* The per-(network, asset) buckets, as read-only tuples — `network`, `asset`,
|
|
633
|
+
* `symbol`, the TRUE `decimals` (frozen from the first record), and the running
|
|
634
|
+
* `totalBase`. Lets the client compose a budget view WITHOUT coupling the ledger
|
|
635
|
+
* to the policy (the cap math lives in the client). Decimals only exist for a
|
|
636
|
+
* pair once it's been spent on — a never-spent pair simply isn't a bucket.
|
|
637
|
+
*/
|
|
638
|
+
assetBuckets(): {
|
|
639
|
+
network: Caip2;
|
|
640
|
+
asset: string;
|
|
641
|
+
symbol?: string;
|
|
642
|
+
decimals: number;
|
|
643
|
+
totalBase: bigint;
|
|
644
|
+
}[];
|
|
645
|
+
/**
|
|
646
|
+
* The per-denomination grand totals, as read-only tuples — `denom` and the running
|
|
647
|
+
* `totalScaled` (at {@link DENOM_PRECISION}). Lets the client compose the grand-total
|
|
648
|
+
* budget view; the cap math lives in the client. A never-spent denomination is absent.
|
|
649
|
+
*/
|
|
650
|
+
denomBuckets(): {
|
|
651
|
+
denom: string;
|
|
652
|
+
totalScaled: bigint;
|
|
653
|
+
}[];
|
|
654
|
+
/** An immutable snapshot of all spend so far. */
|
|
655
|
+
summary(): SpendSummary;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
export { type AddressId as A, buildSignatureHeader as B, type Caip2 as C, memorySpendStore as D, type ExactAuthorizationWire as E, parseChallenge as F, parseExactPaymentHeader as G, HEADER_REQUIRED as H, parseReceipt as I, parseSettleResponse as J, parseSignatureHeader as K, pickAccept as L, type PaidReceipt as P, type SettleOutcome as S, type VerifyErrorCode as V, type X402AcceptEntry as X, type AssetId as a, type ExactPaymentPayload as b, type ExactPaymentPayloadAny as c, HEADER_RESPONSE as d, HEADER_RESPONSE_V1 as e, HEADER_SIGNATURE as f, HEADER_SIGNATURE_V1 as g, type ParsedExactPayment as h, type Permit2Authorization as i, type Permit2PaymentPayload as j, type SpendAssetTotal as k, type SpendDenomTotal as l, SpendLedger as m, type SpendRecord as n, type SpendStore as o, type SpendSummary as p, type VerifyResult as q, type X402AnyAccept as r, type X402Challenge as s, type X402ExactAcceptEntry as t, type X402PaymentSignature as u, type X402Receipt as v, type X402ResourceObject as w, buildChallengeHeader as x, buildExactSignatureHeader as y, buildReceiptHeader as z };
|