@piprail/sdk 2.15.1 → 2.16.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 +188 -1
- package/README.md +1 -1
- package/dist/{algorand-UF7BLBFN.js → algorand-25FMBCT3.js} +12 -3
- package/dist/{algorand-XGSWDMCZ.cjs → algorand-Q3TUQLPK.cjs} +17 -8
- package/dist/{aptos-KDLX42CR.js → aptos-SBV6SGDP.js} +2 -2
- package/dist/{aptos-J2QSWHTO.cjs → aptos-VBJONBFY.cjs} +5 -5
- package/dist/chunk-2CX7XRZK.js +649 -0
- package/dist/chunk-C52H5TYB.js +474 -0
- package/dist/chunk-OXEFPLZA.cjs +474 -0
- package/dist/chunk-V2IJ5HUW.cjs +649 -0
- package/dist/index.cjs +355 -1181
- package/dist/index.d.cts +39 -6
- package/dist/index.d.ts +39 -6
- package/dist/index.js +171 -997
- package/dist/{ledger-uFtXlIHY.d.cts → ledger-Crc1bZox.d.cts} +164 -10
- package/dist/{ledger-uFtXlIHY.d.ts → ledger-Crc1bZox.d.ts} +164 -10
- package/dist/node.d.cts +2 -2
- package/dist/node.d.ts +2 -2
- package/dist/{solana-S2T3JNR7.cjs → solana-AI2G7V33.cjs} +42 -21
- package/dist/{solana-WO2G7WWZ.js → solana-HTKDRTD3.js} +31 -10
- package/dist/{xrpl-6B2XOXGC.js → xrpl-RUOB37QH.js} +282 -4
- package/dist/{xrpl-VOUXIUYD.cjs → xrpl-SVVS445B.cjs} +292 -14
- package/package.json +1 -1
|
@@ -75,8 +75,28 @@ interface X402ExactAcceptEntry {
|
|
|
75
75
|
asset: AssetId;
|
|
76
76
|
payTo: AddressId;
|
|
77
77
|
maxTimeoutSeconds: number;
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
/**
|
|
79
|
+
* The network id EXACTLY as an x402 **v1** server wrote it (a slug like `'base'`),
|
|
80
|
+
* preserved by {@link normalizeV1Challenge} because `network` above is canonicalised to
|
|
81
|
+
* CAIP-2 for matching while a v1 server string-compares the slug it sent. Internal to the
|
|
82
|
+
* v1 compat path — absent on every v2 rail, and STRIPPED from every outgoing `accepted`
|
|
83
|
+
* echo by `withoutWireNetwork`, since the merchant never published this key.
|
|
84
|
+
*/
|
|
85
|
+
wireNetwork?: string;
|
|
86
|
+
/**
|
|
87
|
+
* Scheme-defined extras. **OPTIONAL when PARSING a foreign 402** — the exact-EVM scheme
|
|
88
|
+
* makes every `extra` key optional (`assetTransferMethod` defaults to `'eip3009'`), and the
|
|
89
|
+
* SVM/Algorand/Aptos/NEAR/Hedera schemes define no `assetTransferMethod` at all, so a
|
|
90
|
+
* conformant rail may ship `extra: {}` or omit the block entirely. A PipRail **gate** always
|
|
91
|
+
* emits it. Every read on the buyer path must optional-chain.
|
|
92
|
+
*/
|
|
93
|
+
extra?: {
|
|
94
|
+
/** The exact transfer method. **OPTIONAL** — `scheme_exact_evm.md`: *"If no
|
|
95
|
+
* `assetTransferMethod` is specified in `PaymentRequired.extra`, clients should default
|
|
96
|
+
* to `\"eip3009\"`"* (and only the non-default methods make it required). The SVM,
|
|
97
|
+
* Algorand, Aptos, NEAR and Hedera schemes never define this key. Read it through
|
|
98
|
+
* {@link exactTransferMethod}, never bare — 91% of the deployed x402 web omits it.
|
|
99
|
+
* EVM: `'eip3009'` for tokens with native
|
|
80
100
|
* `transferWithAuthorization`, or `'permit2'` for tokens WITHOUT it (e.g.
|
|
81
101
|
* Binance-Peg USDC on BNB) — the payer signs a Permit2 witness transfer whose
|
|
82
102
|
* `spender` is the canonical x402ExactPermit2Proxy and whose `witness.to` binds the
|
|
@@ -92,13 +112,46 @@ interface X402ExactAcceptEntry {
|
|
|
92
112
|
* authorizing exactly one NEP-141 `ft_transfer` to `payTo` (per `scheme_exact_near.md`); a
|
|
93
113
|
* facilitator-selected relayer (`feePayer` below) prepays gas + the 1 yoctoNEAR and submits, so
|
|
94
114
|
* the buyer holds zero NEAR. PipRail self-settles ALL. */
|
|
95
|
-
assetTransferMethod
|
|
115
|
+
assetTransferMethod?: 'eip3009' | 'permit2'
|
|
96
116
|
/** A FOREIGN-dialect alias for `'permit2'` — Binance's x402 ("b402") facilitator labels its
|
|
97
117
|
* EVM-Permit2 exact rail `'permit2-exact'` (the coinbase/x402 spec uses bare `'permit2'`).
|
|
98
118
|
* PipRail EMITS only `'permit2'`; it TOLERATES `'permit2-exact'` inbound so the buyer pays a
|
|
99
119
|
* Binance-issued 402 (the buyer treats the two as one rail). NB: settlement still requires the
|
|
100
120
|
* rail to bind PipRail's canonical x402ExactPermit2Proxy — see the buyer in drivers/evm. */
|
|
101
|
-
| 'permit2-exact' | 'svm' | 'algorand' | 'aptos' | 'near'
|
|
121
|
+
| 'permit2-exact' | 'svm' | 'algorand' | 'aptos' | 'near'
|
|
122
|
+
/** **XRPL** — the ledger has exactly ONE way to move value (a `Payment`), so
|
|
123
|
+
* `scheme_exact_xrpl.md` spends this field on SEQUENCING instead of mechanism.
|
|
124
|
+
* `'sequence'` (the DEFAULT, and what all 1,732 live XRPL rails mean by omitting it) uses
|
|
125
|
+
* the payer's account sequence; `'ticketSequence'` sets `Sequence: 0` and supplies a
|
|
126
|
+
* pre-minted `TicketSequence`, letting a payer sign several payments that settle out of
|
|
127
|
+
* order. */
|
|
128
|
+
| 'sequence' | 'ticketSequence';
|
|
129
|
+
/** **XRPL, REQUIRED by the scheme — and absent from 100% of live rails.** The spec says it
|
|
130
|
+
* "must be false" (XRPL charges the fee to the transaction's own `Account`, so the payer
|
|
131
|
+
* always pays). Read it as *false unless present*: REQUIRING it would reject the entire
|
|
132
|
+
* deployed XRPL x402 web, which is exactly the bug class `assetTransferMethod` already caused
|
|
133
|
+
* once. A rail that explicitly says `true` is refused — we cannot honour a sponsor here. */
|
|
134
|
+
areFeesSponsored?: boolean;
|
|
135
|
+
/** **XRPL** — the issuer's classic address for an IOU rail (RLUSD and friends). Required by the
|
|
136
|
+
* scheme for issued currencies, absent for native XRP; present on 869 of the 1,732 live rails,
|
|
137
|
+
* which is precisely the IOU half. Also the discriminator the buyer uses to pick the
|
|
138
|
+
* issued-currency `Amount` object over a bare drops string. */
|
|
139
|
+
issuer?: string;
|
|
140
|
+
/** **XRPL, OPTIONAL** — an opaque invoice identifier. When present the buyer MUST set the
|
|
141
|
+
* transaction's `InvoiceID` to its **SHA-256**, as 32-byte hex; that hash is the challenge
|
|
142
|
+
* binding on this rail (there is no memo — the scheme has facilitators REJECT `Memos`).
|
|
143
|
+
* Present on 1,732 of 1,732 live rails, so treat it as always-on in practice. */
|
|
144
|
+
invoiceId?: string;
|
|
145
|
+
/** **XRPL** — a vendor correlation tag, copied verbatim into the transaction's `SourceTag`.
|
|
146
|
+
* NOT in `scheme_exact_xrpl.md`'s extra table, but present on **1,728 of the 1,732** live XRPL
|
|
147
|
+
* rails: it is how the deployed vendors match a payment back to their own quote. Mirrored
|
|
148
|
+
* because it costs nothing and omitting it is a plausible reason a merchant refuses. */
|
|
149
|
+
sourceTag?: number;
|
|
150
|
+
/** **XRPL, OPTIONAL** — a destination tag the buyer MUST copy verbatim into the transaction
|
|
151
|
+
* when the rail states one (hosted/exchange accounts route deposits by it). Never invented
|
|
152
|
+
* when absent: unlike the onchain-proof path, which derives a tag from the nonce, the exact
|
|
153
|
+
* rail sets `DestinationTag` only if the merchant asked for one. */
|
|
154
|
+
destinationTag?: number;
|
|
102
155
|
/** EIP-712 domain name of the token. OPTIONAL per the exact-EVM scheme (only
|
|
103
156
|
* `assetTransferMethod` is required) — a foreign rail may omit it. NEVER assumed
|
|
104
157
|
* from the symbol (USDC's on-chain name() is "USD Coin", not "USDC"); a PipRail gate
|
|
@@ -132,6 +185,42 @@ interface X402ExactAcceptEntry {
|
|
|
132
185
|
symbol?: string;
|
|
133
186
|
};
|
|
134
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* The transfer method an `exact` rail uses when it names none.
|
|
190
|
+
*
|
|
191
|
+
* `scheme_exact_evm.md` §0: *"If no `assetTransferMethod` is specified in
|
|
192
|
+
* `PaymentRequired.extra`, clients should default to `"eip3009"`."* §1 restates it per-method:
|
|
193
|
+
* `eip3009` is *"optional in `PaymentRequired`, default"*, while `permit2` and `erc7710` are
|
|
194
|
+
* *"required"*. So an absent marker is not a malformed rail — it is the common case (91% of the
|
|
195
|
+
* deployed web) and it means EIP-3009.
|
|
196
|
+
*/
|
|
197
|
+
declare const DEFAULT_EXACT_TRANSFER_METHOD: "eip3009";
|
|
198
|
+
/**
|
|
199
|
+
* Every `assetTransferMethod` a PipRail buyer can actually sign, across all families.
|
|
200
|
+
*
|
|
201
|
+
* Used to SKIP a rail that names a method we don't implement (the spec's `erc7710`, or any
|
|
202
|
+
* future one) rather than sign an EIP-3009 authorization a facilitator built for a different
|
|
203
|
+
* mechanism and will reject. An **absent** marker is not "unknown" — see
|
|
204
|
+
* {@link DEFAULT_EXACT_TRANSFER_METHOD}. Family routing stays in each driver's `payExact`;
|
|
205
|
+
* this set only answers "could any driver of ours settle this?".
|
|
206
|
+
*/
|
|
207
|
+
declare const KNOWN_EXACT_TRANSFER_METHODS: ReadonlySet<string>;
|
|
208
|
+
/**
|
|
209
|
+
* The effective transfer method of an `exact` rail: what it names, or the default when it names
|
|
210
|
+
* nothing. THE ONLY sanctioned way to read `extra.assetTransferMethod` — reading it bare is how
|
|
211
|
+
* the buyer came to reject 91% of the x402 web.
|
|
212
|
+
*
|
|
213
|
+
* Pass `family` to get the right default off-EVM: a Solana rail that names nothing means `svm`,
|
|
214
|
+
* not `eip3009`. Without it the EVM default is assumed (correct for the settleability check,
|
|
215
|
+
* since every family's own literal is in {@link KNOWN_EXACT_TRANSFER_METHODS} anyway).
|
|
216
|
+
*/
|
|
217
|
+
declare function exactTransferMethod(accept: X402ExactAcceptEntry, family?: string): string;
|
|
218
|
+
/**
|
|
219
|
+
* Can any PipRail driver settle this rail's transfer method? True when the rail names a
|
|
220
|
+
* method we implement, AND when it names none (the spec default `eip3009`). False only for a
|
|
221
|
+
* method we don't implement — the rail is then skipped at gather rather than mis-signed.
|
|
222
|
+
*/
|
|
223
|
+
declare function isSettleableExactMethod(accept: X402ExactAcceptEntry): boolean;
|
|
135
224
|
/**
|
|
136
225
|
* A standard x402 `upto` rail (EVM / Permit2) — variable-amount / metered billing.
|
|
137
226
|
* The buyer signs a Permit2 `PermitWitnessTransferFrom` authorization for `amount`
|
|
@@ -181,7 +270,13 @@ interface X402UptoAcceptEntry {
|
|
|
181
270
|
* rail, or a standard `upto` (metered) rail. */
|
|
182
271
|
type X402AnyAccept = X402AcceptEntry | X402ExactAcceptEntry | X402UptoAcceptEntry;
|
|
183
272
|
interface X402Challenge {
|
|
184
|
-
|
|
273
|
+
/**
|
|
274
|
+
* `2` for every challenge PipRail EMITS. `1` appears only on the PARSE side, when
|
|
275
|
+
* {@link normalizeV1Challenge} has lifted a still-deployed v1 server's body into this
|
|
276
|
+
* shape — the buyer must then answer on the v1 wire (`X-PAYMENT`, flat payload). See the
|
|
277
|
+
* version-posture note above {@link HEADER_SIGNATURE_V1}.
|
|
278
|
+
*/
|
|
279
|
+
x402Version: 1 | 2;
|
|
185
280
|
/**
|
|
186
281
|
* Optional human-readable reason (v2 `error?: string`). PipRail EMITS it only on a
|
|
187
282
|
* rejected-proof re-challenge (omitted on a fresh challenge). Typed to also tolerate
|
|
@@ -361,10 +456,25 @@ interface ExactNearPaymentPayload {
|
|
|
361
456
|
/** Base64 of the Borsh-encoded NEP-366 `SignedDelegateAction` (one `ft_transfer`). */
|
|
362
457
|
signedDelegateAction: string;
|
|
363
458
|
}
|
|
459
|
+
/**
|
|
460
|
+
* The `payload` a client sends for the **XRPL `exact`** variant, per `scheme_exact_xrpl.md`:
|
|
461
|
+
* a **fully signed** XRPL `Payment` transaction, hex-encoded, that the resource server (or its
|
|
462
|
+
* facilitator) submits. The signed blob IS the proof — there is no separate authorization object.
|
|
463
|
+
*
|
|
464
|
+
* XRPL is the one family where **the payer pays the network fee**: the fee is a field inside the
|
|
465
|
+
* signed transaction and the ledger charges it to `Account`. So there is no sponsor, no fee-payer
|
|
466
|
+
* co-signature, and no fee-drain guard to write — the buyer needs XRP for the amount *and* the fee.
|
|
467
|
+
* That also means the buyer signs something immediately submittable, so `LastLedgerSequence` is
|
|
468
|
+
* mandatory: it is the only thing bounding how long the merchant may sit on it.
|
|
469
|
+
*/
|
|
470
|
+
interface ExactXrplPaymentPayload {
|
|
471
|
+
/** Hex-encoded, fully signed XRPL `Payment` transaction blob. */
|
|
472
|
+
signedTxBlob: string;
|
|
473
|
+
}
|
|
364
474
|
/** Any `exact`-rail payload shape — EIP-3009 (`authorization`), Permit2 (`permit2Authorization`),
|
|
365
|
-
* SVM (`transaction`), Algorand (`paymentGroup`), Aptos (`transaction` + `senderAuth`),
|
|
366
|
-
* (`signedDelegateAction`). */
|
|
367
|
-
type ExactPaymentPayloadAny = ExactPaymentPayload | Permit2PaymentPayload | ExactSvmPaymentPayload | ExactAlgorandPaymentPayload | ExactAptosPaymentPayload | ExactNearPaymentPayload;
|
|
475
|
+
* SVM (`transaction`), Algorand (`paymentGroup`), Aptos (`transaction` + `senderAuth`), NEAR
|
|
476
|
+
* (`signedDelegateAction`), or XRPL (`signedTxBlob`). */
|
|
477
|
+
type ExactPaymentPayloadAny = ExactPaymentPayload | Permit2PaymentPayload | ExactSvmPaymentPayload | ExactAlgorandPaymentPayload | ExactAptosPaymentPayload | ExactNearPaymentPayload | ExactXrplPaymentPayload;
|
|
368
478
|
interface ParsedExactBase {
|
|
369
479
|
x402Version: number;
|
|
370
480
|
/** The client's claimed network (slug or CAIP-2) — for matching, not trust. */
|
|
@@ -385,7 +495,9 @@ interface ParsedExactBase {
|
|
|
385
495
|
* `'svm'` → {@link ExactSvmPaymentPayload} (`transaction`), `'algorand'` →
|
|
386
496
|
* {@link ExactAlgorandPaymentPayload} (`paymentGroup`); `'aptos'` →
|
|
387
497
|
* {@link ExactAptosPaymentPayload} (`transaction` + `senderAuth`); `'near'` →
|
|
388
|
-
* {@link ExactNearPaymentPayload} (`signedDelegateAction`)
|
|
498
|
+
* {@link ExactNearPaymentPayload} (`signedDelegateAction`); `'sequence'` / `'ticketSequence'` →
|
|
499
|
+
* {@link ExactXrplPaymentPayload} (`signedTxBlob`) — XRPL is the one family whose method literal
|
|
500
|
+
* names the SEQUENCING strategy rather than a transfer mechanism, because it has only one.
|
|
389
501
|
*/
|
|
390
502
|
type ParsedExactPayment = (ParsedExactBase & {
|
|
391
503
|
method: 'eip3009';
|
|
@@ -405,6 +517,12 @@ type ParsedExactPayment = (ParsedExactBase & {
|
|
|
405
517
|
}) | (ParsedExactBase & {
|
|
406
518
|
method: 'near';
|
|
407
519
|
payload: ExactNearPaymentPayload;
|
|
520
|
+
}) | (ParsedExactBase & {
|
|
521
|
+
method: 'sequence';
|
|
522
|
+
payload: ExactXrplPaymentPayload;
|
|
523
|
+
}) | (ParsedExactBase & {
|
|
524
|
+
method: 'ticketSequence';
|
|
525
|
+
payload: ExactXrplPaymentPayload;
|
|
408
526
|
});
|
|
409
527
|
/**
|
|
410
528
|
* What {@link parseUptoPaymentHeader} extracts from an inbound `upto` payment — the
|
|
@@ -648,6 +766,25 @@ declare function buildUptoSignatureHeader(input: {
|
|
|
648
766
|
accepted: X402UptoAcceptEntry;
|
|
649
767
|
payload: Permit2UptoPaymentPayload;
|
|
650
768
|
}): string;
|
|
769
|
+
/**
|
|
770
|
+
* Build the **v1** `X-PAYMENT` header value — the flat, pre-v2 payload shape
|
|
771
|
+
* `{ x402Version: 1, scheme, network, payload }`, base64-JSON.
|
|
772
|
+
*
|
|
773
|
+
* This is the `encodeXPaymentHeader` utility the version-posture note above has always
|
|
774
|
+
* described; it had never been written, so the buyer could parse nothing from a v1 server and
|
|
775
|
+
* could answer nothing either. Needed because v2 moved the header `X-PAYMENT` →
|
|
776
|
+
* `PAYMENT-SIGNATURE` and reshaped the payload: a v1 server ignores `PAYMENT-SIGNATURE`
|
|
777
|
+
* entirely (verified live — it just re-challenges) and reads only `X-PAYMENT`.
|
|
778
|
+
*
|
|
779
|
+
* `network` MUST be the slug the v1 server itself sent (`X402ExactAcceptEntry.wireNetwork`),
|
|
780
|
+
* not our canonical CAIP-2: v1 verifiers string-compare it against their own requirement.
|
|
781
|
+
* There is no `accepted` echo in v1 — the chosen rail is identified by these two flat fields.
|
|
782
|
+
*/
|
|
783
|
+
declare function buildV1PaymentHeader(input: {
|
|
784
|
+
scheme: string;
|
|
785
|
+
network: string;
|
|
786
|
+
payload: unknown;
|
|
787
|
+
}): string;
|
|
651
788
|
/**
|
|
652
789
|
* Parse the PAYMENT-REQUIRED challenge from a 402 response. Prefers the
|
|
653
790
|
* `payment-required` header, falls back to the JSON body.
|
|
@@ -747,6 +884,23 @@ declare function parseUptoPaymentHeader(value: string): ParsedUptoPayment | null
|
|
|
747
884
|
* base64 wrapper, byte-identical to before this split on the HTTP path.
|
|
748
885
|
*/
|
|
749
886
|
declare function parseUptoObject(parsed: unknown): ParsedUptoPayment | null;
|
|
887
|
+
/**
|
|
888
|
+
* Lift an x402 **v1** challenge body into the internal {@link X402Challenge} shape, so the
|
|
889
|
+
* whole buyer path downstream of `parseChallenge` stays v2-only and version-blind.
|
|
890
|
+
*
|
|
891
|
+
* Four v1→v2 skews are absorbed, and nothing else is touched (unknown keys ride along
|
|
892
|
+
* verbatim, so a facilitator's extras survive):
|
|
893
|
+
* 1. `maxAmountRequired` → `amount` (v2's rename). An accept that already has `amount` keeps it.
|
|
894
|
+
* 2. slug `network` (`'base'`) → CAIP-2 (`'eip155:8453'`) so the gather's `supports()` matches,
|
|
895
|
+
* with the ORIGINAL preserved on {@link X402ExactAcceptEntry.wireNetwork} because the v1
|
|
896
|
+
* server string-compares the slug it sent when we echo it back.
|
|
897
|
+
* 3. per-accept `resource` string → a top-level `resource` object (first accept that has one).
|
|
898
|
+
* 4. `x402Version: 1` is KEPT on the result — it is what tells `payExactRail` to answer on the
|
|
899
|
+
* v1 wire (`X-PAYMENT`, flat payload) instead of v2's `PAYMENT-SIGNATURE`.
|
|
900
|
+
*
|
|
901
|
+
* Pure: never mutates `body`, never throws (a caller passing a non-v1 value gets `null`).
|
|
902
|
+
*/
|
|
903
|
+
declare function normalizeV1Challenge(body: unknown): X402Challenge | null;
|
|
750
904
|
/**
|
|
751
905
|
* Pick the first accepts[] entry on the `onchain-proof` scheme whose network
|
|
752
906
|
* satisfies `matches` (any chain family). Returns null if none match.
|
|
@@ -958,4 +1112,4 @@ declare class SpendLedger {
|
|
|
958
1112
|
summary(): SpendSummary;
|
|
959
1113
|
}
|
|
960
1114
|
|
|
961
|
-
export {
|
|
1115
|
+
export { normalizeV1Challenge as $, type AddressId as A, type X402ExactAcceptEntry as B, type Caip2 as C, DEFAULT_EXACT_TRANSFER_METHOD as D, EXT_OFFER_RECEIPT as E, type X402PaymentSignature as F, type X402Receipt as G, HEADER_REQUIRED as H, type X402ResourceObject as I, type X402UptoAcceptEntry as J, KNOWN_EXACT_TRANSFER_METHODS as K, buildChallengeHeader as L, buildExactSignatureHeader as M, buildPaymentIdentifierAdvertisement as N, buildReceiptExtension as O, type PaidReceipt as P, buildReceiptHeader as Q, buildSignatureHeader as R, type SettleOutcome as S, buildUptoSignatureHeader as T, buildV1PaymentHeader as U, type VerifyErrorCode as V, decodeBase64Json as W, type X402AcceptEntry as X, exactTransferMethod as Y, isSettleableExactMethod as Z, memorySpendStore as _, type AssetId as a, parseChallenge as a0, parseExactObject as a1, parseExactPaymentHeader as a2, parseReceipt as a3, parseReceiptExtension as a4, parseSettleResponse as a5, parseSignatureHeader as a6, parseSignatureObject as a7, parseUptoObject as a8, parseUptoPaymentHeader as a9, pickAccept as aa, readPaymentIdentifier as ab, EXT_PAYMENT_IDENTIFIER as b, type ExactAuthorizationWire as c, type ExactPaymentPayload as d, type ExactPaymentPayloadAny as e, HEADER_RESPONSE as f, HEADER_RESPONSE_V1 as g, HEADER_SIGNATURE as h, HEADER_SIGNATURE_V1 as i, type ParsedExactPayment as j, type ParsedUptoPayment as k, type Permit2Authorization as l, type Permit2PaymentPayload as m, type Permit2UptoAuthorization as n, type Permit2UptoPaymentPayload as o, type PipRailReceipt as p, type SignedReceipt as q, type SpendAssetTotal as r, type SpendDenomTotal as s, SpendLedger as t, type SpendRecord as u, type SpendStore as v, type SpendSummary as w, type VerifyResult as x, type X402AnyAccept as y, type X402Challenge as z };
|
|
@@ -75,8 +75,28 @@ interface X402ExactAcceptEntry {
|
|
|
75
75
|
asset: AssetId;
|
|
76
76
|
payTo: AddressId;
|
|
77
77
|
maxTimeoutSeconds: number;
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
/**
|
|
79
|
+
* The network id EXACTLY as an x402 **v1** server wrote it (a slug like `'base'`),
|
|
80
|
+
* preserved by {@link normalizeV1Challenge} because `network` above is canonicalised to
|
|
81
|
+
* CAIP-2 for matching while a v1 server string-compares the slug it sent. Internal to the
|
|
82
|
+
* v1 compat path — absent on every v2 rail, and STRIPPED from every outgoing `accepted`
|
|
83
|
+
* echo by `withoutWireNetwork`, since the merchant never published this key.
|
|
84
|
+
*/
|
|
85
|
+
wireNetwork?: string;
|
|
86
|
+
/**
|
|
87
|
+
* Scheme-defined extras. **OPTIONAL when PARSING a foreign 402** — the exact-EVM scheme
|
|
88
|
+
* makes every `extra` key optional (`assetTransferMethod` defaults to `'eip3009'`), and the
|
|
89
|
+
* SVM/Algorand/Aptos/NEAR/Hedera schemes define no `assetTransferMethod` at all, so a
|
|
90
|
+
* conformant rail may ship `extra: {}` or omit the block entirely. A PipRail **gate** always
|
|
91
|
+
* emits it. Every read on the buyer path must optional-chain.
|
|
92
|
+
*/
|
|
93
|
+
extra?: {
|
|
94
|
+
/** The exact transfer method. **OPTIONAL** — `scheme_exact_evm.md`: *"If no
|
|
95
|
+
* `assetTransferMethod` is specified in `PaymentRequired.extra`, clients should default
|
|
96
|
+
* to `\"eip3009\"`"* (and only the non-default methods make it required). The SVM,
|
|
97
|
+
* Algorand, Aptos, NEAR and Hedera schemes never define this key. Read it through
|
|
98
|
+
* {@link exactTransferMethod}, never bare — 91% of the deployed x402 web omits it.
|
|
99
|
+
* EVM: `'eip3009'` for tokens with native
|
|
80
100
|
* `transferWithAuthorization`, or `'permit2'` for tokens WITHOUT it (e.g.
|
|
81
101
|
* Binance-Peg USDC on BNB) — the payer signs a Permit2 witness transfer whose
|
|
82
102
|
* `spender` is the canonical x402ExactPermit2Proxy and whose `witness.to` binds the
|
|
@@ -92,13 +112,46 @@ interface X402ExactAcceptEntry {
|
|
|
92
112
|
* authorizing exactly one NEP-141 `ft_transfer` to `payTo` (per `scheme_exact_near.md`); a
|
|
93
113
|
* facilitator-selected relayer (`feePayer` below) prepays gas + the 1 yoctoNEAR and submits, so
|
|
94
114
|
* the buyer holds zero NEAR. PipRail self-settles ALL. */
|
|
95
|
-
assetTransferMethod
|
|
115
|
+
assetTransferMethod?: 'eip3009' | 'permit2'
|
|
96
116
|
/** A FOREIGN-dialect alias for `'permit2'` — Binance's x402 ("b402") facilitator labels its
|
|
97
117
|
* EVM-Permit2 exact rail `'permit2-exact'` (the coinbase/x402 spec uses bare `'permit2'`).
|
|
98
118
|
* PipRail EMITS only `'permit2'`; it TOLERATES `'permit2-exact'` inbound so the buyer pays a
|
|
99
119
|
* Binance-issued 402 (the buyer treats the two as one rail). NB: settlement still requires the
|
|
100
120
|
* rail to bind PipRail's canonical x402ExactPermit2Proxy — see the buyer in drivers/evm. */
|
|
101
|
-
| 'permit2-exact' | 'svm' | 'algorand' | 'aptos' | 'near'
|
|
121
|
+
| 'permit2-exact' | 'svm' | 'algorand' | 'aptos' | 'near'
|
|
122
|
+
/** **XRPL** — the ledger has exactly ONE way to move value (a `Payment`), so
|
|
123
|
+
* `scheme_exact_xrpl.md` spends this field on SEQUENCING instead of mechanism.
|
|
124
|
+
* `'sequence'` (the DEFAULT, and what all 1,732 live XRPL rails mean by omitting it) uses
|
|
125
|
+
* the payer's account sequence; `'ticketSequence'` sets `Sequence: 0` and supplies a
|
|
126
|
+
* pre-minted `TicketSequence`, letting a payer sign several payments that settle out of
|
|
127
|
+
* order. */
|
|
128
|
+
| 'sequence' | 'ticketSequence';
|
|
129
|
+
/** **XRPL, REQUIRED by the scheme — and absent from 100% of live rails.** The spec says it
|
|
130
|
+
* "must be false" (XRPL charges the fee to the transaction's own `Account`, so the payer
|
|
131
|
+
* always pays). Read it as *false unless present*: REQUIRING it would reject the entire
|
|
132
|
+
* deployed XRPL x402 web, which is exactly the bug class `assetTransferMethod` already caused
|
|
133
|
+
* once. A rail that explicitly says `true` is refused — we cannot honour a sponsor here. */
|
|
134
|
+
areFeesSponsored?: boolean;
|
|
135
|
+
/** **XRPL** — the issuer's classic address for an IOU rail (RLUSD and friends). Required by the
|
|
136
|
+
* scheme for issued currencies, absent for native XRP; present on 869 of the 1,732 live rails,
|
|
137
|
+
* which is precisely the IOU half. Also the discriminator the buyer uses to pick the
|
|
138
|
+
* issued-currency `Amount` object over a bare drops string. */
|
|
139
|
+
issuer?: string;
|
|
140
|
+
/** **XRPL, OPTIONAL** — an opaque invoice identifier. When present the buyer MUST set the
|
|
141
|
+
* transaction's `InvoiceID` to its **SHA-256**, as 32-byte hex; that hash is the challenge
|
|
142
|
+
* binding on this rail (there is no memo — the scheme has facilitators REJECT `Memos`).
|
|
143
|
+
* Present on 1,732 of 1,732 live rails, so treat it as always-on in practice. */
|
|
144
|
+
invoiceId?: string;
|
|
145
|
+
/** **XRPL** — a vendor correlation tag, copied verbatim into the transaction's `SourceTag`.
|
|
146
|
+
* NOT in `scheme_exact_xrpl.md`'s extra table, but present on **1,728 of the 1,732** live XRPL
|
|
147
|
+
* rails: it is how the deployed vendors match a payment back to their own quote. Mirrored
|
|
148
|
+
* because it costs nothing and omitting it is a plausible reason a merchant refuses. */
|
|
149
|
+
sourceTag?: number;
|
|
150
|
+
/** **XRPL, OPTIONAL** — a destination tag the buyer MUST copy verbatim into the transaction
|
|
151
|
+
* when the rail states one (hosted/exchange accounts route deposits by it). Never invented
|
|
152
|
+
* when absent: unlike the onchain-proof path, which derives a tag from the nonce, the exact
|
|
153
|
+
* rail sets `DestinationTag` only if the merchant asked for one. */
|
|
154
|
+
destinationTag?: number;
|
|
102
155
|
/** EIP-712 domain name of the token. OPTIONAL per the exact-EVM scheme (only
|
|
103
156
|
* `assetTransferMethod` is required) — a foreign rail may omit it. NEVER assumed
|
|
104
157
|
* from the symbol (USDC's on-chain name() is "USD Coin", not "USDC"); a PipRail gate
|
|
@@ -132,6 +185,42 @@ interface X402ExactAcceptEntry {
|
|
|
132
185
|
symbol?: string;
|
|
133
186
|
};
|
|
134
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* The transfer method an `exact` rail uses when it names none.
|
|
190
|
+
*
|
|
191
|
+
* `scheme_exact_evm.md` §0: *"If no `assetTransferMethod` is specified in
|
|
192
|
+
* `PaymentRequired.extra`, clients should default to `"eip3009"`."* §1 restates it per-method:
|
|
193
|
+
* `eip3009` is *"optional in `PaymentRequired`, default"*, while `permit2` and `erc7710` are
|
|
194
|
+
* *"required"*. So an absent marker is not a malformed rail — it is the common case (91% of the
|
|
195
|
+
* deployed web) and it means EIP-3009.
|
|
196
|
+
*/
|
|
197
|
+
declare const DEFAULT_EXACT_TRANSFER_METHOD: "eip3009";
|
|
198
|
+
/**
|
|
199
|
+
* Every `assetTransferMethod` a PipRail buyer can actually sign, across all families.
|
|
200
|
+
*
|
|
201
|
+
* Used to SKIP a rail that names a method we don't implement (the spec's `erc7710`, or any
|
|
202
|
+
* future one) rather than sign an EIP-3009 authorization a facilitator built for a different
|
|
203
|
+
* mechanism and will reject. An **absent** marker is not "unknown" — see
|
|
204
|
+
* {@link DEFAULT_EXACT_TRANSFER_METHOD}. Family routing stays in each driver's `payExact`;
|
|
205
|
+
* this set only answers "could any driver of ours settle this?".
|
|
206
|
+
*/
|
|
207
|
+
declare const KNOWN_EXACT_TRANSFER_METHODS: ReadonlySet<string>;
|
|
208
|
+
/**
|
|
209
|
+
* The effective transfer method of an `exact` rail: what it names, or the default when it names
|
|
210
|
+
* nothing. THE ONLY sanctioned way to read `extra.assetTransferMethod` — reading it bare is how
|
|
211
|
+
* the buyer came to reject 91% of the x402 web.
|
|
212
|
+
*
|
|
213
|
+
* Pass `family` to get the right default off-EVM: a Solana rail that names nothing means `svm`,
|
|
214
|
+
* not `eip3009`. Without it the EVM default is assumed (correct for the settleability check,
|
|
215
|
+
* since every family's own literal is in {@link KNOWN_EXACT_TRANSFER_METHODS} anyway).
|
|
216
|
+
*/
|
|
217
|
+
declare function exactTransferMethod(accept: X402ExactAcceptEntry, family?: string): string;
|
|
218
|
+
/**
|
|
219
|
+
* Can any PipRail driver settle this rail's transfer method? True when the rail names a
|
|
220
|
+
* method we implement, AND when it names none (the spec default `eip3009`). False only for a
|
|
221
|
+
* method we don't implement — the rail is then skipped at gather rather than mis-signed.
|
|
222
|
+
*/
|
|
223
|
+
declare function isSettleableExactMethod(accept: X402ExactAcceptEntry): boolean;
|
|
135
224
|
/**
|
|
136
225
|
* A standard x402 `upto` rail (EVM / Permit2) — variable-amount / metered billing.
|
|
137
226
|
* The buyer signs a Permit2 `PermitWitnessTransferFrom` authorization for `amount`
|
|
@@ -181,7 +270,13 @@ interface X402UptoAcceptEntry {
|
|
|
181
270
|
* rail, or a standard `upto` (metered) rail. */
|
|
182
271
|
type X402AnyAccept = X402AcceptEntry | X402ExactAcceptEntry | X402UptoAcceptEntry;
|
|
183
272
|
interface X402Challenge {
|
|
184
|
-
|
|
273
|
+
/**
|
|
274
|
+
* `2` for every challenge PipRail EMITS. `1` appears only on the PARSE side, when
|
|
275
|
+
* {@link normalizeV1Challenge} has lifted a still-deployed v1 server's body into this
|
|
276
|
+
* shape — the buyer must then answer on the v1 wire (`X-PAYMENT`, flat payload). See the
|
|
277
|
+
* version-posture note above {@link HEADER_SIGNATURE_V1}.
|
|
278
|
+
*/
|
|
279
|
+
x402Version: 1 | 2;
|
|
185
280
|
/**
|
|
186
281
|
* Optional human-readable reason (v2 `error?: string`). PipRail EMITS it only on a
|
|
187
282
|
* rejected-proof re-challenge (omitted on a fresh challenge). Typed to also tolerate
|
|
@@ -361,10 +456,25 @@ interface ExactNearPaymentPayload {
|
|
|
361
456
|
/** Base64 of the Borsh-encoded NEP-366 `SignedDelegateAction` (one `ft_transfer`). */
|
|
362
457
|
signedDelegateAction: string;
|
|
363
458
|
}
|
|
459
|
+
/**
|
|
460
|
+
* The `payload` a client sends for the **XRPL `exact`** variant, per `scheme_exact_xrpl.md`:
|
|
461
|
+
* a **fully signed** XRPL `Payment` transaction, hex-encoded, that the resource server (or its
|
|
462
|
+
* facilitator) submits. The signed blob IS the proof — there is no separate authorization object.
|
|
463
|
+
*
|
|
464
|
+
* XRPL is the one family where **the payer pays the network fee**: the fee is a field inside the
|
|
465
|
+
* signed transaction and the ledger charges it to `Account`. So there is no sponsor, no fee-payer
|
|
466
|
+
* co-signature, and no fee-drain guard to write — the buyer needs XRP for the amount *and* the fee.
|
|
467
|
+
* That also means the buyer signs something immediately submittable, so `LastLedgerSequence` is
|
|
468
|
+
* mandatory: it is the only thing bounding how long the merchant may sit on it.
|
|
469
|
+
*/
|
|
470
|
+
interface ExactXrplPaymentPayload {
|
|
471
|
+
/** Hex-encoded, fully signed XRPL `Payment` transaction blob. */
|
|
472
|
+
signedTxBlob: string;
|
|
473
|
+
}
|
|
364
474
|
/** Any `exact`-rail payload shape — EIP-3009 (`authorization`), Permit2 (`permit2Authorization`),
|
|
365
|
-
* SVM (`transaction`), Algorand (`paymentGroup`), Aptos (`transaction` + `senderAuth`),
|
|
366
|
-
* (`signedDelegateAction`). */
|
|
367
|
-
type ExactPaymentPayloadAny = ExactPaymentPayload | Permit2PaymentPayload | ExactSvmPaymentPayload | ExactAlgorandPaymentPayload | ExactAptosPaymentPayload | ExactNearPaymentPayload;
|
|
475
|
+
* SVM (`transaction`), Algorand (`paymentGroup`), Aptos (`transaction` + `senderAuth`), NEAR
|
|
476
|
+
* (`signedDelegateAction`), or XRPL (`signedTxBlob`). */
|
|
477
|
+
type ExactPaymentPayloadAny = ExactPaymentPayload | Permit2PaymentPayload | ExactSvmPaymentPayload | ExactAlgorandPaymentPayload | ExactAptosPaymentPayload | ExactNearPaymentPayload | ExactXrplPaymentPayload;
|
|
368
478
|
interface ParsedExactBase {
|
|
369
479
|
x402Version: number;
|
|
370
480
|
/** The client's claimed network (slug or CAIP-2) — for matching, not trust. */
|
|
@@ -385,7 +495,9 @@ interface ParsedExactBase {
|
|
|
385
495
|
* `'svm'` → {@link ExactSvmPaymentPayload} (`transaction`), `'algorand'` →
|
|
386
496
|
* {@link ExactAlgorandPaymentPayload} (`paymentGroup`); `'aptos'` →
|
|
387
497
|
* {@link ExactAptosPaymentPayload} (`transaction` + `senderAuth`); `'near'` →
|
|
388
|
-
* {@link ExactNearPaymentPayload} (`signedDelegateAction`)
|
|
498
|
+
* {@link ExactNearPaymentPayload} (`signedDelegateAction`); `'sequence'` / `'ticketSequence'` →
|
|
499
|
+
* {@link ExactXrplPaymentPayload} (`signedTxBlob`) — XRPL is the one family whose method literal
|
|
500
|
+
* names the SEQUENCING strategy rather than a transfer mechanism, because it has only one.
|
|
389
501
|
*/
|
|
390
502
|
type ParsedExactPayment = (ParsedExactBase & {
|
|
391
503
|
method: 'eip3009';
|
|
@@ -405,6 +517,12 @@ type ParsedExactPayment = (ParsedExactBase & {
|
|
|
405
517
|
}) | (ParsedExactBase & {
|
|
406
518
|
method: 'near';
|
|
407
519
|
payload: ExactNearPaymentPayload;
|
|
520
|
+
}) | (ParsedExactBase & {
|
|
521
|
+
method: 'sequence';
|
|
522
|
+
payload: ExactXrplPaymentPayload;
|
|
523
|
+
}) | (ParsedExactBase & {
|
|
524
|
+
method: 'ticketSequence';
|
|
525
|
+
payload: ExactXrplPaymentPayload;
|
|
408
526
|
});
|
|
409
527
|
/**
|
|
410
528
|
* What {@link parseUptoPaymentHeader} extracts from an inbound `upto` payment — the
|
|
@@ -648,6 +766,25 @@ declare function buildUptoSignatureHeader(input: {
|
|
|
648
766
|
accepted: X402UptoAcceptEntry;
|
|
649
767
|
payload: Permit2UptoPaymentPayload;
|
|
650
768
|
}): string;
|
|
769
|
+
/**
|
|
770
|
+
* Build the **v1** `X-PAYMENT` header value — the flat, pre-v2 payload shape
|
|
771
|
+
* `{ x402Version: 1, scheme, network, payload }`, base64-JSON.
|
|
772
|
+
*
|
|
773
|
+
* This is the `encodeXPaymentHeader` utility the version-posture note above has always
|
|
774
|
+
* described; it had never been written, so the buyer could parse nothing from a v1 server and
|
|
775
|
+
* could answer nothing either. Needed because v2 moved the header `X-PAYMENT` →
|
|
776
|
+
* `PAYMENT-SIGNATURE` and reshaped the payload: a v1 server ignores `PAYMENT-SIGNATURE`
|
|
777
|
+
* entirely (verified live — it just re-challenges) and reads only `X-PAYMENT`.
|
|
778
|
+
*
|
|
779
|
+
* `network` MUST be the slug the v1 server itself sent (`X402ExactAcceptEntry.wireNetwork`),
|
|
780
|
+
* not our canonical CAIP-2: v1 verifiers string-compare it against their own requirement.
|
|
781
|
+
* There is no `accepted` echo in v1 — the chosen rail is identified by these two flat fields.
|
|
782
|
+
*/
|
|
783
|
+
declare function buildV1PaymentHeader(input: {
|
|
784
|
+
scheme: string;
|
|
785
|
+
network: string;
|
|
786
|
+
payload: unknown;
|
|
787
|
+
}): string;
|
|
651
788
|
/**
|
|
652
789
|
* Parse the PAYMENT-REQUIRED challenge from a 402 response. Prefers the
|
|
653
790
|
* `payment-required` header, falls back to the JSON body.
|
|
@@ -747,6 +884,23 @@ declare function parseUptoPaymentHeader(value: string): ParsedUptoPayment | null
|
|
|
747
884
|
* base64 wrapper, byte-identical to before this split on the HTTP path.
|
|
748
885
|
*/
|
|
749
886
|
declare function parseUptoObject(parsed: unknown): ParsedUptoPayment | null;
|
|
887
|
+
/**
|
|
888
|
+
* Lift an x402 **v1** challenge body into the internal {@link X402Challenge} shape, so the
|
|
889
|
+
* whole buyer path downstream of `parseChallenge` stays v2-only and version-blind.
|
|
890
|
+
*
|
|
891
|
+
* Four v1→v2 skews are absorbed, and nothing else is touched (unknown keys ride along
|
|
892
|
+
* verbatim, so a facilitator's extras survive):
|
|
893
|
+
* 1. `maxAmountRequired` → `amount` (v2's rename). An accept that already has `amount` keeps it.
|
|
894
|
+
* 2. slug `network` (`'base'`) → CAIP-2 (`'eip155:8453'`) so the gather's `supports()` matches,
|
|
895
|
+
* with the ORIGINAL preserved on {@link X402ExactAcceptEntry.wireNetwork} because the v1
|
|
896
|
+
* server string-compares the slug it sent when we echo it back.
|
|
897
|
+
* 3. per-accept `resource` string → a top-level `resource` object (first accept that has one).
|
|
898
|
+
* 4. `x402Version: 1` is KEPT on the result — it is what tells `payExactRail` to answer on the
|
|
899
|
+
* v1 wire (`X-PAYMENT`, flat payload) instead of v2's `PAYMENT-SIGNATURE`.
|
|
900
|
+
*
|
|
901
|
+
* Pure: never mutates `body`, never throws (a caller passing a non-v1 value gets `null`).
|
|
902
|
+
*/
|
|
903
|
+
declare function normalizeV1Challenge(body: unknown): X402Challenge | null;
|
|
750
904
|
/**
|
|
751
905
|
* Pick the first accepts[] entry on the `onchain-proof` scheme whose network
|
|
752
906
|
* satisfies `matches` (any chain family). Returns null if none match.
|
|
@@ -958,4 +1112,4 @@ declare class SpendLedger {
|
|
|
958
1112
|
summary(): SpendSummary;
|
|
959
1113
|
}
|
|
960
1114
|
|
|
961
|
-
export {
|
|
1115
|
+
export { normalizeV1Challenge as $, type AddressId as A, type X402ExactAcceptEntry as B, type Caip2 as C, DEFAULT_EXACT_TRANSFER_METHOD as D, EXT_OFFER_RECEIPT as E, type X402PaymentSignature as F, type X402Receipt as G, HEADER_REQUIRED as H, type X402ResourceObject as I, type X402UptoAcceptEntry as J, KNOWN_EXACT_TRANSFER_METHODS as K, buildChallengeHeader as L, buildExactSignatureHeader as M, buildPaymentIdentifierAdvertisement as N, buildReceiptExtension as O, type PaidReceipt as P, buildReceiptHeader as Q, buildSignatureHeader as R, type SettleOutcome as S, buildUptoSignatureHeader as T, buildV1PaymentHeader as U, type VerifyErrorCode as V, decodeBase64Json as W, type X402AcceptEntry as X, exactTransferMethod as Y, isSettleableExactMethod as Z, memorySpendStore as _, type AssetId as a, parseChallenge as a0, parseExactObject as a1, parseExactPaymentHeader as a2, parseReceipt as a3, parseReceiptExtension as a4, parseSettleResponse as a5, parseSignatureHeader as a6, parseSignatureObject as a7, parseUptoObject as a8, parseUptoPaymentHeader as a9, pickAccept as aa, readPaymentIdentifier as ab, EXT_PAYMENT_IDENTIFIER as b, type ExactAuthorizationWire as c, type ExactPaymentPayload as d, type ExactPaymentPayloadAny as e, HEADER_RESPONSE as f, HEADER_RESPONSE_V1 as g, HEADER_SIGNATURE as h, HEADER_SIGNATURE_V1 as i, type ParsedExactPayment as j, type ParsedUptoPayment as k, type Permit2Authorization as l, type Permit2PaymentPayload as m, type Permit2UptoAuthorization as n, type Permit2UptoPaymentPayload as o, type PipRailReceipt as p, type SignedReceipt as q, type SpendAssetTotal as r, type SpendDenomTotal as s, SpendLedger as t, type SpendRecord as u, type SpendStore as v, type SpendSummary as w, type VerifyResult as x, type X402AnyAccept as y, type X402Challenge as z };
|
package/dist/node.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { v as SpendStore } from './ledger-
|
|
2
|
-
export {
|
|
1
|
+
import { v as SpendStore } from './ledger-Crc1bZox.cjs';
|
|
2
|
+
export { _ as memorySpendStore } from './ledger-Crc1bZox.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* A durable {@link SpendStore} backed by a local JSONL file (one settled payment per
|
package/dist/node.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { v as SpendStore } from './ledger-
|
|
2
|
-
export {
|
|
1
|
+
import { v as SpendStore } from './ledger-Crc1bZox.js';
|
|
2
|
+
export { _ as memorySpendStore } from './ledger-Crc1bZox.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* A durable {@link SpendStore} backed by a local JSONL file (one settled payment per
|