@piprail/sdk 1.17.0 → 1.19.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 CHANGED
@@ -4,6 +4,59 @@ All notable changes to `@piprail/sdk` are documented here. The format
4
4
  follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the
5
5
  versions follow [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## [1.19.0] — 2026-06-11 — gasless `exact` on 3 more chains (Monad · zkSync Era · Injective)
8
+
9
+ A minor, fully additive release — defaults byte-identical (`exact` stays opt-in), no new dependency,
10
+ the lazy-chunk invariant holds. The same slug-only path as 1.18.0, extended after on-chain verification.
11
+
12
+ ### Added — gasless EIP-3009 `exact` on 3 more EVM chains → **17 gasless mainnet EVM chains**
13
+ - **Monad (143), zkSync Era (324), Injective (1776)** added to `EXACT_NETWORK_SLUGS`. Each ships a
14
+ **native Circle USDC** verified on-chain to the same bar as 1.18.0: `symbol`/`decimals` match,
15
+ `authorizationState` present (the EIP-3009 marker), explicit EIP-712 domain `version` 2, and — the
16
+ check that actually matters for signing — the preset **chainId matches the chain's real
17
+ `eth_chainId`** (a mismatch would have the token reject every signature). All three resolve
18
+ `exact/eip3009` through a live gate end-to-end. The buyer pays **gasless, no approval, no proxy**.
19
+ - zkSync Era's native account abstraction is **not a blocker** here: an EOA payer's standard `ecrecover`
20
+ path through the token's FiatToken `transferWithAuthorization` is unaffected, and the EIP-712 domain
21
+ was confirmed correct (chainId 324, version 2).
22
+
23
+ ### Docs
24
+ - The **Gasless payments** coverage table now lists all 17 gasless-via-EIP-3009 chains.
25
+
26
+ ### Tests
27
+ - `chainIdForExactNetwork` now asserts the 3 new slugs alongside the 1.18.0 set.
28
+
29
+ ## [1.18.0] — 2026-06-11 — gasless `exact` on 7 more chains + a Permit2-proxy guard
30
+
31
+ A minor, fully additive release — defaults byte-identical (`exact` stays opt-in), no new dependency,
32
+ the lazy-chunk invariant holds.
33
+
34
+ ### Added — gasless EIP-3009 `exact` on 7 more EVM chains
35
+ - **Sonic, Linea, Celo, Unichain, World Chain, Sei, HyperEVM** added to `EXACT_NETWORK_SLUGS`. Each
36
+ ships a **native Circle USDC** whose `transferWithAuthorization` (EIP-3009) was **verified on-chain**
37
+ (`authorizationState` present), so the buyer pays **gasless, with no approval and no proxy**. This
38
+ roughly **doubles** PipRail's gasless-EVM footprint (7 → 14 mainnet chains). Live-proven on **HyperEVM
39
+ mainnet** (a standard `exact` client signed EIP-3009, the gate self-settled — tx `0xe31f92ee…`).
40
+ - (The rail was never gated per-chain in the driver — it's capability-detected at runtime via
41
+ `exactDomain`. `EXACT_NETWORK_SLUGS` is the public `chainIdForExactNetwork` helper + the advertised
42
+ list; it had simply drifted behind the real capability. It's now accurate.)
43
+
44
+ ### Hardened — never advertise an unsettleable Permit2 rail
45
+ - The `exact` rail's **Permit2** fallback (for non-EIP-3009 tokens) now checks the **x402ExactPermit2Proxy
46
+ is deployed** on the chain before advertising it. On a chain with neither an EIP-3009 token nor the
47
+ proxy (e.g. Mantle/Scroll/Kaia for their tokens), the gate offers `onchain-proof` only instead of a
48
+ Permit2 rail it could never settle; a forced `method: 'permit2'` there is a clear config error.
49
+ - New driver-contract method `exactPermit2Supported?()` (EVM driver implements it from the verified
50
+ proxy-chain set). New public exports: **`PERMIT2_PROXY_CHAIN_IDS`**, **`isPermit2ProxyChain`**.
51
+
52
+ ### Docs
53
+ - The chain-specific "Permit2 & BNB Chain" page was consolidated into a comprehensive **Gasless
54
+ payments** page (what gasless means · `onchain-proof` vs `exact` · EIP-3009 vs Permit2 · a clear
55
+ per-chain/-token coverage table). Old URL redirects.
56
+
57
+ ### Tests
58
+ - +5 (the 7 new slugs, `isPermit2ProxyChain`, and the proxy-guard: auto-drop, mixed-gate, forced-throw).
59
+
7
60
  ## [1.17.0] — 2026-06-11 — `onPaid` hardening: enriched, isolated, durable receipts
8
61
 
9
62
  A minor, fully additive release — defaults byte-identical (fire-and-forget stays the default,
package/dist/index.cjs CHANGED
@@ -516,7 +516,19 @@ var EXACT_NETWORK_SLUGS = {
516
516
  polygon: 137,
517
517
  avalanche: 43114,
518
518
  bnb: 56,
519
- bsc: 56
519
+ bsc: 56,
520
+ // Native Circle USDC, EIP-3009 verified on-chain (authorizationState present, domain
521
+ // version 2, chainId matched) — gasless, no proxy, no approve:
522
+ sonic: 146,
523
+ linea: 59144,
524
+ celo: 42220,
525
+ unichain: 130,
526
+ worldchain: 480,
527
+ sei: 1329,
528
+ hyperevm: 999,
529
+ monad: 143,
530
+ zksync: 324,
531
+ injective: 1776
520
532
  };
521
533
  function chainIdForExactNetwork(slug) {
522
534
  return _nullishCoalesce(EXACT_NETWORK_SLUGS[slug], () => ( null));
@@ -930,6 +942,37 @@ async function verifyAndSettleExactEvm(input) {
930
942
 
931
943
  var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
932
944
  var X402_EXACT_PERMIT2_PROXY = "0x402085c248EeA27D92E8b30b2C58ed07f9E20001";
945
+ var PERMIT2_PROXY_CHAIN_IDS = /* @__PURE__ */ new Set([
946
+ 1,
947
+ // Ethereum
948
+ 8453,
949
+ // Base
950
+ 84532,
951
+ // Base Sepolia
952
+ 42161,
953
+ // Arbitrum
954
+ 10,
955
+ // Optimism
956
+ 137,
957
+ // Polygon
958
+ 43114,
959
+ // Avalanche
960
+ 56,
961
+ // BNB
962
+ 42220,
963
+ // Celo
964
+ 480,
965
+ // World Chain
966
+ 1329,
967
+ // Sei
968
+ 999,
969
+ // HyperEVM
970
+ 143
971
+ // Monad
972
+ ]);
973
+ function isPermit2ProxyChain(chainId) {
974
+ return PERMIT2_PROXY_CHAIN_IDS.has(chainId);
975
+ }
933
976
  var PERMIT2_WITNESS_TYPES = {
934
977
  PermitWitnessTransferFrom: [
935
978
  { name: "permitted", type: "TokenPermissions" },
@@ -1660,6 +1703,11 @@ function makeEvmNetwork(resolved) {
1660
1703
  async exactDomain(asset) {
1661
1704
  return readExactDomain(publicClient, asset);
1662
1705
  },
1706
+ // Whether the Permit2 transfer method can settle here (proxy deployed). EIP-3009
1707
+ // needs no proxy; this only gates the Permit2 fallback for non-EIP-3009 tokens.
1708
+ exactPermit2Supported() {
1709
+ return isPermit2ProxyChain(resolved.chainId);
1710
+ },
1663
1711
  async settleExactSelf({ relayer, payload, accept }) {
1664
1712
  const a = relayer._native;
1665
1713
  if ("permit2Authorization" in payload) {
@@ -4129,6 +4177,14 @@ function createPaymentGate(options) {
4129
4177
  method = "permit2";
4130
4178
  }
4131
4179
  }
4180
+ if (method === "permit2" && !(_nullishCoalesce(_optionalChain([net, 'access', _64 => _64.exactPermit2Supported, 'optionalCall', _65 => _65()]), () => ( false)))) {
4181
+ if (cfg.method === "permit2") {
4182
+ throw new Error(
4183
+ `requirePayment: exact \`method: 'permit2'\` needs the x402 Permit2 proxy deployed on ${net.network}, but it isn't there. Offer an EIP-3009 token (gasless, no proxy), or drop \`exact\` on this chain. (See PERMIT2_PROXY_CHAIN_IDS.)`
4184
+ );
4185
+ }
4186
+ return void 0;
4187
+ }
4132
4188
  if (cfg.settle === "self") {
4133
4189
  if (cfg.relayer === void 0) {
4134
4190
  throw new Error(
@@ -4214,7 +4270,7 @@ function createPaymentGate(options) {
4214
4270
  const specs = await ready();
4215
4271
  const nonce = genNonce();
4216
4272
  const bazaar = options.discovery ? { bazaar: buildBazaarExtension(options.discovery === true ? {} : options.discovery) } : void 0;
4217
- const extensions = { ...bazaar, ..._optionalChain([opts, 'optionalAccess', _64 => _64.extensions]) };
4273
+ const extensions = { ...bazaar, ..._optionalChain([opts, 'optionalAccess', _66 => _66.extensions]) };
4218
4274
  const challenge2 = {
4219
4275
  x402Version: 2,
4220
4276
  resource: {
@@ -4222,7 +4278,7 @@ function createPaymentGate(options) {
4222
4278
  ...options.description ? { description: options.description } : {}
4223
4279
  },
4224
4280
  accepts: buildAccepts(specs, nonce),
4225
- ..._optionalChain([opts, 'optionalAccess', _65 => _65.error]) ? { error: opts.error } : {},
4281
+ ..._optionalChain([opts, 'optionalAccess', _67 => _67.error]) ? { error: opts.error } : {},
4226
4282
  ...Object.keys(extensions).length > 0 ? { extensions } : {}
4227
4283
  };
4228
4284
  return { challenge: challenge2, requiredHeader: buildChallengeHeader(challenge2) };
@@ -4456,7 +4512,7 @@ function isRetryableStatus(status) {
4456
4512
  }
4457
4513
  var sleep = (ms) => ms > 0 ? new Promise((resolve) => setTimeout(resolve, ms)) : Promise.resolve();
4458
4514
  async function signBody(secret, body) {
4459
- const subtle = _optionalChain([globalThis, 'access', _66 => _66.crypto, 'optionalAccess', _67 => _67.subtle]);
4515
+ const subtle = _optionalChain([globalThis, 'access', _68 => _68.crypto, 'optionalAccess', _69 => _69.subtle]);
4460
4516
  if (!subtle) return null;
4461
4517
  try {
4462
4518
  const enc = new TextEncoder();
@@ -4526,7 +4582,7 @@ async function deliverReceipt(receipt, options) {
4526
4582
  const retryable = status === void 0 ? true : isRetryableStatus(status);
4527
4583
  const willRetry = !ok && retryable && attempt < maxAttempts;
4528
4584
  try {
4529
- _optionalChain([onAttempt, 'optionalCall', _68 => _68({ attempt, ok, ...status !== void 0 ? { status } : {}, ...error ? { error } : {}, willRetry })]);
4585
+ _optionalChain([onAttempt, 'optionalCall', _70 => _70({ attempt, ok, ...status !== void 0 ? { status } : {}, ...error ? { error } : {}, willRetry })]);
4530
4586
  } catch (e36) {
4531
4587
  }
4532
4588
  if (ok) return { delivered: true, attempts: attempt, status };
@@ -4624,4 +4680,6 @@ async function deliverReceipt(receipt, options) {
4624
4680
 
4625
4681
 
4626
4682
 
4627
- exports.CHAINS = CHAINS; exports.ConfirmationTimeoutError = _chunkPA6YD3HLcjs.ConfirmationTimeoutError; exports.DIRECTORY_INFO = DIRECTORY_INFO; exports.EIP3009_TYPES = EIP3009_TYPES; exports.EXACT_NETWORK_SLUGS = EXACT_NETWORK_SLUGS; exports.GENERATOR = GENERATOR; exports.HEADER_REQUIRED = HEADER_REQUIRED; exports.HEADER_RESPONSE = HEADER_RESPONSE; exports.HEADER_RESPONSE_V1 = HEADER_RESPONSE_V1; exports.HEADER_SIGNATURE = HEADER_SIGNATURE; exports.HEADER_SIGNATURE_V1 = HEADER_SIGNATURE_V1; exports.InsufficientFundsError = _chunkPA6YD3HLcjs.InsufficientFundsError; exports.InvalidEnvelopeError = _chunkPA6YD3HLcjs.InvalidEnvelopeError; exports.MaxRetriesExceededError = _chunkPA6YD3HLcjs.MaxRetriesExceededError; exports.MissingDriverError = _chunkPA6YD3HLcjs.MissingDriverError; exports.NoCompatibleAcceptError = _chunkPA6YD3HLcjs.NoCompatibleAcceptError; exports.NonReplayableBodyError = _chunkPA6YD3HLcjs.NonReplayableBodyError; exports.PERMIT2_ADDRESS = PERMIT2_ADDRESS; exports.PERMIT2_WITNESS_TYPES = PERMIT2_WITNESS_TYPES; exports.PIPRAIL_AGENT_GUIDE = PIPRAIL_AGENT_GUIDE; exports.PaymentDeclinedError = _chunkPA6YD3HLcjs.PaymentDeclinedError; exports.PaymentTimeoutError = _chunkPA6YD3HLcjs.PaymentTimeoutError; exports.PipRailClient = PipRailClient; exports.PipRailError = _chunkPA6YD3HLcjs.PipRailError; exports.RecipientNotReadyError = _chunkPA6YD3HLcjs.RecipientNotReadyError; exports.SettlementError = _chunkPA6YD3HLcjs.SettlementError; exports.UnknownTokenError = _chunkPA6YD3HLcjs.UnknownTokenError; exports.UnsupportedNetworkError = _chunkPA6YD3HLcjs.UnsupportedNetworkError; exports.UnsupportedSchemeError = _chunkPA6YD3HLcjs.UnsupportedSchemeError; exports.WrongChainError = _chunkPA6YD3HLcjs.WrongChainError; exports.WrongFamilyError = _chunkPA6YD3HLcjs.WrongFamilyError; exports.X402_EXACT_PERMIT2_PROXY = X402_EXACT_PERMIT2_PROXY; exports.agentGuide = agentGuide; exports.buildBazaarExtension = buildBazaarExtension; exports.buildChallengeHeader = buildChallengeHeader; exports.buildExactAuthorization = buildExactAuthorization; exports.buildExactSignatureHeader = buildExactSignatureHeader; exports.buildOpenApi = buildOpenApi; exports.buildReceiptHeader = buildReceiptHeader; exports.buildSignatureHeader = buildSignatureHeader; exports.buildWellKnownX402 = buildWellKnownX402; exports.buildX402DnsTxt = buildX402DnsTxt; exports.chainIdForExactNetwork = chainIdForExactNetwork; exports.claim402IndexDomain = claim402IndexDomain; exports.classifyChallenge = classifyChallenge; exports.createPaymentGate = createPaymentGate; exports.decorateOutcome = decorateOutcome; exports.deliverReceipt = deliverReceipt; exports.eip3009Abi = eip3009Abi; exports.encodeXPaymentHeader = encodeXPaymentHeader; exports.evaluatePolicy = evaluatePolicy; exports.explainDecline = explainDecline; exports.formatSpendReport = formatSpendReport; exports.getDirectoryInfo = getDirectoryInfo; exports.normalizeNetwork = normalizeNetwork; exports.parseChallenge = parseChallenge; exports.parseExactPaymentHeader = parseExactPaymentHeader; exports.parseExactRequirements = parseExactRequirements; exports.parseReceipt = parseReceipt; exports.parseSettleResponse = parseSettleResponse; exports.parseSignatureHeader = parseSignatureHeader; exports.paymentTools = paymentTools; exports.pickAccept = pickAccept; exports.planAcross = planAcross; exports.readExactDomain = readExactDomain; exports.register402Index = register402Index; exports.registerDriver = registerDriver; exports.registerX402Scan = registerX402Scan; exports.requirePayment = requirePayment; exports.resolveChain = resolveChain; exports.searchOpenIndexes = searchOpenIndexes; exports.settleViaFacilitator = settleViaFacilitator; exports.summarizePlan = summarizePlan; exports.toInsufficientFundsError = _chunkPA6YD3HLcjs.toInsufficientFundsError; exports.toInvalidBody = toInvalidBody; exports.verify402IndexDomain = verify402IndexDomain;
4683
+
4684
+
4685
+ exports.CHAINS = CHAINS; exports.ConfirmationTimeoutError = _chunkPA6YD3HLcjs.ConfirmationTimeoutError; exports.DIRECTORY_INFO = DIRECTORY_INFO; exports.EIP3009_TYPES = EIP3009_TYPES; exports.EXACT_NETWORK_SLUGS = EXACT_NETWORK_SLUGS; exports.GENERATOR = GENERATOR; exports.HEADER_REQUIRED = HEADER_REQUIRED; exports.HEADER_RESPONSE = HEADER_RESPONSE; exports.HEADER_RESPONSE_V1 = HEADER_RESPONSE_V1; exports.HEADER_SIGNATURE = HEADER_SIGNATURE; exports.HEADER_SIGNATURE_V1 = HEADER_SIGNATURE_V1; exports.InsufficientFundsError = _chunkPA6YD3HLcjs.InsufficientFundsError; exports.InvalidEnvelopeError = _chunkPA6YD3HLcjs.InvalidEnvelopeError; exports.MaxRetriesExceededError = _chunkPA6YD3HLcjs.MaxRetriesExceededError; exports.MissingDriverError = _chunkPA6YD3HLcjs.MissingDriverError; exports.NoCompatibleAcceptError = _chunkPA6YD3HLcjs.NoCompatibleAcceptError; exports.NonReplayableBodyError = _chunkPA6YD3HLcjs.NonReplayableBodyError; exports.PERMIT2_ADDRESS = PERMIT2_ADDRESS; exports.PERMIT2_PROXY_CHAIN_IDS = PERMIT2_PROXY_CHAIN_IDS; exports.PERMIT2_WITNESS_TYPES = PERMIT2_WITNESS_TYPES; exports.PIPRAIL_AGENT_GUIDE = PIPRAIL_AGENT_GUIDE; exports.PaymentDeclinedError = _chunkPA6YD3HLcjs.PaymentDeclinedError; exports.PaymentTimeoutError = _chunkPA6YD3HLcjs.PaymentTimeoutError; exports.PipRailClient = PipRailClient; exports.PipRailError = _chunkPA6YD3HLcjs.PipRailError; exports.RecipientNotReadyError = _chunkPA6YD3HLcjs.RecipientNotReadyError; exports.SettlementError = _chunkPA6YD3HLcjs.SettlementError; exports.UnknownTokenError = _chunkPA6YD3HLcjs.UnknownTokenError; exports.UnsupportedNetworkError = _chunkPA6YD3HLcjs.UnsupportedNetworkError; exports.UnsupportedSchemeError = _chunkPA6YD3HLcjs.UnsupportedSchemeError; exports.WrongChainError = _chunkPA6YD3HLcjs.WrongChainError; exports.WrongFamilyError = _chunkPA6YD3HLcjs.WrongFamilyError; exports.X402_EXACT_PERMIT2_PROXY = X402_EXACT_PERMIT2_PROXY; exports.agentGuide = agentGuide; exports.buildBazaarExtension = buildBazaarExtension; exports.buildChallengeHeader = buildChallengeHeader; exports.buildExactAuthorization = buildExactAuthorization; exports.buildExactSignatureHeader = buildExactSignatureHeader; exports.buildOpenApi = buildOpenApi; exports.buildReceiptHeader = buildReceiptHeader; exports.buildSignatureHeader = buildSignatureHeader; exports.buildWellKnownX402 = buildWellKnownX402; exports.buildX402DnsTxt = buildX402DnsTxt; exports.chainIdForExactNetwork = chainIdForExactNetwork; exports.claim402IndexDomain = claim402IndexDomain; exports.classifyChallenge = classifyChallenge; exports.createPaymentGate = createPaymentGate; exports.decorateOutcome = decorateOutcome; exports.deliverReceipt = deliverReceipt; exports.eip3009Abi = eip3009Abi; exports.encodeXPaymentHeader = encodeXPaymentHeader; exports.evaluatePolicy = evaluatePolicy; exports.explainDecline = explainDecline; exports.formatSpendReport = formatSpendReport; exports.getDirectoryInfo = getDirectoryInfo; exports.isPermit2ProxyChain = isPermit2ProxyChain; exports.normalizeNetwork = normalizeNetwork; exports.parseChallenge = parseChallenge; exports.parseExactPaymentHeader = parseExactPaymentHeader; exports.parseExactRequirements = parseExactRequirements; exports.parseReceipt = parseReceipt; exports.parseSettleResponse = parseSettleResponse; exports.parseSignatureHeader = parseSignatureHeader; exports.paymentTools = paymentTools; exports.pickAccept = pickAccept; exports.planAcross = planAcross; exports.readExactDomain = readExactDomain; exports.register402Index = register402Index; exports.registerDriver = registerDriver; exports.registerX402Scan = registerX402Scan; exports.requirePayment = requirePayment; exports.resolveChain = resolveChain; exports.searchOpenIndexes = searchOpenIndexes; exports.settleViaFacilitator = settleViaFacilitator; exports.summarizePlan = summarizePlan; exports.toInsufficientFundsError = _chunkPA6YD3HLcjs.toInsufficientFundsError; exports.toInvalidBody = toInvalidBody; exports.verify402IndexDomain = verify402IndexDomain;
package/dist/index.d.cts CHANGED
@@ -4357,6 +4357,15 @@ interface ResolvedNetwork {
4357
4357
  name: string;
4358
4358
  version: string;
4359
4359
  } | null>;
4360
+ /**
4361
+ * OPTIONAL (EVM-only) — whether this chain can carry the **Permit2** transfer method
4362
+ * of the `exact` scheme: i.e. the canonical Permit2 **and** the `x402ExactPermit2Proxy`
4363
+ * are deployed here. The gate calls it to AVOID advertising a Permit2 `exact` rail it
4364
+ * could never settle (a non-EIP-3009 token on a proxy-less chain — e.g. Binance-Peg
4365
+ * USDC on a chain without the proxy). EIP-3009 needs no proxy, so this gates ONLY the
4366
+ * Permit2 fallback. Omitted (or `false`) ⇒ treat Permit2 as unavailable on this chain.
4367
+ */
4368
+ exactPermit2Supported?(): boolean;
4360
4369
  /**
4361
4370
  * OPTIONAL (EVM-only today) — verify a standard x402 `exact` (EIP-3009) payment
4362
4371
  * locally, then SELF-SETTLE it by broadcasting `transferWithAuthorization` from the
@@ -6356,8 +6365,11 @@ declare class UnsupportedNetworkError extends PipRailError {
6356
6365
 
6357
6366
  /** x402 network slug → EVM chain id, for the chains PipRail ships an exact-payable
6358
6367
  * 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.) */
6368
+ * USDC isn't EIP-3009). This is a public REFERENCE/helper, NOT the runtime gate: the
6369
+ * gate offers `exact` on ANY EVM chain whose token is EIP-3009 (detected live via
6370
+ * `exactDomain`) or whose chain has the Permit2 proxy — so keep this list in sync with
6371
+ * what we've VERIFIED, but the rail isn't limited to it. An unknown slug → `null`.
6372
+ * (Matching uses CAIP-2 via `net.supports`.) */
6361
6373
  declare const EXACT_NETWORK_SLUGS: Readonly<Record<string, number>>;
6362
6374
  /** Resolve an x402 `exact` network slug (e.g. "base") to its EVM chain id. */
6363
6375
  declare function chainIdForExactNetwork(slug: string): number | null;
@@ -6620,10 +6632,20 @@ declare function readExactDomain(publicClient: PublicClient, asset: string): Pro
6620
6632
 
6621
6633
  /** Canonical Permit2 (Uniswap), same address on every EVM chain incl. BNB. */
6622
6634
  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. */
6635
+ /** Canonical x402ExactPermit2Proxy — the SAME CREATE2 address on every chain where it's been
6636
+ * deployed (see {@link PERMIT2_PROXY_CHAIN_IDS}; it is NOT on every EVM chain). It is the
6637
+ * `spender` the buyer signs over, and the contract the seller settles through; it enforces
6638
+ * `transferDetails.to == witness.to`, so funds can only reach the signed payTo. */
6626
6639
  declare const X402_EXACT_PERMIT2_PROXY: "0x402085c248EeA27D92E8b30b2C58ed07f9E20001";
6640
+ /** EVM chain ids where BOTH the canonical Permit2 AND the x402ExactPermit2Proxy are deployed —
6641
+ * i.e. where the **Permit2** transfer method of `exact` can actually settle. Verified on-chain
6642
+ * (`eth_getCode`, 2026-06-11). EIP-3009 needs NO proxy, so this gates only the Permit2 fallback;
6643
+ * on a non-EIP-3009 token on a chain absent here, the gate offers `onchain-proof` only rather
6644
+ * than an unsettleable Permit2 rail. The proxy is a permissionless CREATE2 deploy, so extend
6645
+ * this as it lands on more chains (re-verify before adding). */
6646
+ declare const PERMIT2_PROXY_CHAIN_IDS: ReadonlySet<number>;
6647
+ /** Whether a chain has the x402 Permit2 proxy deployed (→ can settle the Permit2 exact method). */
6648
+ declare function isPermit2ProxyChain(chainId: number): boolean;
6627
6649
  /**
6628
6650
  * EIP-712 type set for the x402 `permit2` exact method. MUST encode to exactly the type
6629
6651
  * string Permit2 reconstructs for `permitWitnessTransferFrom`:
@@ -6663,4 +6685,4 @@ declare const PERMIT2_WITNESS_TYPES: {
6663
6685
  }];
6664
6686
  };
6665
6687
 
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 };
6688
+ 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_PROXY_CHAIN_IDS, 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, isPermit2ProxyChain, normalizeNetwork, parseChallenge, parseExactPaymentHeader, parseExactRequirements, parseReceipt, parseSettleResponse, parseSignatureHeader, paymentTools, pickAccept, planAcross, readExactDomain, register402Index, registerDriver, registerX402Scan, requirePayment, resolveChain, searchOpenIndexes, settleViaFacilitator, summarizePlan, toInsufficientFundsError, toInvalidBody, verify402IndexDomain };
package/dist/index.d.ts CHANGED
@@ -4357,6 +4357,15 @@ interface ResolvedNetwork {
4357
4357
  name: string;
4358
4358
  version: string;
4359
4359
  } | null>;
4360
+ /**
4361
+ * OPTIONAL (EVM-only) — whether this chain can carry the **Permit2** transfer method
4362
+ * of the `exact` scheme: i.e. the canonical Permit2 **and** the `x402ExactPermit2Proxy`
4363
+ * are deployed here. The gate calls it to AVOID advertising a Permit2 `exact` rail it
4364
+ * could never settle (a non-EIP-3009 token on a proxy-less chain — e.g. Binance-Peg
4365
+ * USDC on a chain without the proxy). EIP-3009 needs no proxy, so this gates ONLY the
4366
+ * Permit2 fallback. Omitted (or `false`) ⇒ treat Permit2 as unavailable on this chain.
4367
+ */
4368
+ exactPermit2Supported?(): boolean;
4360
4369
  /**
4361
4370
  * OPTIONAL (EVM-only today) — verify a standard x402 `exact` (EIP-3009) payment
4362
4371
  * locally, then SELF-SETTLE it by broadcasting `transferWithAuthorization` from the
@@ -6356,8 +6365,11 @@ declare class UnsupportedNetworkError extends PipRailError {
6356
6365
 
6357
6366
  /** x402 network slug → EVM chain id, for the chains PipRail ships an exact-payable
6358
6367
  * 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.) */
6368
+ * USDC isn't EIP-3009). This is a public REFERENCE/helper, NOT the runtime gate: the
6369
+ * gate offers `exact` on ANY EVM chain whose token is EIP-3009 (detected live via
6370
+ * `exactDomain`) or whose chain has the Permit2 proxy — so keep this list in sync with
6371
+ * what we've VERIFIED, but the rail isn't limited to it. An unknown slug → `null`.
6372
+ * (Matching uses CAIP-2 via `net.supports`.) */
6361
6373
  declare const EXACT_NETWORK_SLUGS: Readonly<Record<string, number>>;
6362
6374
  /** Resolve an x402 `exact` network slug (e.g. "base") to its EVM chain id. */
6363
6375
  declare function chainIdForExactNetwork(slug: string): number | null;
@@ -6620,10 +6632,20 @@ declare function readExactDomain(publicClient: PublicClient, asset: string): Pro
6620
6632
 
6621
6633
  /** Canonical Permit2 (Uniswap), same address on every EVM chain incl. BNB. */
6622
6634
  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. */
6635
+ /** Canonical x402ExactPermit2Proxy — the SAME CREATE2 address on every chain where it's been
6636
+ * deployed (see {@link PERMIT2_PROXY_CHAIN_IDS}; it is NOT on every EVM chain). It is the
6637
+ * `spender` the buyer signs over, and the contract the seller settles through; it enforces
6638
+ * `transferDetails.to == witness.to`, so funds can only reach the signed payTo. */
6626
6639
  declare const X402_EXACT_PERMIT2_PROXY: "0x402085c248EeA27D92E8b30b2C58ed07f9E20001";
6640
+ /** EVM chain ids where BOTH the canonical Permit2 AND the x402ExactPermit2Proxy are deployed —
6641
+ * i.e. where the **Permit2** transfer method of `exact` can actually settle. Verified on-chain
6642
+ * (`eth_getCode`, 2026-06-11). EIP-3009 needs NO proxy, so this gates only the Permit2 fallback;
6643
+ * on a non-EIP-3009 token on a chain absent here, the gate offers `onchain-proof` only rather
6644
+ * than an unsettleable Permit2 rail. The proxy is a permissionless CREATE2 deploy, so extend
6645
+ * this as it lands on more chains (re-verify before adding). */
6646
+ declare const PERMIT2_PROXY_CHAIN_IDS: ReadonlySet<number>;
6647
+ /** Whether a chain has the x402 Permit2 proxy deployed (→ can settle the Permit2 exact method). */
6648
+ declare function isPermit2ProxyChain(chainId: number): boolean;
6627
6649
  /**
6628
6650
  * EIP-712 type set for the x402 `permit2` exact method. MUST encode to exactly the type
6629
6651
  * string Permit2 reconstructs for `permitWitnessTransferFrom`:
@@ -6663,4 +6685,4 @@ declare const PERMIT2_WITNESS_TYPES: {
6663
6685
  }];
6664
6686
  };
6665
6687
 
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 };
6688
+ 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_PROXY_CHAIN_IDS, 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, isPermit2ProxyChain, normalizeNetwork, parseChallenge, parseExactPaymentHeader, parseExactRequirements, parseReceipt, parseSettleResponse, parseSignatureHeader, paymentTools, pickAccept, planAcross, readExactDomain, register402Index, registerDriver, registerX402Scan, requirePayment, resolveChain, searchOpenIndexes, settleViaFacilitator, summarizePlan, toInsufficientFundsError, toInvalidBody, verify402IndexDomain };
package/dist/index.js CHANGED
@@ -516,7 +516,19 @@ var EXACT_NETWORK_SLUGS = {
516
516
  polygon: 137,
517
517
  avalanche: 43114,
518
518
  bnb: 56,
519
- bsc: 56
519
+ bsc: 56,
520
+ // Native Circle USDC, EIP-3009 verified on-chain (authorizationState present, domain
521
+ // version 2, chainId matched) — gasless, no proxy, no approve:
522
+ sonic: 146,
523
+ linea: 59144,
524
+ celo: 42220,
525
+ unichain: 130,
526
+ worldchain: 480,
527
+ sei: 1329,
528
+ hyperevm: 999,
529
+ monad: 143,
530
+ zksync: 324,
531
+ injective: 1776
520
532
  };
521
533
  function chainIdForExactNetwork(slug) {
522
534
  return EXACT_NETWORK_SLUGS[slug] ?? null;
@@ -930,6 +942,37 @@ import {
930
942
  } from "viem";
931
943
  var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
932
944
  var X402_EXACT_PERMIT2_PROXY = "0x402085c248EeA27D92E8b30b2C58ed07f9E20001";
945
+ var PERMIT2_PROXY_CHAIN_IDS = /* @__PURE__ */ new Set([
946
+ 1,
947
+ // Ethereum
948
+ 8453,
949
+ // Base
950
+ 84532,
951
+ // Base Sepolia
952
+ 42161,
953
+ // Arbitrum
954
+ 10,
955
+ // Optimism
956
+ 137,
957
+ // Polygon
958
+ 43114,
959
+ // Avalanche
960
+ 56,
961
+ // BNB
962
+ 42220,
963
+ // Celo
964
+ 480,
965
+ // World Chain
966
+ 1329,
967
+ // Sei
968
+ 999,
969
+ // HyperEVM
970
+ 143
971
+ // Monad
972
+ ]);
973
+ function isPermit2ProxyChain(chainId) {
974
+ return PERMIT2_PROXY_CHAIN_IDS.has(chainId);
975
+ }
933
976
  var PERMIT2_WITNESS_TYPES = {
934
977
  PermitWitnessTransferFrom: [
935
978
  { name: "permitted", type: "TokenPermissions" },
@@ -1660,6 +1703,11 @@ function makeEvmNetwork(resolved) {
1660
1703
  async exactDomain(asset) {
1661
1704
  return readExactDomain(publicClient, asset);
1662
1705
  },
1706
+ // Whether the Permit2 transfer method can settle here (proxy deployed). EIP-3009
1707
+ // needs no proxy; this only gates the Permit2 fallback for non-EIP-3009 tokens.
1708
+ exactPermit2Supported() {
1709
+ return isPermit2ProxyChain(resolved.chainId);
1710
+ },
1663
1711
  async settleExactSelf({ relayer, payload, accept }) {
1664
1712
  const a = relayer._native;
1665
1713
  if ("permit2Authorization" in payload) {
@@ -4129,6 +4177,14 @@ function createPaymentGate(options) {
4129
4177
  method = "permit2";
4130
4178
  }
4131
4179
  }
4180
+ if (method === "permit2" && !(net.exactPermit2Supported?.() ?? false)) {
4181
+ if (cfg.method === "permit2") {
4182
+ throw new Error(
4183
+ `requirePayment: exact \`method: 'permit2'\` needs the x402 Permit2 proxy deployed on ${net.network}, but it isn't there. Offer an EIP-3009 token (gasless, no proxy), or drop \`exact\` on this chain. (See PERMIT2_PROXY_CHAIN_IDS.)`
4184
+ );
4185
+ }
4186
+ return void 0;
4187
+ }
4132
4188
  if (cfg.settle === "self") {
4133
4189
  if (cfg.relayer === void 0) {
4134
4190
  throw new Error(
@@ -4566,6 +4622,7 @@ export {
4566
4622
  NoCompatibleAcceptError,
4567
4623
  NonReplayableBodyError,
4568
4624
  PERMIT2_ADDRESS,
4625
+ PERMIT2_PROXY_CHAIN_IDS,
4569
4626
  PERMIT2_WITNESS_TYPES,
4570
4627
  PIPRAIL_AGENT_GUIDE,
4571
4628
  PaymentDeclinedError,
@@ -4602,6 +4659,7 @@ export {
4602
4659
  explainDecline,
4603
4660
  formatSpendReport,
4604
4661
  getDirectoryInfo,
4662
+ isPermit2ProxyChain,
4605
4663
  normalizeNetwork,
4606
4664
  parseChallenge,
4607
4665
  parseExactPaymentHeader,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@piprail/sdk",
3
- "version": "1.17.0",
3
+ "version": "1.19.0",
4
4
  "description": "Accept x402 crypto payments across 29 chains — every major EVM chain plus Solana, TON, Tron, NEAR, Sui, Aptos, Algorand, Stellar & XRPL — in a couple of lines. No backend, no database, no fee; payments settle straight to your wallet.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",