@piprail/sdk 1.15.0 → 1.17.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 +94 -0
- package/README.md +27 -790
- package/dist/index.cjs +689 -112
- package/dist/index.d.cts +325 -39
- package/dist/index.d.ts +325 -39
- package/dist/index.js +636 -59
- package/package.json +1 -5
- package/CHAINS.md +0 -179
- package/DISCOVERY.md +0 -420
- package/ERRORS.md +0 -283
- package/STANDARDS.md +0 -130
package/dist/index.d.cts
CHANGED
|
@@ -82,8 +82,12 @@ interface X402ExactAcceptEntry {
|
|
|
82
82
|
payTo: AddressId;
|
|
83
83
|
maxTimeoutSeconds: number;
|
|
84
84
|
extra: {
|
|
85
|
-
/** The exact-EVM transfer method
|
|
86
|
-
|
|
85
|
+
/** The exact-EVM transfer method, per the x402 `exact` EVM scheme: `'eip3009'`
|
|
86
|
+
* for tokens with native `transferWithAuthorization`, or `'permit2'` for tokens
|
|
87
|
+
* WITHOUT it (e.g. Binance-Peg USDC on BNB) — the payer signs a Permit2 witness
|
|
88
|
+
* transfer whose `spender` is the canonical x402ExactPermit2Proxy and whose
|
|
89
|
+
* `witness.to` binds the recipient. PipRail self-settles BOTH. */
|
|
90
|
+
assetTransferMethod: 'eip3009' | 'permit2';
|
|
87
91
|
/** EIP-712 domain name of the token. OPTIONAL per the exact-EVM scheme (only
|
|
88
92
|
* `assetTransferMethod` is required) — a foreign rail may omit it. NEVER assumed
|
|
89
93
|
* from the symbol (USDC's on-chain name() is "USD Coin", not "USDC"); a PipRail gate
|
|
@@ -154,22 +158,65 @@ interface ExactPaymentPayload {
|
|
|
154
158
|
authorization: ExactAuthorizationWire;
|
|
155
159
|
}
|
|
156
160
|
/**
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
161
|
+
* The `permit2Authorization` a payer signs for the `permit2` variant of the x402
|
|
162
|
+
* `exact` EVM scheme (tokens without EIP-3009 — e.g. Binance-Peg USDC on BNB). It is
|
|
163
|
+
* an EIP-712 `PermitWitnessTransferFrom` over the canonical Permit2 contract, whose
|
|
164
|
+
* `spender` is the canonical **x402ExactPermit2Proxy** and whose **witness** binds the
|
|
165
|
+
* recipient (`to`) + an activation time (`validAfter`). All numeric fields are DECIMAL
|
|
166
|
+
* strings on the wire (`permitted.amount`, `nonce`, `deadline`, `witness.validAfter`).
|
|
162
167
|
*/
|
|
163
|
-
interface
|
|
168
|
+
interface Permit2Authorization {
|
|
169
|
+
/** What may be pulled: the ERC-20 token + the exact base-unit amount. */
|
|
170
|
+
permitted: {
|
|
171
|
+
token: string;
|
|
172
|
+
amount: string;
|
|
173
|
+
};
|
|
174
|
+
/** The payer (token owner). */
|
|
175
|
+
from: string;
|
|
176
|
+
/** The signature's allowed spender — the canonical x402ExactPermit2Proxy. */
|
|
177
|
+
spender: string;
|
|
178
|
+
/** Permit2 unordered nonce (a uint256, decimal string). Single-use via its bitmap. */
|
|
179
|
+
nonce: string;
|
|
180
|
+
/** Unix-seconds signature expiry. */
|
|
181
|
+
deadline: string;
|
|
182
|
+
/** The proxy-enforced witness: funds go ONLY to `to`, and not before `validAfter`. */
|
|
183
|
+
witness: {
|
|
184
|
+
to: string;
|
|
185
|
+
validAfter: string;
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
/** The `payload` a client sends for the `permit2` exact variant: a signature + its Permit2 authorization. */
|
|
189
|
+
interface Permit2PaymentPayload {
|
|
190
|
+
signature: string;
|
|
191
|
+
permit2Authorization: Permit2Authorization;
|
|
192
|
+
}
|
|
193
|
+
/** Either `exact`-rail payload shape — EIP-3009 (`authorization`) or Permit2 (`permit2Authorization`). */
|
|
194
|
+
type ExactPaymentPayloadAny = ExactPaymentPayload | Permit2PaymentPayload;
|
|
195
|
+
interface ParsedExactBase {
|
|
164
196
|
x402Version: number;
|
|
165
197
|
/** The client's claimed network (slug or CAIP-2) — for matching, not trust. */
|
|
166
198
|
network: string;
|
|
167
199
|
/** The client's claimed asset, if present (v2 `accepted.asset`). */
|
|
168
200
|
asset?: string;
|
|
169
|
-
payload: ExactPaymentPayload;
|
|
170
201
|
/** The full decoded PaymentPayload, for verbatim forwarding to a facilitator (Mode B). */
|
|
171
202
|
raw: Record<string, unknown>;
|
|
172
203
|
}
|
|
204
|
+
/**
|
|
205
|
+
* What {@link parseExactPaymentHeader} extracts from an inbound `exact` payment,
|
|
206
|
+
* normalised across the v1 (`X-PAYMENT`, flat `{scheme,network,payload}`, network slug)
|
|
207
|
+
* and v2 (`PAYMENT-SIGNATURE`, `{accepted,payload}`, CAIP-2 network) wire shapes.
|
|
208
|
+
* `network`/`asset` are the CLIENT's claim — used only to MATCH an offered rail; the gate
|
|
209
|
+
* re-derives every verified field from its own trusted rail. A discriminated union on
|
|
210
|
+
* `method`, so narrowing on `method` narrows `payload`: `'eip3009'` → {@link ExactPaymentPayload}
|
|
211
|
+
* (`authorization`), `'permit2'` → {@link Permit2PaymentPayload} (`permit2Authorization`).
|
|
212
|
+
*/
|
|
213
|
+
type ParsedExactPayment = (ParsedExactBase & {
|
|
214
|
+
method: 'eip3009';
|
|
215
|
+
payload: ExactPaymentPayload;
|
|
216
|
+
}) | (ParsedExactBase & {
|
|
217
|
+
method: 'permit2';
|
|
218
|
+
payload: Permit2PaymentPayload;
|
|
219
|
+
});
|
|
173
220
|
interface X402Receipt {
|
|
174
221
|
scheme: 'onchain-proof' | 'exact';
|
|
175
222
|
/**
|
|
@@ -192,6 +239,37 @@ interface X402Receipt {
|
|
|
192
239
|
payTo: AddressId;
|
|
193
240
|
verifiedAt: string;
|
|
194
241
|
}
|
|
242
|
+
/**
|
|
243
|
+
* The settled-payment record handed to a gate's `onPaid` hook — the wire
|
|
244
|
+
* {@link X402Receipt} plus the merchant-facing extras the gate already computed
|
|
245
|
+
* for the challenge, so a receipt handler never needs a second lookup to display
|
|
246
|
+
* or reconcile it: the token's `decimals`/`symbol`, the human `amountFormatted`
|
|
247
|
+
* (derived from the SETTLED base-unit `amount`, not the requested price), and a
|
|
248
|
+
* stable `idempotencyKey`.
|
|
249
|
+
*
|
|
250
|
+
* **Delivery contract — read this before persisting receipts.** `onPaid` is
|
|
251
|
+
* **at-least-once**: with a single in-memory replay store it fires exactly once
|
|
252
|
+
* per proof, but across instances sharing a custom `isUsed`/`markUsed` store two
|
|
253
|
+
* nodes can settle the same proof in a race and each fire once. Always **dedupe on
|
|
254
|
+
* `idempotencyKey`** (a unique index / upsert). It is also fire-and-forget by
|
|
255
|
+
* default — the gate does not block the response on it and a process crash between
|
|
256
|
+
* settlement and your side-effect drops that receipt. For durability either set
|
|
257
|
+
* `awaitOnPaid` (record before the 200) or push to a durable queue inside the hook;
|
|
258
|
+
* for a webhook, use {@link deliverReceipt} (signed, retried, idempotent).
|
|
259
|
+
*/
|
|
260
|
+
interface PaidReceipt extends X402Receipt {
|
|
261
|
+
/** The token's on-chain decimals — pairs with `amount` so you can format without a lookup. */
|
|
262
|
+
decimals: number;
|
|
263
|
+
/** The token symbol when the gate knows it (e.g. `USDC`, `FDUSD`). */
|
|
264
|
+
symbol?: string;
|
|
265
|
+
/** Human-readable settled amount, e.g. `"0.05"` — `amount` / 10**`decimals`. */
|
|
266
|
+
amountFormatted: string;
|
|
267
|
+
/**
|
|
268
|
+
* A stable, unique key for this settlement (the settled `transaction` id). `onPaid`
|
|
269
|
+
* is at-least-once across instances — dedupe persistence and webhook delivery on this.
|
|
270
|
+
*/
|
|
271
|
+
idempotencyKey: string;
|
|
272
|
+
}
|
|
195
273
|
/**
|
|
196
274
|
* Why a verification failed — a closed, chain-agnostic vocabulary. Every code a
|
|
197
275
|
* driver returns is in this union; a client/agent branches on it rather than
|
|
@@ -236,7 +314,7 @@ declare function buildSignatureHeader(signature: X402PaymentSignature): string;
|
|
|
236
314
|
*/
|
|
237
315
|
declare function buildExactSignatureHeader(input: {
|
|
238
316
|
accepted: X402ExactAcceptEntry;
|
|
239
|
-
payload:
|
|
317
|
+
payload: ExactPaymentPayloadAny;
|
|
240
318
|
}): string;
|
|
241
319
|
/**
|
|
242
320
|
* Parse the PAYMENT-REQUIRED challenge from a 402 response. Prefers the
|
|
@@ -610,7 +688,7 @@ declare const CHAINS: {
|
|
|
610
688
|
value: bigint;
|
|
611
689
|
yParity: number;
|
|
612
690
|
accessList: viem.AccessList;
|
|
613
|
-
authorizationList
|
|
691
|
+
authorizationList?: undefined | undefined;
|
|
614
692
|
blobVersionedHashes?: undefined | undefined;
|
|
615
693
|
chainId: number;
|
|
616
694
|
type: "eip1559";
|
|
@@ -619,7 +697,7 @@ declare const CHAINS: {
|
|
|
619
697
|
maxFeePerGas: bigint;
|
|
620
698
|
maxPriorityFeePerGas: bigint;
|
|
621
699
|
isSystemTx?: undefined | undefined;
|
|
622
|
-
mint
|
|
700
|
+
mint?: undefined | undefined;
|
|
623
701
|
sourceHash?: undefined | undefined;
|
|
624
702
|
} | {
|
|
625
703
|
blockHash: `0x${string}` | null;
|
|
@@ -1019,11 +1097,13 @@ declare const CHAINS: {
|
|
|
1019
1097
|
maxPriorityFeePerGas: bigint;
|
|
1020
1098
|
isSystemTx?: undefined | undefined;
|
|
1021
1099
|
mint?: undefined | undefined;
|
|
1022
|
-
sourceHash
|
|
1100
|
+
sourceHash?: undefined | undefined;
|
|
1023
1101
|
} | {
|
|
1024
1102
|
blockHash: `0x${string}` | null;
|
|
1025
1103
|
blockNumber: bigint | null;
|
|
1026
|
-
blockTimestamp
|
|
1104
|
+
blockTimestamp
|
|
1105
|
+
/** EVM chain id, e.g. 5000 for Mantle. */
|
|
1106
|
+
? /** EVM chain id, e.g. 5000 for Mantle. */: bigint | undefined;
|
|
1027
1107
|
from: abitype.Address;
|
|
1028
1108
|
gas: bigint;
|
|
1029
1109
|
hash: viem.Hash;
|
|
@@ -1257,6 +1337,16 @@ declare const CHAINS: {
|
|
|
1257
1337
|
decimals: number;
|
|
1258
1338
|
symbol: string;
|
|
1259
1339
|
};
|
|
1340
|
+
FDUSD: {
|
|
1341
|
+
address: "0xc5f0f7b66764F6ec8C8Dff7BA683102295E16409";
|
|
1342
|
+
decimals: number;
|
|
1343
|
+
symbol: string;
|
|
1344
|
+
};
|
|
1345
|
+
USD1: {
|
|
1346
|
+
address: "0x8d0D000Ee44948FC98c9B98A4FA4921476f08B0d";
|
|
1347
|
+
decimals: number;
|
|
1348
|
+
symbol: string;
|
|
1349
|
+
};
|
|
1260
1350
|
};
|
|
1261
1351
|
};
|
|
1262
1352
|
avalanche: {
|
|
@@ -2725,7 +2815,9 @@ declare const CHAINS: {
|
|
|
2725
2815
|
chainId: number;
|
|
2726
2816
|
type: "eip7702";
|
|
2727
2817
|
gasPrice?: undefined | undefined;
|
|
2728
|
-
maxFeePerBlobGas
|
|
2818
|
+
maxFeePerBlobGas
|
|
2819
|
+
/** JSON-RPC endpoint. */
|
|
2820
|
+
? /** JSON-RPC endpoint. */: undefined | undefined;
|
|
2729
2821
|
maxFeePerGas: bigint;
|
|
2730
2822
|
maxPriorityFeePerGas: bigint;
|
|
2731
2823
|
l1BatchNumber: bigint | null;
|
|
@@ -4230,7 +4322,7 @@ interface ResolvedNetwork {
|
|
|
4230
4322
|
* and the nonce (for the client's spend record + a re-present-the-same-auth retry).
|
|
4231
4323
|
*/
|
|
4232
4324
|
payExact?(wallet: WalletHandle, accept: X402ExactAcceptEntry): Promise<{
|
|
4233
|
-
payload:
|
|
4325
|
+
payload: ExactPaymentPayloadAny;
|
|
4234
4326
|
accepted: X402ExactAcceptEntry;
|
|
4235
4327
|
payerFrom: string;
|
|
4236
4328
|
nonce: string;
|
|
@@ -4280,7 +4372,7 @@ interface ResolvedNetwork {
|
|
|
4280
4372
|
*/
|
|
4281
4373
|
settleExactSelf?(input: {
|
|
4282
4374
|
relayer: WalletHandle;
|
|
4283
|
-
payload:
|
|
4375
|
+
payload: ExactPaymentPayloadAny;
|
|
4284
4376
|
accept: X402ExactAcceptEntry;
|
|
4285
4377
|
}): Promise<VerifyResult>;
|
|
4286
4378
|
}
|
|
@@ -5627,16 +5719,18 @@ interface AcceptOption {
|
|
|
5627
5719
|
rpcUrl?: string;
|
|
5628
5720
|
}
|
|
5629
5721
|
/**
|
|
5630
|
-
* Opt into ALSO advertising a standard x402 `exact` rail
|
|
5631
|
-
*
|
|
5632
|
-
*
|
|
5633
|
-
*
|
|
5722
|
+
* Opt into ALSO advertising a standard x402 `exact` rail beside the default
|
|
5723
|
+
* `onchain-proof` rail, so ANY standard x402 client can pay this gate (dual-advertise).
|
|
5724
|
+
* EVM ERC-20 only — **EIP-3009** (USDC, EURC) or, for tokens without it, **Permit2**
|
|
5725
|
+
* (any ERC-20 — e.g. Binance-Peg USDC on BNB, settled via the canonical
|
|
5726
|
+
* x402ExactPermit2Proxy). NOT native coins, NOT non-EVM chains. Omitting `exact` leaves
|
|
5727
|
+
* the gate byte-identical to today (onchain-proof only).
|
|
5634
5728
|
*
|
|
5635
5729
|
* Two settlement modes, both backendless (PipRail hosts nothing):
|
|
5636
|
-
* - `settle: 'self'` — your own `relayer` key broadcasts
|
|
5637
|
-
*
|
|
5638
|
-
* and
|
|
5639
|
-
* redirect risk.
|
|
5730
|
+
* - `settle: 'self'` — your own `relayer` key broadcasts the settle (EIP-3009's
|
|
5731
|
+
* `transferWithAuthorization`, or the proxy's `settle` for Permit2). You pay gas to
|
|
5732
|
+
* RECEIVE (the inverse of onchain-proof) and keep the relayer funded. The signature
|
|
5733
|
+
* binds the recipient, so there's no redirect risk. The on-brand default for the rail.
|
|
5640
5734
|
* - `settle: { facilitator }` — delegate verify+settle to a third-party x402
|
|
5641
5735
|
* facilitator YOU choose (Coinbase CDP, x402.org, …). No relayer key needed; the
|
|
5642
5736
|
* facilitator pays gas. Also the only path onto Coinbase's Bazaar directory.
|
|
@@ -5649,6 +5743,10 @@ interface ExactRailOption {
|
|
|
5649
5743
|
/** Required for `settle: 'self'` — the gas-paying relayer wallet: EVM `{ privateKey }`
|
|
5650
5744
|
* or a bring-your-own `{ walletClient }`. (Distinct from `payTo`, the receive address.) */
|
|
5651
5745
|
relayer?: unknown;
|
|
5746
|
+
/** Which exact-EVM transfer method to advertise. `'auto'` (default) uses EIP-3009 when the
|
|
5747
|
+
* token supports it, else Permit2 — so a non-EIP-3009 token like Binance-Peg USDC on BNB
|
|
5748
|
+
* "just works". Force `'eip3009'` or `'permit2'` to pin one. */
|
|
5749
|
+
method?: 'eip3009' | 'permit2' | 'auto';
|
|
5652
5750
|
}
|
|
5653
5751
|
interface RequirePaymentOptions {
|
|
5654
5752
|
/**
|
|
@@ -5696,8 +5794,28 @@ interface RequirePaymentOptions {
|
|
|
5696
5794
|
isUsed?: (ref: string) => boolean | Promise<boolean>;
|
|
5697
5795
|
/** Replay hook — record a redeemed proof. */
|
|
5698
5796
|
markUsed?: (ref: string) => void | Promise<void>;
|
|
5699
|
-
/**
|
|
5700
|
-
|
|
5797
|
+
/**
|
|
5798
|
+
* Fired when a payment verifies successfully, with the enriched {@link PaidReceipt}.
|
|
5799
|
+
* May be **sync or async** — a throw OR a rejected promise is isolated (routed to
|
|
5800
|
+
* `onPaidError`), so the hook can never break the request or crash the process.
|
|
5801
|
+
* Fire-and-forget by default (the response is not blocked on it); set `awaitOnPaid`
|
|
5802
|
+
* to record the receipt before the resource is served. `onPaid` is **at-least-once**
|
|
5803
|
+
* across instances — dedupe on `receipt.idempotencyKey`. See {@link PaidReceipt}.
|
|
5804
|
+
*/
|
|
5805
|
+
onPaid?: (receipt: PaidReceipt) => void | Promise<void>;
|
|
5806
|
+
/**
|
|
5807
|
+
* Observe a failure inside `onPaid` (sync throw or async rejection). Without it,
|
|
5808
|
+
* a failing receipt hook is swallowed silently — set this to log/alert/queue the
|
|
5809
|
+
* dropped receipt. Its own throws are also swallowed (it can never break a request).
|
|
5810
|
+
*/
|
|
5811
|
+
onPaidError?: (error: unknown, receipt: PaidReceipt) => void;
|
|
5812
|
+
/**
|
|
5813
|
+
* Await `onPaid` before returning the paid result (and thus before the gated
|
|
5814
|
+
* resource is served), so "receipt recorded" is guaranteed on the happy path.
|
|
5815
|
+
* Default `false` (fire-and-forget — lower latency). A rejection is still isolated
|
|
5816
|
+
* via `onPaidError`; it never turns a settled payment into a 402.
|
|
5817
|
+
*/
|
|
5818
|
+
awaitOnPaid?: boolean;
|
|
5701
5819
|
/**
|
|
5702
5820
|
* ALSO advertise a standard x402 `exact` rail (EIP-3009) so any standard x402
|
|
5703
5821
|
* client can pay this gate — opt-in, EVM/EIP-3009 only. See {@link ExactRailOption}.
|
|
@@ -5867,6 +5985,85 @@ interface SettleViaFacilitatorInput extends FacilitatorConfig {
|
|
|
5867
5985
|
*/
|
|
5868
5986
|
declare function settleViaFacilitator(input: SettleViaFacilitatorInput): Promise<VerifyResult>;
|
|
5869
5987
|
|
|
5988
|
+
/**
|
|
5989
|
+
* Reliable receipt delivery — the durable webhook a stateless gate can't be.
|
|
5990
|
+
*
|
|
5991
|
+
* `deliverReceipt(receipt, { url, secret })` POSTs a settled {@link PaidReceipt} to
|
|
5992
|
+
* YOUR OWN endpoint, with retries + exponential backoff, an HMAC-SHA256 signature,
|
|
5993
|
+
* and an idempotency key. It is the recommended body of an `onPaid` hook when you
|
|
5994
|
+
* want at-least-once delivery to a webhook instead of a fire-and-forget callback:
|
|
5995
|
+
*
|
|
5996
|
+
* createPaymentGate({
|
|
5997
|
+
* chain, token, amount, payTo,
|
|
5998
|
+
* awaitOnPaid: true, // record before serving
|
|
5999
|
+
* onPaid: (r) => deliverReceipt(r, {
|
|
6000
|
+
* url: process.env.RECEIPTS_WEBHOOK,
|
|
6001
|
+
* secret: process.env.RECEIPTS_SECRET, // signs the body
|
|
6002
|
+
* }),
|
|
6003
|
+
* })
|
|
6004
|
+
*
|
|
6005
|
+
* Charter note: PipRail hosts nothing — `url` is **your** endpoint. This is a pure
|
|
6006
|
+
* transport primitive (no chain libraries), isomorphic (global `fetch` + Web Crypto),
|
|
6007
|
+
* and it **never throws**: failures come back as `{ delivered: false, … }`, because a
|
|
6008
|
+
* delivery helper that threw would reintroduce the very crash `onPaid` isolation
|
|
6009
|
+
* prevents. The receiver verifies the signature and dedupes on the idempotency key.
|
|
6010
|
+
*/
|
|
6011
|
+
|
|
6012
|
+
interface DeliverReceiptOptions {
|
|
6013
|
+
/** Your receiving endpoint. PipRail hosts nothing — this is your server. */
|
|
6014
|
+
url: string;
|
|
6015
|
+
/**
|
|
6016
|
+
* Shared secret. When set, the raw JSON body is signed HMAC-SHA256 and sent as
|
|
6017
|
+
* `<signatureHeader>: sha256=<hex>` so the receiver can verify authenticity.
|
|
6018
|
+
*/
|
|
6019
|
+
secret?: string;
|
|
6020
|
+
/** Extra retry attempts after the first send (default 5 → up to 6 POSTs total). */
|
|
6021
|
+
retries?: number;
|
|
6022
|
+
/** Per-attempt timeout in ms (default 10000). An attempt that exceeds it is aborted + retried. */
|
|
6023
|
+
timeoutMs?: number;
|
|
6024
|
+
/** Extra request headers (merged; never override the signature/idempotency headers). */
|
|
6025
|
+
headers?: Record<string, string>;
|
|
6026
|
+
/** Header carrying the signature. Default `piprail-signature`. */
|
|
6027
|
+
signatureHeader?: string;
|
|
6028
|
+
/** Header carrying the dedupe key (= `receipt.idempotencyKey`). Default `idempotency-key`. */
|
|
6029
|
+
idempotencyHeader?: string;
|
|
6030
|
+
/** Backoff before retry N (1-based) in ms. Default jittered exponential (cap 30s). */
|
|
6031
|
+
backoff?: (attempt: number) => number;
|
|
6032
|
+
/** Injected `fetch` (tests / non-global-fetch runtimes). Defaults to the global. */
|
|
6033
|
+
fetchImpl?: typeof fetch;
|
|
6034
|
+
/** Observe each attempt (logging/metrics). Its own throws are ignored. */
|
|
6035
|
+
onAttempt?: (info: DeliverAttempt) => void;
|
|
6036
|
+
}
|
|
6037
|
+
/** One delivery attempt's outcome (passed to `onAttempt`). */
|
|
6038
|
+
interface DeliverAttempt {
|
|
6039
|
+
/** 1-based attempt number. */
|
|
6040
|
+
attempt: number;
|
|
6041
|
+
/** Did the endpoint return a 2xx? */
|
|
6042
|
+
ok: boolean;
|
|
6043
|
+
/** HTTP status, when a response was received. */
|
|
6044
|
+
status?: number;
|
|
6045
|
+
/** Transport/abort error message, when no response was received. */
|
|
6046
|
+
error?: string;
|
|
6047
|
+
/** Will another attempt follow? */
|
|
6048
|
+
willRetry: boolean;
|
|
6049
|
+
}
|
|
6050
|
+
/** The terminal result of `deliverReceipt` — it never throws, so always inspect this. */
|
|
6051
|
+
interface DeliverResult {
|
|
6052
|
+
/** True iff the endpoint returned a 2xx within the attempt budget. */
|
|
6053
|
+
delivered: boolean;
|
|
6054
|
+
/** Total POSTs made (1 + retries used). */
|
|
6055
|
+
attempts: number;
|
|
6056
|
+
/** Final HTTP status, when the last attempt got a response. */
|
|
6057
|
+
status?: number;
|
|
6058
|
+
/** Final error, when delivery failed (last transport error or a non-2xx summary). */
|
|
6059
|
+
error?: string;
|
|
6060
|
+
}
|
|
6061
|
+
/**
|
|
6062
|
+
* POST a settled receipt to your endpoint with retries, a timeout, an HMAC signature,
|
|
6063
|
+
* and an idempotency key. Never throws — returns a {@link DeliverResult}.
|
|
6064
|
+
*/
|
|
6065
|
+
declare function deliverReceipt(receipt: PaidReceipt, options: DeliverReceiptOptions): Promise<DeliverResult>;
|
|
6066
|
+
|
|
5870
6067
|
/**
|
|
5871
6068
|
* The driver registry — the ONLY place the families meet. Routing decides a
|
|
5872
6069
|
* family from the `chain` value (synchronously), then asks that family's
|
|
@@ -6157,8 +6354,10 @@ declare class UnsupportedNetworkError extends PipRailError {
|
|
|
6157
6354
|
* the same funds to the same payTo and waste their own gas — no redirect risk.
|
|
6158
6355
|
*/
|
|
6159
6356
|
|
|
6160
|
-
/** x402 network slug → EVM chain id, for the chains PipRail ships
|
|
6161
|
-
*
|
|
6357
|
+
/** x402 network slug → EVM chain id, for the chains PipRail ships an exact-payable
|
|
6358
|
+
* stablecoin on — EIP-3009 USDC/EURC on most, and **Permit2** on BNB (Binance-Peg
|
|
6359
|
+
* USDC isn't EIP-3009). Extend as needed; an unknown slug just won't be selected.
|
|
6360
|
+
* (Matching uses CAIP-2 via `net.supports`; this is the public slug helper.) */
|
|
6162
6361
|
declare const EXACT_NETWORK_SLUGS: Readonly<Record<string, number>>;
|
|
6163
6362
|
/** Resolve an x402 `exact` network slug (e.g. "base") to its EVM chain id. */
|
|
6164
6363
|
declare function chainIdForExactNetwork(slug: string): number | null;
|
|
@@ -6359,22 +6558,109 @@ declare const eip3009Abi: readonly [{
|
|
|
6359
6558
|
readonly outputs: readonly [{
|
|
6360
6559
|
readonly type: "string";
|
|
6361
6560
|
}];
|
|
6561
|
+
}, {
|
|
6562
|
+
readonly type: "function";
|
|
6563
|
+
readonly name: "DOMAIN_SEPARATOR";
|
|
6564
|
+
readonly stateMutability: "view";
|
|
6565
|
+
readonly inputs: readonly [];
|
|
6566
|
+
readonly outputs: readonly [{
|
|
6567
|
+
readonly type: "bytes32";
|
|
6568
|
+
}];
|
|
6362
6569
|
}];
|
|
6363
6570
|
/**
|
|
6364
|
-
* Read an EIP-3009 token's true EIP-712 domain `{ name, version }` from the
|
|
6365
|
-
*
|
|
6366
|
-
*
|
|
6367
|
-
*
|
|
6571
|
+
* Read an EIP-3009 token's true EIP-712 domain `{ name, version }` from the contract — what a
|
|
6572
|
+
* payer must sign over. Returns `null` if the asset is NOT an EIP-3009 token (no
|
|
6573
|
+
* `authorizationState` — e.g. USDT, native coin, a plain ERC-20), so the caller falls back to
|
|
6574
|
+
* permit2 / onchain-proof.
|
|
6575
|
+
*
|
|
6576
|
+
* The name is NEVER assumed from the symbol: canonical USDC's domain name is "USD Coin" (not
|
|
6577
|
+
* "USDC"), and EURC's is "Euro Coin" on Ethereum/Avalanche but "EURC" on Base — only the on-chain
|
|
6578
|
+
* read is authoritative.
|
|
6368
6579
|
*
|
|
6369
|
-
* The
|
|
6370
|
-
* "
|
|
6371
|
-
* on
|
|
6372
|
-
* (
|
|
6373
|
-
* `
|
|
6580
|
+
* The version comes from `version()` when the token exposes it (canonical FiatToken — USDC is
|
|
6581
|
+
* "2"). Many EIP-3009 tokens HARDCODE the domain version and DON'T expose `version()` — e.g.
|
|
6582
|
+
* **FDUSD and USD1 on BNB Chain** (both "1"). For those we DERIVE the version by matching the
|
|
6583
|
+
* token's on-chain `DOMAIN_SEPARATOR()` against the standard 4-field domain for a small set of
|
|
6584
|
+
* common versions; a token with a non-standard / salted domain returns `null` (→ permit2 fallback).
|
|
6374
6585
|
*/
|
|
6375
6586
|
declare function readExactDomain(publicClient: PublicClient, asset: string): Promise<{
|
|
6376
6587
|
name: string;
|
|
6377
6588
|
version: string;
|
|
6378
6589
|
} | null>;
|
|
6379
6590
|
|
|
6380
|
-
|
|
6591
|
+
/**
|
|
6592
|
+
* ── EVM SECTION: x402 `exact` scheme, `permit2` variant — BUYER + SELLER ──────
|
|
6593
|
+
*
|
|
6594
|
+
* The companion to `exact.ts` for ERC-20 tokens that do NOT implement EIP-3009
|
|
6595
|
+
* `transferWithAuthorization` — most notably **Binance-Peg USDC/USDT on BNB Chain**
|
|
6596
|
+
* (no native Circle USDC exists on BNB). The x402 `exact` EVM scheme defines a second
|
|
6597
|
+
* `assetTransferMethod`, `"permit2"`, for exactly these tokens:
|
|
6598
|
+
*
|
|
6599
|
+
* • The payer signs an EIP-712 **`PermitWitnessTransferFrom`** over the canonical
|
|
6600
|
+
* **Permit2** contract, with `spender` = the canonical **x402ExactPermit2Proxy**
|
|
6601
|
+
* and a **witness** that binds the recipient (`to`) + an activation time
|
|
6602
|
+
* (`validAfter`). The buyer never broadcasts (and, after a one-time Permit2 approval,
|
|
6603
|
+
* spends ~0 gas) — the merchant/facilitator broadcasts.
|
|
6604
|
+
* • The merchant/facilitator settles by calling the **proxy's `settle(...)`**, which
|
|
6605
|
+
* calls `Permit2.permitWitnessTransferFrom`. Because the signed `spender` is the
|
|
6606
|
+
* proxy and the proxy forces `transferDetails.to == witness.to`, a relayer can only
|
|
6607
|
+
* push the signed funds to the signed recipient — no redirect risk (same guarantee
|
|
6608
|
+
* EIP-3009's `to`-binding gives us).
|
|
6609
|
+
*
|
|
6610
|
+
* Spec: github.com/coinbase/x402 `specs/schemes/exact/scheme_exact_evm.md` (the Permit2
|
|
6611
|
+
* method). Both contracts are canonical CREATE2 deployments (same address every EVM
|
|
6612
|
+
* chain) and are verified deployed on BNB. This module mirrors `exact.ts` file-for-file
|
|
6613
|
+
* (buyer {@link payPermit2Evm}; seller {@link verifyAndSettlePermit2Evm}); the EVM
|
|
6614
|
+
* driver routes to it on `accept.extra.assetTransferMethod === 'permit2'`.
|
|
6615
|
+
*
|
|
6616
|
+
* One-time setup: the payer must `approve(Permit2, max)` on the token ONCE
|
|
6617
|
+
* ({@link ensurePermit2Allowance} does this lazily) — after that, every payment is a
|
|
6618
|
+
* gasless signature. This is the only way `permit2` differs operationally from EIP-3009.
|
|
6619
|
+
*/
|
|
6620
|
+
|
|
6621
|
+
/** Canonical Permit2 (Uniswap), same address on every EVM chain incl. BNB. */
|
|
6622
|
+
declare const PERMIT2_ADDRESS: "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
6623
|
+
/** Canonical x402ExactPermit2Proxy (CREATE2), same address on every EVM chain incl. BNB.
|
|
6624
|
+
* It is the `spender` the buyer signs over, and the contract the seller settles through;
|
|
6625
|
+
* it enforces `transferDetails.to == witness.to`, so funds can only reach the signed payTo. */
|
|
6626
|
+
declare const X402_EXACT_PERMIT2_PROXY: "0x402085c248EeA27D92E8b30b2C58ed07f9E20001";
|
|
6627
|
+
/**
|
|
6628
|
+
* EIP-712 type set for the x402 `permit2` exact method. MUST encode to exactly the type
|
|
6629
|
+
* string Permit2 reconstructs for `permitWitnessTransferFrom`:
|
|
6630
|
+
* `PermitWitnessTransferFrom(TokenPermissions permitted,address spender,uint256 nonce,uint256 deadline,Witness witness)TokenPermissions(address token,uint256 amount)Witness(address to,uint256 validAfter)`
|
|
6631
|
+
* (viem orders referenced structs alphabetically → TokenPermissions before Witness ✓.)
|
|
6632
|
+
*/
|
|
6633
|
+
declare const PERMIT2_WITNESS_TYPES: {
|
|
6634
|
+
readonly PermitWitnessTransferFrom: readonly [{
|
|
6635
|
+
readonly name: "permitted";
|
|
6636
|
+
readonly type: "TokenPermissions";
|
|
6637
|
+
}, {
|
|
6638
|
+
readonly name: "spender";
|
|
6639
|
+
readonly type: "address";
|
|
6640
|
+
}, {
|
|
6641
|
+
readonly name: "nonce";
|
|
6642
|
+
readonly type: "uint256";
|
|
6643
|
+
}, {
|
|
6644
|
+
readonly name: "deadline";
|
|
6645
|
+
readonly type: "uint256";
|
|
6646
|
+
}, {
|
|
6647
|
+
readonly name: "witness";
|
|
6648
|
+
readonly type: "Witness";
|
|
6649
|
+
}];
|
|
6650
|
+
readonly TokenPermissions: readonly [{
|
|
6651
|
+
readonly name: "token";
|
|
6652
|
+
readonly type: "address";
|
|
6653
|
+
}, {
|
|
6654
|
+
readonly name: "amount";
|
|
6655
|
+
readonly type: "uint256";
|
|
6656
|
+
}];
|
|
6657
|
+
readonly Witness: readonly [{
|
|
6658
|
+
readonly name: "to";
|
|
6659
|
+
readonly type: "address";
|
|
6660
|
+
}, {
|
|
6661
|
+
readonly name: "validAfter";
|
|
6662
|
+
readonly type: "uint256";
|
|
6663
|
+
}];
|
|
6664
|
+
};
|
|
6665
|
+
|
|
6666
|
+
export { type AcceptOption, type AddressId, type AgentTool, type AlgorandToken, type AptosToken, type AssetId, type BazaarExtension, type BuildExactParams, CHAINS, type Caip2, type ChainFamily, type ChainInput, type ChainName, type ChainPreset, type ChainSelector, type ChallengeTriage, type ChallengeVerdict, type ConfirmInfo, ConfirmationTimeoutError, type CostEstimate, DIRECTORY_INFO, type DeclineReasonCode, type DeliverAttempt, type DeliverReceiptOptions, type DeliverResult, type DirectoryInfo, type DiscoverOptions, type DiscoveredRail, type DiscoveredResource, type DiscoveryDescriptor, type DiscoverySigner, type DiscoverySource, type DomainClaim, type DomainVerification, EIP3009_TYPES, EXACT_NETWORK_SLUGS, type EvmToken, type ExactAccept, type ExactAuthorization, type ExactAuthorizationWire, type ExactPaymentPayload, type ExactPaymentPayloadAny, type ExactRailOption, type ExpressLikeMiddleware, type ExpressLikeNext, type ExpressLikeRequest, type ExpressLikeResponse, type FacilitatorConfig, type FacilitatorPaymentRequirements, GENERATOR, HEADER_REQUIRED, HEADER_RESPONSE, HEADER_RESPONSE_V1, HEADER_SIGNATURE, HEADER_SIGNATURE_V1, InsufficientFundsError, InvalidEnvelopeError, type ListingVisibility, type ManifestInput, MaxRetriesExceededError, MissingDriverError, type NearToken, NoCompatibleAcceptError, NonReplayableBodyError, type OpenApiDocument, type OpenApiOperation, PERMIT2_ADDRESS, PERMIT2_WITNESS_TYPES, PIPRAIL_AGENT_GUIDE, type PaidReceipt, type ParsedExactPayment, type PayBlocker, type PayOption, type PayWarning, PaymentDeclinedError, type PaymentDriver, type PaymentGate, type PaymentIntent, type PaymentPlan, type PaymentPolicy, type PaymentRail, type PaymentScheme, PaymentTimeoutError, type Permit2Authorization, type Permit2PaymentPayload, PipRailClient, type PipRailClientOptions, type PipRailCostQuote, PipRailError, type PipRailEvent, type PipRailQuote, type PolicyDecision, type PolicyDenyCode, RecipientNotReadyError, type RecipientReason, type RegisterInput, type RegisterOptions, type RegisterOutcome, type RequirePaymentOptions, type ResolveOptions, type ResolvedChain, type ResolvedNetwork, type ResolvedToken, type ResourceDescription, type SearchOpenIndexesOptions, type SessionBudget, type SettleOutcome, type SettleViaFacilitatorInput, SettlementError, type SolanaToken, type SpendAssetTotal, type SpendRecord, type SpendRemaining, type SpendSummary, type StellarToken, type SuiToken, type TokenInfo, type TokenInput, type TonToken, type ToolAnnotations, type TronToken, UnknownTokenError, UnsupportedNetworkError, UnsupportedSchemeError, type VerifyErrorCode, type VerifyPaymentResult, type VerifyResult, type WalletBalance, type WalletHandle, type WalletInput, type WellKnownX402, WrongChainError, WrongFamilyError, type X402AcceptEntry, type X402AnyAccept, type X402Challenge, type X402DnsRecord, type X402ExactAcceptEntry, type X402InvalidBody, type X402PaymentSignature, type X402Receipt, type X402ResourceObject, X402_EXACT_PERMIT2_PROXY, type XrplToken, agentGuide, buildBazaarExtension, buildChallengeHeader, buildExactAuthorization, buildExactSignatureHeader, buildOpenApi, buildReceiptHeader, buildSignatureHeader, buildWellKnownX402, buildX402DnsTxt, chainIdForExactNetwork, claim402IndexDomain, classifyChallenge, createPaymentGate, decorateOutcome, deliverReceipt, eip3009Abi, encodeXPaymentHeader, evaluatePolicy, explainDecline, formatSpendReport, getDirectoryInfo, normalizeNetwork, parseChallenge, parseExactPaymentHeader, parseExactRequirements, parseReceipt, parseSettleResponse, parseSignatureHeader, paymentTools, pickAccept, planAcross, readExactDomain, register402Index, registerDriver, registerX402Scan, requirePayment, resolveChain, searchOpenIndexes, settleViaFacilitator, summarizePlan, toInsufficientFundsError, toInvalidBody, verify402IndexDomain };
|