@piprail/sdk 1.21.0 → 1.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -22,7 +22,8 @@
22
22
 
23
23
 
24
24
 
25
- var _chunkPA6YD3HLcjs = require('./chunk-PA6YD3HL.cjs');
25
+
26
+ var _chunkU35MG4TFcjs = require('./chunk-U35MG4TF.cjs');
26
27
 
27
28
  // src/drivers/registry.ts
28
29
  var byFamily = /* @__PURE__ */ new Map();
@@ -51,13 +52,13 @@ function resolveNetwork(opts) {
51
52
  const family = familyForChain(opts.chain);
52
53
  const driver = byFamily.get(family);
53
54
  if (!driver) {
54
- throw new (0, _chunkPA6YD3HLcjs.UnsupportedNetworkError)(
55
+ throw new (0, _chunkU35MG4TFcjs.UnsupportedNetworkError)(
55
56
  `No driver registered for the "${family}" family \u2014 it may not be mounted yet (use the async resolveNetwork()).`
56
57
  );
57
58
  }
58
59
  const net = driver.resolve(opts);
59
60
  if (!net) {
60
- throw new (0, _chunkPA6YD3HLcjs.UnsupportedNetworkError)(
61
+ throw new (0, _chunkU35MG4TFcjs.UnsupportedNetworkError)(
61
62
  `The ${family} driver didn't recognise this chain input.`
62
63
  );
63
64
  }
@@ -326,12 +327,12 @@ function createWalletAdapter(config, resolved) {
326
327
  }
327
328
  const wc = config.walletClient;
328
329
  if (!wc.account) {
329
- throw new (0, _chunkPA6YD3HLcjs.WrongFamilyError)(
330
+ throw new (0, _chunkU35MG4TFcjs.WrongFamilyError)(
330
331
  "chain is EVM; the provided walletClient has no attached account. Use `createWalletClient({ account, chain, transport })`, or pass { privateKey }."
331
332
  );
332
333
  }
333
334
  if (wc.chain && wc.chain.id !== resolved.chainId) {
334
- throw new (0, _chunkPA6YD3HLcjs.WrongChainError)(
335
+ throw new (0, _chunkU35MG4TFcjs.WrongChainError)(
335
336
  `PipRailClient: walletClient is on chain ${wc.chain.id} but the SDK was configured with chain ${resolved.chainId}. They must match.`
336
337
  );
337
338
  }
@@ -662,19 +663,23 @@ async function payExactEvm(input) {
662
663
  code = void 0;
663
664
  }
664
665
  if (code && code !== "0x") {
665
- throw new (0, _chunkPA6YD3HLcjs.UnsupportedSchemeError)(
666
+ throw new (0, _chunkU35MG4TFcjs.UnsupportedSchemeError)(
666
667
  `exact buyer rail requires an EOA signer; ${account.address} is a contract / EIP-1271 / EIP-7702-delegated account (no recoverable ECDSA signature). Pay via onchain-proof.`
667
668
  );
668
669
  }
669
- const domain = await readExactDomain(publicClient, accept.asset);
670
+ let domain = await readExactDomain(publicClient, accept.asset);
671
+ if (!domain) {
672
+ await new Promise((r) => setTimeout(r, 300));
673
+ domain = await readExactDomain(publicClient, accept.asset);
674
+ }
670
675
  if (!domain) {
671
- throw new (0, _chunkPA6YD3HLcjs.UnsupportedSchemeError)(
672
- `exact: ${accept.asset} on ${accept.network} isn't an EIP-3009 token (USDT needs Permit2; native coin and plain ERC-20s aren't exact-payable). Pay via onchain-proof.`
676
+ throw new (0, _chunkU35MG4TFcjs.UnsupportedSchemeError)(
677
+ `exact: couldn't derive the EIP-712 domain for ${accept.asset} on ${accept.network}. Either it isn't an EIP-3009 token (USDT needs Permit2; native/plain ERC-20 aren't exact-payable) \u2014 pay via onchain-proof \u2014 OR your RPC couldn't read it (transient): if the gate advertised eip3009, pass a reliable rpcUrl and retry.`
673
678
  );
674
679
  }
675
680
  const g = globalThis.crypto;
676
681
  if (!_optionalChain([g, 'optionalAccess', _5 => _5.getRandomValues])) {
677
- throw new (0, _chunkPA6YD3HLcjs.UnsupportedSchemeError)(
682
+ throw new (0, _chunkU35MG4TFcjs.UnsupportedSchemeError)(
678
683
  "this runtime lacks Web Crypto (globalThis.crypto.getRandomValues); the exact rail needs a CSPRNG nonce."
679
684
  );
680
685
  }
@@ -931,7 +936,7 @@ async function verifyAndSettleExactEvm(input) {
931
936
  args: writeArgs
932
937
  });
933
938
  } catch (err) {
934
- throw new (0, _chunkPA6YD3HLcjs.SettlementError)(
939
+ throw new (0, _chunkU35MG4TFcjs.SettlementError)(
935
940
  `exact settle: the merchant relayer failed to broadcast transferWithAuthorization (${shorten(err instanceof Error ? err.message : String(err))}). The payer's authorization is still valid and unused \u2014 fund/fix the relayer and the payer can retry.`,
936
941
  { cause: err }
937
942
  );
@@ -943,7 +948,7 @@ async function verifyAndSettleExactEvm(input) {
943
948
  return { ok: false, error: "tx_reverted", detail: `Settlement tx ${txHash} reverted on-chain.` };
944
949
  }
945
950
  } catch (err) {
946
- throw new (0, _chunkPA6YD3HLcjs.SettlementError)(
951
+ throw new (0, _chunkU35MG4TFcjs.SettlementError)(
947
952
  `exact settle: broadcast ${txHash} but couldn't confirm it (${shorten(err instanceof Error ? err.message : String(err))}).`,
948
953
  { cause: err }
949
954
  );
@@ -1076,7 +1081,7 @@ function shorten2(msg) {
1076
1081
  function randomPermit2Nonce() {
1077
1082
  const g = globalThis.crypto;
1078
1083
  if (!_optionalChain([g, 'optionalAccess', _8 => _8.getRandomValues])) {
1079
- throw new (0, _chunkPA6YD3HLcjs.UnsupportedSchemeError)(
1084
+ throw new (0, _chunkU35MG4TFcjs.UnsupportedSchemeError)(
1080
1085
  "this runtime lacks Web Crypto (globalThis.crypto.getRandomValues); the permit2 rail needs a CSPRNG nonce."
1081
1086
  );
1082
1087
  }
@@ -1095,7 +1100,7 @@ async function ensurePermit2Allowance(input) {
1095
1100
  args: [account.address, PERMIT2_ADDRESS]
1096
1101
  });
1097
1102
  } catch (err) {
1098
- throw new (0, _chunkPA6YD3HLcjs.UnsupportedSchemeError)(
1103
+ throw new (0, _chunkU35MG4TFcjs.UnsupportedSchemeError)(
1099
1104
  `permit2: couldn't read the Permit2 allowance for ${token} (${shorten2(err instanceof Error ? err.message : String(err))}).`
1100
1105
  );
1101
1106
  }
@@ -1112,7 +1117,7 @@ async function ensurePermit2Allowance(input) {
1112
1117
  await publicClient.waitForTransactionReceipt({ hash, confirmations: 1 });
1113
1118
  return hash;
1114
1119
  } catch (err) {
1115
- throw _nullishCoalesce(_chunkPA6YD3HLcjs.toInsufficientFundsError.call(void 0, err), () => ( new (0, _chunkPA6YD3HLcjs.SettlementError)(
1120
+ throw _nullishCoalesce(_chunkU35MG4TFcjs.toInsufficientFundsError.call(void 0, err), () => ( new (0, _chunkU35MG4TFcjs.SettlementError)(
1116
1121
  `permit2: the one-time Permit2 approval for ${token} failed to broadcast (${shorten2(err instanceof Error ? err.message : String(err))}).`,
1117
1122
  { cause: err }
1118
1123
  )));
@@ -1127,7 +1132,7 @@ async function payPermit2Evm(input) {
1127
1132
  code = void 0;
1128
1133
  }
1129
1134
  if (code && code !== "0x") {
1130
- throw new (0, _chunkPA6YD3HLcjs.UnsupportedSchemeError)(
1135
+ throw new (0, _chunkU35MG4TFcjs.UnsupportedSchemeError)(
1131
1136
  `permit2 buyer rail requires an EOA signer; ${account.address} is a contract / EIP-1271 / EIP-7702-delegated account. Pay via onchain-proof.`
1132
1137
  );
1133
1138
  }
@@ -1302,7 +1307,7 @@ async function verifyAndSettlePermit2Evm(input) {
1302
1307
  args: settleArgs
1303
1308
  });
1304
1309
  } catch (err) {
1305
- throw new (0, _chunkPA6YD3HLcjs.SettlementError)(
1310
+ throw new (0, _chunkU35MG4TFcjs.SettlementError)(
1306
1311
  `permit2 settle: the merchant relayer failed to broadcast the proxy settle (${shorten2(err instanceof Error ? err.message : String(err))}). The payer's signature is still valid and its nonce unused \u2014 fund/fix the relayer and the payer can retry.`,
1307
1312
  { cause: err }
1308
1313
  );
@@ -1314,7 +1319,7 @@ async function verifyAndSettlePermit2Evm(input) {
1314
1319
  return { ok: false, error: "tx_reverted", detail: `Settlement tx ${txHash} reverted on-chain.` };
1315
1320
  }
1316
1321
  } catch (err) {
1317
- throw new (0, _chunkPA6YD3HLcjs.SettlementError)(
1322
+ throw new (0, _chunkU35MG4TFcjs.SettlementError)(
1318
1323
  `permit2 settle: broadcast ${txHash} but couldn't confirm it (${shorten2(err instanceof Error ? err.message : String(err))}).`,
1319
1324
  { cause: err }
1320
1325
  );
@@ -1547,15 +1552,15 @@ function makeEvmNetwork(resolved) {
1547
1552
  const info = resolved.tokens[token.toUpperCase()];
1548
1553
  if (!info) {
1549
1554
  const known = Object.keys(resolved.tokens).join(", ") || "(none built in)";
1550
- throw new (0, _chunkPA6YD3HLcjs.UnknownTokenError)(
1555
+ throw new (0, _chunkU35MG4TFcjs.UnknownTokenError)(
1551
1556
  `token "${token}" isn't built in for ${resolved.chain.name} (known: ${known}). Pass { address, decimals } instead, or use 'native'.`
1552
1557
  );
1553
1558
  }
1554
1559
  return { asset: info.address, decimals: info.decimals, symbol: info.symbol };
1555
1560
  }
1556
- _chunkPA6YD3HLcjs.rejectForeignToken.call(void 0, token, "evm", network);
1561
+ _chunkU35MG4TFcjs.rejectForeignToken.call(void 0, token, "evm", network);
1557
1562
  if (!("address" in token)) {
1558
- throw new (0, _chunkPA6YD3HLcjs.WrongFamilyError)(
1563
+ throw new (0, _chunkU35MG4TFcjs.WrongFamilyError)(
1559
1564
  `chain ${network} is EVM; a custom token must be { address, decimals }.`
1560
1565
  );
1561
1566
  }
@@ -1587,14 +1592,14 @@ function makeEvmNetwork(resolved) {
1587
1592
  },
1588
1593
  assertValidPayTo(payTo) {
1589
1594
  if (!_viem.isAddress.call(void 0, payTo)) {
1590
- throw new (0, _chunkPA6YD3HLcjs.WrongFamilyError)(
1595
+ throw new (0, _chunkU35MG4TFcjs.WrongFamilyError)(
1591
1596
  `chain ${network} is EVM, but payTo "${payTo}" is not a valid 0x address.`
1592
1597
  );
1593
1598
  }
1594
1599
  },
1595
1600
  bindWallet(wallet) {
1596
1601
  if (typeof wallet !== "object" || wallet === null || !("privateKey" in wallet) && !("walletClient" in wallet)) {
1597
- throw new (0, _chunkPA6YD3HLcjs.WrongFamilyError)(
1602
+ throw new (0, _chunkU35MG4TFcjs.WrongFamilyError)(
1598
1603
  `chain ${network} is EVM; wallet must be { privateKey } or { walletClient }.`
1599
1604
  );
1600
1605
  }
@@ -1611,12 +1616,12 @@ function makeEvmNetwork(resolved) {
1611
1616
  });
1612
1617
  } catch (err) {
1613
1618
  if (isViemInsufficientFunds(err)) {
1614
- throw new (0, _chunkPA6YD3HLcjs.InsufficientFundsError)(
1619
+ throw new (0, _chunkU35MG4TFcjs.InsufficientFundsError)(
1615
1620
  err instanceof Error ? err.message : "Insufficient funds for payment.",
1616
1621
  { cause: err }
1617
1622
  );
1618
1623
  }
1619
- throw _nullishCoalesce(_chunkPA6YD3HLcjs.toInsufficientFundsError.call(void 0, err), () => ( err));
1624
+ throw _nullishCoalesce(_chunkU35MG4TFcjs.toInsufficientFundsError.call(void 0, err), () => ( err));
1620
1625
  }
1621
1626
  },
1622
1627
  async confirm(ref, minConfirmations) {
@@ -1627,7 +1632,7 @@ function makeEvmNetwork(resolved) {
1627
1632
  });
1628
1633
  return { height: receipt.blockNumber.toString() };
1629
1634
  } catch (err) {
1630
- throw new (0, _chunkPA6YD3HLcjs.ConfirmationTimeoutError)(
1635
+ throw new (0, _chunkU35MG4TFcjs.ConfirmationTimeoutError)(
1631
1636
  `EVM tx ${ref} did not reach ${minConfirmations} confirmation(s) in time.`,
1632
1637
  { cause: err }
1633
1638
  );
@@ -1637,7 +1642,7 @@ function makeEvmNetwork(resolved) {
1637
1642
  const { decimals, symbol } = resolved.chain.nativeCurrency;
1638
1643
  if (accept.scheme === "exact") {
1639
1644
  const permit2 = accept.extra.assetTransferMethod === "permit2";
1640
- return _chunkPA6YD3HLcjs.nativeCost.call(void 0, {
1645
+ return _chunkU35MG4TFcjs.nativeCost.call(void 0, {
1641
1646
  symbol,
1642
1647
  decimals,
1643
1648
  fee: 0n,
@@ -1648,7 +1653,7 @@ function makeEvmNetwork(resolved) {
1648
1653
  const gasLimit = accept.asset === "native" ? 21000n : 65000n;
1649
1654
  try {
1650
1655
  const gasPrice = await publicClient.getGasPrice();
1651
- return _chunkPA6YD3HLcjs.nativeCost.call(void 0, {
1656
+ return _chunkU35MG4TFcjs.nativeCost.call(void 0, {
1652
1657
  symbol,
1653
1658
  decimals,
1654
1659
  fee: gasPrice * gasLimit,
@@ -1657,7 +1662,7 @@ function makeEvmNetwork(resolved) {
1657
1662
  });
1658
1663
  } catch (e20) {
1659
1664
  const gasPrice = 5000000000n;
1660
- return _chunkPA6YD3HLcjs.nativeCost.call(void 0, {
1665
+ return _chunkU35MG4TFcjs.nativeCost.call(void 0, {
1661
1666
  symbol,
1662
1667
  decimals,
1663
1668
  fee: gasPrice * gasLimit,
@@ -1791,9 +1796,9 @@ var loaders = {
1791
1796
  solana: async () => {
1792
1797
  let mod;
1793
1798
  try {
1794
- mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./solana-CCVSMOKS.cjs")));
1799
+ mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./solana-UEMHFQH5.cjs")));
1795
1800
  } catch (cause) {
1796
- throw new (0, _chunkPA6YD3HLcjs.MissingDriverError)(
1801
+ throw new (0, _chunkU35MG4TFcjs.MissingDriverError)(
1797
1802
  `Solana selected, but its packages aren't installed. Run: npm install @solana/web3.js @solana/spl-token bs58`,
1798
1803
  { cause }
1799
1804
  );
@@ -1803,9 +1808,9 @@ var loaders = {
1803
1808
  ton: async () => {
1804
1809
  let mod;
1805
1810
  try {
1806
- mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./ton-RNEFN25G.cjs")));
1811
+ mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./ton-RAYJFKJC.cjs")));
1807
1812
  } catch (cause) {
1808
- throw new (0, _chunkPA6YD3HLcjs.MissingDriverError)(
1813
+ throw new (0, _chunkU35MG4TFcjs.MissingDriverError)(
1809
1814
  `TON selected, but its packages aren't installed. Run: npm install @ton/ton @ton/core @ton/crypto`,
1810
1815
  { cause }
1811
1816
  );
@@ -1815,9 +1820,9 @@ var loaders = {
1815
1820
  stellar: async () => {
1816
1821
  let mod;
1817
1822
  try {
1818
- mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./stellar-XHLLNHQP.cjs")));
1823
+ mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./stellar-SCRRPCEA.cjs")));
1819
1824
  } catch (cause) {
1820
- throw new (0, _chunkPA6YD3HLcjs.MissingDriverError)(
1825
+ throw new (0, _chunkU35MG4TFcjs.MissingDriverError)(
1821
1826
  `Stellar selected, but its package isn't installed. Run: npm install @stellar/stellar-sdk`,
1822
1827
  { cause }
1823
1828
  );
@@ -1827,9 +1832,9 @@ var loaders = {
1827
1832
  xrpl: async () => {
1828
1833
  let mod;
1829
1834
  try {
1830
- mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./xrpl-XN2NBNGI.cjs")));
1835
+ mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./xrpl-GXUFDXHU.cjs")));
1831
1836
  } catch (cause) {
1832
- throw new (0, _chunkPA6YD3HLcjs.MissingDriverError)(
1837
+ throw new (0, _chunkU35MG4TFcjs.MissingDriverError)(
1833
1838
  `XRPL selected, but its package isn't installed. Run: npm install xrpl`,
1834
1839
  { cause }
1835
1840
  );
@@ -1839,9 +1844,9 @@ var loaders = {
1839
1844
  tron: async () => {
1840
1845
  let mod;
1841
1846
  try {
1842
- mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./tron-TKJHNFGM.cjs")));
1847
+ mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./tron-KX4VWS7V.cjs")));
1843
1848
  } catch (cause) {
1844
- throw new (0, _chunkPA6YD3HLcjs.MissingDriverError)(
1849
+ throw new (0, _chunkU35MG4TFcjs.MissingDriverError)(
1845
1850
  `Tron selected, but its package isn't installed. Run: npm install tronweb`,
1846
1851
  { cause }
1847
1852
  );
@@ -1851,9 +1856,9 @@ var loaders = {
1851
1856
  sui: async () => {
1852
1857
  let mod;
1853
1858
  try {
1854
- mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./sui-6CVLEXLA.cjs")));
1859
+ mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./sui-LFT65OGU.cjs")));
1855
1860
  } catch (cause) {
1856
- throw new (0, _chunkPA6YD3HLcjs.MissingDriverError)(
1861
+ throw new (0, _chunkU35MG4TFcjs.MissingDriverError)(
1857
1862
  `Sui selected, but its package isn't installed. Run: npm install @mysten/sui`,
1858
1863
  { cause }
1859
1864
  );
@@ -1863,9 +1868,9 @@ var loaders = {
1863
1868
  near: async () => {
1864
1869
  let mod;
1865
1870
  try {
1866
- mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./near-ZJLZE26R.cjs")));
1871
+ mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./near-MG256A3E.cjs")));
1867
1872
  } catch (cause) {
1868
- throw new (0, _chunkPA6YD3HLcjs.MissingDriverError)(
1873
+ throw new (0, _chunkU35MG4TFcjs.MissingDriverError)(
1869
1874
  `NEAR selected, but its package isn't installed. Run: npm install near-api-js`,
1870
1875
  { cause }
1871
1876
  );
@@ -1875,9 +1880,9 @@ var loaders = {
1875
1880
  aptos: async () => {
1876
1881
  let mod;
1877
1882
  try {
1878
- mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./aptos-GJGIZHNI.cjs")));
1883
+ mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./aptos-XIIHPAOO.cjs")));
1879
1884
  } catch (cause) {
1880
- throw new (0, _chunkPA6YD3HLcjs.MissingDriverError)(
1885
+ throw new (0, _chunkU35MG4TFcjs.MissingDriverError)(
1881
1886
  `Aptos selected, but its package isn't installed. Run: npm install @aptos-labs/ts-sdk`,
1882
1887
  { cause }
1883
1888
  );
@@ -1887,9 +1892,9 @@ var loaders = {
1887
1892
  algorand: async () => {
1888
1893
  let mod;
1889
1894
  try {
1890
- mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./algorand-EJ3S2V7E.cjs")));
1895
+ mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./algorand-ZJ53VCTN.cjs")));
1891
1896
  } catch (cause) {
1892
- throw new (0, _chunkPA6YD3HLcjs.MissingDriverError)(
1897
+ throw new (0, _chunkU35MG4TFcjs.MissingDriverError)(
1893
1898
  `Algorand selected, but its package isn't installed. Run: npm install algosdk`,
1894
1899
  { cause }
1895
1900
  );
@@ -2436,7 +2441,7 @@ function evaluatePolicy(intent, policy, spentForAssetBase, ctx) {
2436
2441
  }
2437
2442
  }
2438
2443
  if (policy.maxAmount !== void 0) {
2439
- const cap = _chunkPA6YD3HLcjs.floorUnits.call(void 0, policy.maxAmount, intent.decimals);
2444
+ const cap = _chunkU35MG4TFcjs.floorUnits.call(void 0, policy.maxAmount, intent.decimals);
2440
2445
  if (intent.amountBase > cap) {
2441
2446
  return deny(
2442
2447
  "MAX_AMOUNT",
@@ -2445,7 +2450,7 @@ function evaluatePolicy(intent, policy, spentForAssetBase, ctx) {
2445
2450
  }
2446
2451
  }
2447
2452
  if (policy.maxTotal !== void 0) {
2448
- const cap = _chunkPA6YD3HLcjs.floorUnits.call(void 0, policy.maxTotal, intent.decimals);
2453
+ const cap = _chunkU35MG4TFcjs.floorUnits.call(void 0, policy.maxTotal, intent.decimals);
2449
2454
  if (spentForAssetBase + intent.amountBase > cap) {
2450
2455
  return deny(
2451
2456
  "MAX_TOTAL",
@@ -2454,7 +2459,7 @@ function evaluatePolicy(intent, policy, spentForAssetBase, ctx) {
2454
2459
  }
2455
2460
  }
2456
2461
  if (ctx && policy.windowTotal !== void 0 && policy.windowSeconds !== void 0) {
2457
- const cap = _chunkPA6YD3HLcjs.floorUnits.call(void 0, policy.windowTotal, intent.decimals);
2462
+ const cap = _chunkU35MG4TFcjs.floorUnits.call(void 0, policy.windowTotal, intent.decimals);
2458
2463
  if (ctx.spentInWindowBase + intent.amountBase > cap) {
2459
2464
  return deny(
2460
2465
  "WINDOW_TOTAL",
@@ -2543,7 +2548,7 @@ var SpendLedger = (_class = class {constructor() { _class.prototype.__init.call(
2543
2548
  symbol: b.symbol,
2544
2549
  decimals: b.decimals,
2545
2550
  totalBase: b.total.toString(),
2546
- totalFormatted: _chunkPA6YD3HLcjs.formatUnits.call(void 0, b.total, b.decimals),
2551
+ totalFormatted: _chunkU35MG4TFcjs.formatUnits.call(void 0, b.total, b.decimals),
2547
2552
  count: b.count
2548
2553
  })),
2549
2554
  records: [...this.records]
@@ -2622,7 +2627,7 @@ var PipRailClient = (_class2 = class {
2622
2627
  chain: this.opts.chain,
2623
2628
  rpcUrl: this.opts.rpcUrl
2624
2629
  });
2625
- const wallet = net.bindWallet(this.opts.wallet);
2630
+ const wallet = this.opts.wallet !== void 0 ? net.bindWallet(this.opts.wallet) : void 0;
2626
2631
  return { net, wallet };
2627
2632
  })();
2628
2633
  }
@@ -2739,13 +2744,13 @@ var PipRailClient = (_class2 = class {
2739
2744
  spentBase: b.totalBase.toString()
2740
2745
  };
2741
2746
  if (maxTotal === void 0) return base2;
2742
- const capBase = _chunkPA6YD3HLcjs.floorUnits.call(void 0, maxTotal, b.decimals);
2747
+ const capBase = _chunkU35MG4TFcjs.floorUnits.call(void 0, maxTotal, b.decimals);
2743
2748
  const remainingBase = capBase > b.totalBase ? capBase - b.totalBase : 0n;
2744
2749
  return {
2745
2750
  ...base2,
2746
2751
  capBase: capBase.toString(),
2747
2752
  remainingBase: remainingBase.toString(),
2748
- remainingFormatted: _chunkPA6YD3HLcjs.formatUnits.call(void 0, remainingBase, b.decimals)
2753
+ remainingFormatted: _chunkU35MG4TFcjs.formatUnits.call(void 0, remainingBase, b.decimals)
2749
2754
  };
2750
2755
  });
2751
2756
  }
@@ -2785,9 +2790,14 @@ var PipRailClient = (_class2 = class {
2785
2790
  if (res.status !== 402) return null;
2786
2791
  const challenge = await parseChallenge(res);
2787
2792
  if (!challenge) {
2788
- throw new (0, _chunkPA6YD3HLcjs.InvalidEnvelopeError)("402 response did not include a parseable x402 challenge.");
2793
+ throw new (0, _chunkU35MG4TFcjs.InvalidEnvelopeError)("402 response did not include a parseable x402 challenge.");
2789
2794
  }
2790
2795
  const { net, wallet } = await this.ensure();
2796
+ if (!wallet) {
2797
+ throw new (0, _chunkU35MG4TFcjs.WalletRequiredError)(
2798
+ "planPayment needs a wallet (it checks YOUR balance, gas, and recipient-readiness). This client is read-only \u2014 construct it with a `wallet` to plan or pay."
2799
+ );
2800
+ }
2791
2801
  return this.planFromChallenge(net, wallet, challenge, url, this.resolveSchemes());
2792
2802
  }
2793
2803
  /**
@@ -2939,6 +2949,7 @@ var PipRailClient = (_class2 = class {
2939
2949
  */
2940
2950
  async discoverySigner() {
2941
2951
  const { net, wallet } = await this.ensure();
2952
+ if (!wallet) return null;
2942
2953
  return net.discoverySigner ? net.discoverySigner(wallet) : null;
2943
2954
  }
2944
2955
  /**
@@ -2951,7 +2962,7 @@ var PipRailClient = (_class2 = class {
2951
2962
  async fetch(url, init) {
2952
2963
  const body = _optionalChain([init, 'optionalAccess', _41 => _41.body]);
2953
2964
  if (body !== void 0 && body !== null && !isReplayableBodyInit(body)) {
2954
- throw new (0, _chunkPA6YD3HLcjs.NonReplayableBodyError)(
2965
+ throw new (0, _chunkU35MG4TFcjs.NonReplayableBodyError)(
2955
2966
  "fetch(): init.body is not replayable. Pass a string, FormData, URLSearchParams, ArrayBuffer, or Blob \u2014 not a ReadableStream."
2956
2967
  );
2957
2968
  }
@@ -2960,13 +2971,18 @@ var PipRailClient = (_class2 = class {
2960
2971
  const schemes = this.resolveSchemes(_optionalChain([init, 'optionalAccess', _42 => _42.schemes]));
2961
2972
  const resolved = await this.resolveChallenge(url, firstResponse, schemes);
2962
2973
  const { net, wallet, challenge } = resolved;
2974
+ if (!wallet) {
2975
+ throw new (0, _chunkU35MG4TFcjs.WalletRequiredError)(
2976
+ "Paying a 402 needs a wallet to sign + settle. This client is read-only \u2014 construct it with a `wallet` to pay (quote/discover/register still work without one)."
2977
+ );
2978
+ }
2963
2979
  let accept = resolved.accept;
2964
2980
  let quote = resolved.quote;
2965
2981
  const autoRoute = _nullishCoalesce(_nullishCoalesce(_optionalChain([init, 'optionalAccess', _43 => _43.autoRoute]), () => ( this.opts.autoRoute)), () => ( false));
2966
2982
  if (autoRoute) {
2967
2983
  const plan = await this.planFromChallenge(net, wallet, challenge, url, schemes);
2968
2984
  if (!plan.best) {
2969
- throw new (0, _chunkPA6YD3HLcjs.PaymentDeclinedError)(_nullishCoalesce(plan.fundingHint, () => ( "No rail is settleable for this payment.")));
2985
+ throw new (0, _chunkU35MG4TFcjs.PaymentDeclinedError)(_nullishCoalesce(plan.fundingHint, () => ( "No rail is settleable for this payment.")));
2970
2986
  }
2971
2987
  accept = plan.best.accept;
2972
2988
  quote = plan.best.quote;
@@ -2990,7 +3006,7 @@ var PipRailClient = (_class2 = class {
2990
3006
  async resolveChallenge(url, response, schemes) {
2991
3007
  const challenge = await parseChallenge(response);
2992
3008
  if (!challenge) {
2993
- throw new (0, _chunkPA6YD3HLcjs.InvalidEnvelopeError)(
3009
+ throw new (0, _chunkU35MG4TFcjs.InvalidEnvelopeError)(
2994
3010
  "402 response did not include a parseable x402 challenge."
2995
3011
  );
2996
3012
  }
@@ -3001,7 +3017,7 @@ var PipRailClient = (_class2 = class {
3001
3017
  (a) => a.scheme === "exact" && net.supports(a.network)
3002
3018
  );
3003
3019
  if (schemes.includes("exact") && exactOnNet && typeof net.payExact !== "function") {
3004
- throw new (0, _chunkPA6YD3HLcjs.UnsupportedSchemeError)(
3020
+ throw new (0, _chunkU35MG4TFcjs.UnsupportedSchemeError)(
3005
3021
  `This 402 offers a standard 'exact' rail on ${net.network}, but the ${net.family} family can't pay 'exact' (supported on EVM + Solana today), and no 'onchain-proof' rail was offered.`
3006
3022
  );
3007
3023
  }
@@ -3010,13 +3026,13 @@ var PipRailClient = (_class2 = class {
3010
3026
  (a) => a.scheme === "exact" && net.supports(a.network) && net.describeAsset(a.asset) != null
3011
3027
  );
3012
3028
  if (payable) {
3013
- throw new (0, _chunkPA6YD3HLcjs.NoCompatibleAcceptError)(
3029
+ throw new (0, _chunkU35MG4TFcjs.NoCompatibleAcceptError)(
3014
3030
  `This 402 is payable only via the standard 'exact' rail on ${net.network}, which is OFF by default. Enable it: new PipRailClient({ \u2026, schemes: ['onchain-proof', 'exact'] }) or per call fetch(url, { schemes: ['exact'] }) (MCP: PIPRAIL_SCHEMES=onchain-proof,exact).`
3015
3031
  );
3016
3032
  }
3017
3033
  }
3018
3034
  const networks = [...new Set(challenge.accepts.map((a) => a.network))].join(", ");
3019
- throw new (0, _chunkPA6YD3HLcjs.NoCompatibleAcceptError)(
3035
+ throw new (0, _chunkU35MG4TFcjs.NoCompatibleAcceptError)(
3020
3036
  `No accepts[] entry payable by this client on ${net.network} (schemes: ${schemes.join(", ")}; challenge offered: ${networks || "none"}).`
3021
3037
  );
3022
3038
  }
@@ -3118,21 +3134,21 @@ var PipRailClient = (_class2 = class {
3118
3134
  if (isExact) {
3119
3135
  if (tokenKnown && bal.token < amount) {
3120
3136
  blockers.push("INSUFFICIENT_TOKEN");
3121
- shortfall.token = _chunkPA6YD3HLcjs.formatUnits.call(void 0, amount - bal.token, quote.decimals);
3137
+ shortfall.token = _chunkU35MG4TFcjs.formatUnits.call(void 0, amount - bal.token, quote.decimals);
3122
3138
  }
3123
3139
  } else if (isNative) {
3124
3140
  if (nativeKnown && bal.native < amount + fee) {
3125
3141
  blockers.push("INSUFFICIENT_TOKEN");
3126
- shortfall.token = _chunkPA6YD3HLcjs.formatUnits.call(void 0, amount + fee - bal.native, quote.decimals);
3142
+ shortfall.token = _chunkU35MG4TFcjs.formatUnits.call(void 0, amount + fee - bal.native, quote.decimals);
3127
3143
  }
3128
3144
  } else {
3129
3145
  if (tokenKnown && bal.token < amount) {
3130
3146
  blockers.push("INSUFFICIENT_TOKEN");
3131
- shortfall.token = _chunkPA6YD3HLcjs.formatUnits.call(void 0, amount - bal.token, quote.decimals);
3147
+ shortfall.token = _chunkU35MG4TFcjs.formatUnits.call(void 0, amount - bal.token, quote.decimals);
3132
3148
  }
3133
3149
  if (nativeKnown && bal.native < fee) {
3134
3150
  blockers.push("INSUFFICIENT_GAS");
3135
- shortfall.native = _chunkPA6YD3HLcjs.formatUnits.call(void 0, fee - bal.native, cost.feeDecimals);
3151
+ shortfall.native = _chunkU35MG4TFcjs.formatUnits.call(void 0, fee - bal.native, cost.feeDecimals);
3136
3152
  } else if (nativeKnown && fee > 0n && bal.native < fee * 3n / 2n) {
3137
3153
  warnings.push("THIN_GAS_MARGIN");
3138
3154
  }
@@ -3157,8 +3173,8 @@ var PipRailClient = (_class2 = class {
3157
3173
  blockers,
3158
3174
  warnings,
3159
3175
  balance: {
3160
- token: bal.token != null ? _chunkPA6YD3HLcjs.formatUnits.call(void 0, bal.token, quote.decimals) : null,
3161
- native: bal.native != null ? _chunkPA6YD3HLcjs.formatUnits.call(void 0, bal.native, cost.feeDecimals) : null
3176
+ token: bal.token != null ? _chunkU35MG4TFcjs.formatUnits.call(void 0, bal.token, quote.decimals) : null,
3177
+ native: bal.native != null ? _chunkU35MG4TFcjs.formatUnits.call(void 0, bal.native, cost.feeDecimals) : null
3162
3178
  },
3163
3179
  need: { token: quote.amountFormatted, native: cost.feeFormatted },
3164
3180
  ...shortfall.token || shortfall.native ? { shortfall } : {},
@@ -3169,7 +3185,7 @@ var PipRailClient = (_class2 = class {
3169
3185
  * driver's describeAsset) + the policy verdict + a symbol-mismatch flag. */
3170
3186
  buildQuote(net, accept, url, description) {
3171
3187
  if (!/^\d+$/.test(accept.amount)) {
3172
- throw new (0, _chunkPA6YD3HLcjs.InvalidEnvelopeError)(
3188
+ throw new (0, _chunkU35MG4TFcjs.InvalidEnvelopeError)(
3173
3189
  `challenge amount "${accept.amount}" is not a base-unit integer.`
3174
3190
  );
3175
3191
  }
@@ -3177,12 +3193,12 @@ var PipRailClient = (_class2 = class {
3177
3193
  const described = net.describeAsset(accept.asset);
3178
3194
  const decimals = _nullishCoalesce(_optionalChain([described, 'optionalAccess', _44 => _44.decimals]), () => ( accept.extra.decimals));
3179
3195
  if (decimals === void 0) {
3180
- throw new (0, _chunkPA6YD3HLcjs.InvalidEnvelopeError)(
3196
+ throw new (0, _chunkU35MG4TFcjs.InvalidEnvelopeError)(
3181
3197
  `challenge for ${accept.asset} on ${accept.network} states no decimals and the SDK doesn't recognise the token \u2014 refusing to price it.`
3182
3198
  );
3183
3199
  }
3184
3200
  const symbol = _nullishCoalesce(_optionalChain([described, 'optionalAccess', _45 => _45.symbol]), () => ( accept.extra.symbol));
3185
- const amountFormatted = _chunkPA6YD3HLcjs.formatUnits.call(void 0, amountBase, decimals);
3201
+ const amountFormatted = _chunkU35MG4TFcjs.formatUnits.call(void 0, amountBase, decimals);
3186
3202
  const intent = {
3187
3203
  host: hostOf2(url),
3188
3204
  chain: this.opts.chain,
@@ -3240,7 +3256,7 @@ var PipRailClient = (_class2 = class {
3240
3256
  * TERMINAL expiry/approval decline it must not retry) without parsing prose. */
3241
3257
  async authorize(quote) {
3242
3258
  if (!quote.withinPolicy) {
3243
- throw new (0, _chunkPA6YD3HLcjs.PaymentDeclinedError)(
3259
+ throw new (0, _chunkU35MG4TFcjs.PaymentDeclinedError)(
3244
3260
  `Payment refused by policy: ${_nullishCoalesce(quote.policyReason, () => ( "not allowed"))}`,
3245
3261
  { reasonCode: reasonCodeForPolicy(quote.policyCode) }
3246
3262
  );
@@ -3251,13 +3267,13 @@ var PipRailClient = (_class2 = class {
3251
3267
  try {
3252
3268
  approved = await hook(quote);
3253
3269
  } catch (err) {
3254
- throw new (0, _chunkPA6YD3HLcjs.PaymentDeclinedError)("onBeforePay threw \u2014 refusing to pay.", {
3270
+ throw new (0, _chunkU35MG4TFcjs.PaymentDeclinedError)("onBeforePay threw \u2014 refusing to pay.", {
3255
3271
  cause: err,
3256
3272
  reasonCode: "APPROVAL"
3257
3273
  });
3258
3274
  }
3259
3275
  if (!approved) {
3260
- throw new (0, _chunkPA6YD3HLcjs.PaymentDeclinedError)(
3276
+ throw new (0, _chunkU35MG4TFcjs.PaymentDeclinedError)(
3261
3277
  `onBeforePay declined ${quote.amountFormatted} ${_nullishCoalesce(quote.symbol, () => ( ""))}`.trimEnd() + ` on ${quote.network}.`,
3262
3278
  { reasonCode: "APPROVAL" }
3263
3279
  );
@@ -3282,7 +3298,7 @@ var PipRailClient = (_class2 = class {
3282
3298
  }
3283
3299
  async payAndConfirm(net, wallet, accept) {
3284
3300
  if (!net.supports(accept.network)) {
3285
- throw new (0, _chunkPA6YD3HLcjs.WrongChainError)(
3301
+ throw new (0, _chunkU35MG4TFcjs.WrongChainError)(
3286
3302
  `Challenge expects ${accept.network} but client is on ${net.network}.`
3287
3303
  );
3288
3304
  }
@@ -3335,7 +3351,7 @@ var PipRailClient = (_class2 = class {
3335
3351
  });
3336
3352
  } catch (err) {
3337
3353
  if (timeoutController.signal.aborted) {
3338
- throw new (0, _chunkPA6YD3HLcjs.PaymentTimeoutError)(
3354
+ throw new (0, _chunkU35MG4TFcjs.PaymentTimeoutError)(
3339
3355
  `Server did not respond within ${this.retryTimeoutMs}ms after broadcasting payment ${ref}. Re-verify or re-submit ref=${ref} \u2014 do NOT re-pay.`,
3340
3356
  { cause: err, ref }
3341
3357
  );
@@ -3357,7 +3373,7 @@ var PipRailClient = (_class2 = class {
3357
3373
  kind: "payment-failed",
3358
3374
  reason: `server returned 402 after broadcasting payment ${ref}${unconfirmedNote} (${why})`
3359
3375
  });
3360
- throw new (0, _chunkPA6YD3HLcjs.MaxRetriesExceededError)(
3376
+ throw new (0, _chunkU35MG4TFcjs.MaxRetriesExceededError)(
3361
3377
  `Server still returned 402 after ${attempts} attempt(s) with on-chain proof ref=${ref}${unconfirmedNote}. Last server rejection: ${why}. Re-verify or re-submit ref=${ref} before retrying \u2014 never re-pay (it would double-spend).`,
3362
3378
  { ref }
3363
3379
  );
@@ -3381,7 +3397,7 @@ var PipRailClient = (_class2 = class {
3381
3397
  */
3382
3398
  async payExactRail(net, wallet, accept, url, init, quote) {
3383
3399
  if (!net.payExact) {
3384
- throw new (0, _chunkPA6YD3HLcjs.UnsupportedSchemeError)(
3400
+ throw new (0, _chunkU35MG4TFcjs.UnsupportedSchemeError)(
3385
3401
  `the ${net.family} family can't pay a standard 'exact' rail (supported on EVM + Solana today).`
3386
3402
  );
3387
3403
  }
@@ -3391,7 +3407,7 @@ var PipRailClient = (_class2 = class {
3391
3407
  headers.set(HEADER_SIGNATURE, buildExactSignatureHeader({ accepted, payload }));
3392
3408
  const rejectDefinitive = (why2) => {
3393
3409
  this.safeEmit({ kind: "payment-failed", reason: `exact: facilitator rejected nonce=${nonce} (${why2})` });
3394
- throw new (0, _chunkPA6YD3HLcjs.MaxRetriesExceededError)(
3410
+ throw new (0, _chunkU35MG4TFcjs.MaxRetriesExceededError)(
3395
3411
  `exact: the facilitator rejected the payment (${why2}). Fix the cause, then re-present the SAME signed authorization (nonce=${nonce}) \u2014 do NOT re-sign a fresh nonce. ref=${nonce}.`,
3396
3412
  { ref: nonce }
3397
3413
  );
@@ -3414,7 +3430,7 @@ var PipRailClient = (_class2 = class {
3414
3430
  try {
3415
3431
  response = await fetch(url, { ..._nullishCoalesce(init, () => ( {})), headers, signal });
3416
3432
  } catch (err) {
3417
- throw new (0, _chunkPA6YD3HLcjs.PaymentTimeoutError)(
3433
+ throw new (0, _chunkU35MG4TFcjs.PaymentTimeoutError)(
3418
3434
  `exact: no response after submitting the authorization (nonce=${nonce}) to ${hostOf2(url)}. The facilitator may have already settled it \u2014 verify on-chain with authorizationState(${payerFrom}, ${nonce}) before re-presenting; do NOT re-pay.`,
3419
3435
  { cause: err, ref: nonce }
3420
3436
  );
@@ -3447,7 +3463,7 @@ var PipRailClient = (_class2 = class {
3447
3463
  kind: "payment-failed",
3448
3464
  reason: `exact: 402 after submitting authorization nonce=${nonce} (${why})`
3449
3465
  });
3450
- throw new (0, _chunkPA6YD3HLcjs.MaxRetriesExceededError)(
3466
+ throw new (0, _chunkU35MG4TFcjs.MaxRetriesExceededError)(
3451
3467
  `exact: server still returned 402 after submitting the signed authorization (nonce=${nonce}). Last rejection: ${why}. Re-present the SAME authorization \u2014 do NOT re-sign a fresh nonce; verify authorizationState(${payerFrom}, ${nonce}) first. ref=${nonce}.`,
3452
3468
  { ref: nonce }
3453
3469
  );
@@ -3601,7 +3617,7 @@ function summarizePlan(plan) {
3601
3617
  return `NOT payable: ${_nullishCoalesce(plan.fundingHint, () => ( `no settleable rail on ${plan.network}`))}`;
3602
3618
  }
3603
3619
  function explainDecline(err) {
3604
- if (!(err instanceof _chunkPA6YD3HLcjs.PipRailError)) {
3620
+ if (!(err instanceof _chunkU35MG4TFcjs.PipRailError)) {
3605
3621
  return `Payment failed: ${err instanceof Error ? err.message : String(err)}`;
3606
3622
  }
3607
3623
  switch (err.code) {
@@ -3647,6 +3663,18 @@ straight from your wallet to the server; PipRail custodies nothing. Follow this.
3647
3663
  and return the result.
3648
3664
  Always plan before you pay so you never commit to a payment you cannot finish.
3649
3665
 
3666
+ ## Gasless \u2014 the exact rail (zero gas for you)
3667
+ A 402 may offer up to two rails; you don't choose per payment \u2014 the client does, automatically:
3668
+ - onchain-proof (PipRail's default): you broadcast the payment yourself and pay the network gas
3669
+ (the native coin \u2014 ETH/SOL/\u2026). Works on every chain.
3670
+ - exact (the ratified x402 rail, opt-in): you only SIGN; the server \u2014 or a facilitator it chose
3671
+ (e.g. PayAI) \u2014 broadcasts it, so you pay ZERO gas (you need only the token, no native coin). It
3672
+ works on EVM + Solana, and the on-chain method (EIP-3009 / Permit2 / SVM) is picked automatically.
3673
+ When the exact scheme is enabled AND balance-aware routing is on, paying picks the cheapest
3674
+ settleable rail \u2014 i.e. the gasless exact one. Nothing changes in your loop: quote \u2192 plan \u2192 pay is
3675
+ identical. The exact scheme is OPT-IN by the operator (MCP: PIPRAIL_SCHEMES=onchain-proof,exact);
3676
+ you can't enable it yourself, but you can report when a 402 needs it (see UNSUPPORTED_SCHEME below).
3677
+
3650
3678
  ## Reading a refusal \u2014 never crash, never double-spend
3651
3679
  A failed pay returns a STRUCTURED object, never a thrown error you must catch:
3652
3680
  { ok:false, code, reason, explain, ref?, reasonCode?, declined? }
@@ -3664,9 +3692,13 @@ Branch on \`code\` (always reliable). Key cases:
3664
3692
  - code:'INSUFFICIENT_FUNDS' \u2014 top up the wallet (token and/or native gas), retry.
3665
3693
  - code:'PAYMENT_TIMEOUT' / 'MAX_RETRIES_EXCEEDED' / 'CONFIRMATION_TIMEOUT' \u2014 the
3666
3694
  payment may ALREADY be on-chain. Recover using the proof on \`.ref\` (re-verify
3667
- or re-submit it); never re-pay \u2014 a fresh payment would double-spend.
3695
+ or re-submit it); never re-pay \u2014 a fresh payment would double-spend. On a gasless
3696
+ exact rail \`.ref\` is the authorization NONCE, not a tx hash: re-present the SAME
3697
+ signed authorization, never sign a fresh one (that would risk a double-spend).
3668
3698
  - code:'NO_COMPATIBLE_ACCEPT' / 'UNSUPPORTED_SCHEME' \u2014 the 402 isn't payable on
3669
3699
  your chain/scheme; \`explain\` says whether it's the wrong chain or a scheme to enable.
3700
+ If it's a standard x402 server offering an exact rail, that's a config fix the operator makes
3701
+ once (enable the exact scheme); report it, don't retry the same call blindly.
3670
3702
 
3671
3703
  ## Knowing your leash \u2014 call piprail_budget
3672
3704
  piprail_budget tells you how much budget and time you have left, per
@@ -3875,14 +3907,14 @@ function paymentTools(client) {
3875
3907
  receipt: parseReceipt(res)
3876
3908
  };
3877
3909
  } catch (err) {
3878
- if (err instanceof _chunkPA6YD3HLcjs.PipRailError) {
3910
+ if (err instanceof _chunkU35MG4TFcjs.PipRailError) {
3879
3911
  const out = {
3880
3912
  ok: false,
3881
3913
  code: err.code,
3882
3914
  reason: err.message,
3883
3915
  explain: explainDecline(err)
3884
3916
  };
3885
- if (err instanceof _chunkPA6YD3HLcjs.PaymentDeclinedError) {
3917
+ if (err instanceof _chunkU35MG4TFcjs.PaymentDeclinedError) {
3886
3918
  out.declined = true;
3887
3919
  if (err.reasonCode) out.reasonCode = err.reasonCode;
3888
3920
  }
@@ -4116,13 +4148,13 @@ async function settleViaFacilitator(input) {
4116
4148
  try {
4117
4149
  verify = await post(`${base2}/verify`, body, auth);
4118
4150
  } catch (err) {
4119
- throw new (0, _chunkPA6YD3HLcjs.SettlementError)(
4151
+ throw new (0, _chunkU35MG4TFcjs.SettlementError)(
4120
4152
  `exact settle (facilitator ${base2}): /verify request failed (${err instanceof Error ? err.message : String(err)}).`,
4121
4153
  { cause: err }
4122
4154
  );
4123
4155
  }
4124
4156
  if (verify.status !== 200) {
4125
- throw new (0, _chunkPA6YD3HLcjs.SettlementError)(
4157
+ throw new (0, _chunkU35MG4TFcjs.SettlementError)(
4126
4158
  `exact settle (facilitator ${base2}): /verify returned HTTP ${verify.status} (transport/auth error).`
4127
4159
  );
4128
4160
  }
@@ -4138,13 +4170,13 @@ async function settleViaFacilitator(input) {
4138
4170
  try {
4139
4171
  settle = await post(`${base2}/settle`, body, auth);
4140
4172
  } catch (err) {
4141
- throw new (0, _chunkPA6YD3HLcjs.SettlementError)(
4173
+ throw new (0, _chunkU35MG4TFcjs.SettlementError)(
4142
4174
  `exact settle (facilitator ${base2}): /settle request failed (${err instanceof Error ? err.message : String(err)}).`,
4143
4175
  { cause: err }
4144
4176
  );
4145
4177
  }
4146
4178
  if (settle.status !== 200) {
4147
- throw new (0, _chunkPA6YD3HLcjs.SettlementError)(
4179
+ throw new (0, _chunkU35MG4TFcjs.SettlementError)(
4148
4180
  `exact settle (facilitator ${base2}): /settle returned HTTP ${settle.status} (transport/auth error).`
4149
4181
  );
4150
4182
  }
@@ -4199,6 +4231,7 @@ function createPaymentGate(options) {
4199
4231
  if (resolved) return resolved;
4200
4232
  const p = (async () => {
4201
4233
  const accepts = normaliseAccepts(options);
4234
+ const exactSkips = [];
4202
4235
  const specs = await Promise.all(
4203
4236
  accepts.map(async (a) => {
4204
4237
  const net = await resolveNetwork2({ chain: a.chain, rpcUrl: _nullishCoalesce(a.rpcUrl, () => ( options.rpcUrl)) });
@@ -4210,15 +4243,19 @@ function createPaymentGate(options) {
4210
4243
  }
4211
4244
  net.assertValidPayTo(payTo);
4212
4245
  const { asset, decimals, symbol } = net.resolveToken(a.token);
4213
- const amountBase = _chunkPA6YD3HLcjs.parseUnits.call(void 0, a.amount, decimals);
4246
+ const amountBase = _chunkU35MG4TFcjs.parseUnits.call(void 0, a.amount, decimals);
4214
4247
  const spec = { net, asset, decimals, symbol, amountBase, amountFormatted: a.amount, payTo };
4215
- if (options.exact) spec.exact = await resolveExactRail(net, asset);
4248
+ if (options.exact) {
4249
+ const outcome = await resolveExactRail(net, asset);
4250
+ if (outcome.rail) spec.exact = outcome.rail;
4251
+ else if (outcome.skipReason) exactSkips.push(outcome.skipReason);
4252
+ }
4216
4253
  return spec;
4217
4254
  })
4218
4255
  );
4219
4256
  if (options.exact && !specs.some((s) => s.exact)) {
4220
4257
  throw new Error(
4221
- "requirePayment: `exact` was requested but none of the offered rails support it. The standard `exact` rail is EVM ERC-20 (EIP-3009 \u2014 USDC / EURC \u2014 or Permit2, e.g. Binance-Peg USDC on BNB) or a Solana SPL token (SVM) \u2014 NOT native coins, NOT families without a standard `exact` scheme. Offer an EVM ERC-20 / Solana SPL token, or drop `exact`."
4258
+ "requirePayment: `exact` was requested but none of the offered rails support it. " + (exactSkips.length > 0 ? exactSkips.join(" ") : "The standard `exact` rail is EVM ERC-20 (EIP-3009 \u2014 USDC / EURC \u2014 or Permit2, e.g. Binance-Peg USDC on BNB) or a Solana SPL token (SVM) \u2014 NOT native coins, NOT families without a standard `exact` scheme. Offer an EVM ERC-20 / Solana SPL token, or drop `exact`.")
4222
4259
  );
4223
4260
  }
4224
4261
  return specs;
@@ -4231,10 +4268,11 @@ function createPaymentGate(options) {
4231
4268
  }
4232
4269
  async function resolveExactRail(net, asset) {
4233
4270
  const cfg = options.exact;
4234
- if (!net.resolveExactRail) return void 0;
4271
+ const settle = cfg.settle;
4272
+ if (!net.resolveExactRail) return {};
4235
4273
  let relayer;
4236
4274
  let feePayer;
4237
- if (cfg.settle === "self") {
4275
+ if (settle === "self") {
4238
4276
  if (cfg.relayer === void 0) {
4239
4277
  throw new Error(
4240
4278
  "requirePayment: exact `settle: 'self'` needs a `relayer` wallet (the gas-paying key that broadcasts the settle), e.g. exact: { settle: 'self', relayer: { privateKey } }."
@@ -4242,21 +4280,36 @@ function createPaymentGate(options) {
4242
4280
  }
4243
4281
  relayer = net.bindWallet(cfg.relayer);
4244
4282
  } else {
4245
- feePayer = cfg.settle.feePayer;
4283
+ feePayer = settle.feePayer;
4246
4284
  }
4247
4285
  const method = _nullishCoalesce(cfg.method, () => ( "auto"));
4248
4286
  let info = await net.resolveExactRail({ asset, method, relayer, feePayer });
4249
- if (!info && cfg.settle !== "self" && !feePayer) {
4250
- const discovered = await fetchFacilitatorFeePayer(cfg.settle.facilitator, net.network);
4251
- if (discovered) info = await net.resolveExactRail({ asset, method, relayer, feePayer: discovered });
4287
+ if (!info && settle !== "self" && !feePayer && asset !== "native") {
4288
+ const discovered = await fetchFacilitatorFeePayer(settle.facilitator, net.network);
4289
+ if (!discovered) {
4290
+ return {
4291
+ skipReason: `${net.network}: couldn't read a fee payer from the facilitator (${settle.facilitator}/supported) \u2014 it may be down, or may not sponsor this network. Set \`exact.settle.feePayer\` explicitly to remove the runtime dependency, switch to \`settle: 'self'\` with your own relayer, or retry.`
4292
+ };
4293
+ }
4294
+ info = await net.resolveExactRail({ asset, method, relayer, feePayer: discovered });
4252
4295
  }
4253
- if (!info) return void 0;
4254
- const mode = cfg.settle === "self" ? { kind: "self", relayer } : {
4296
+ if (!info) return {};
4297
+ if (settle !== "self" && info.method === "permit2") {
4298
+ if (cfg.method === "permit2") {
4299
+ throw new Error(
4300
+ "requirePayment: exact `method: 'permit2'` can't be settled by a third-party facilitator \u2014 facilitators settle the standard EIP-3009 (EVM) / SVM (Solana) schemes, not PipRail\u2019s Permit2 proxy. Use an EIP-3009 token (USDC / EURC) with the facilitator, or `settle: 'self'` (your own relayer) to settle Permit2 yourself."
4301
+ );
4302
+ }
4303
+ return {
4304
+ skipReason: `${net.network}: this token isn't EIP-3009 (auto-selected Permit2), which a third-party facilitator can't settle \u2014 it would serve onchain-proof only here. Use an EIP-3009 token (USDC / EURC) with the facilitator, or \`settle: 'self'\` to settle Permit2 yourself.`
4305
+ };
4306
+ }
4307
+ const mode = settle === "self" ? { kind: "self", relayer } : {
4255
4308
  kind: "facilitator",
4256
- url: cfg.settle.facilitator,
4257
- ...cfg.settle.authHeaders ? { authHeaders: cfg.settle.authHeaders } : {}
4309
+ url: settle.facilitator,
4310
+ ...settle.authHeaders ? { authHeaders: settle.authHeaders } : {}
4258
4311
  };
4259
- return { method: info.method, ...info.extra ? { extra: info.extra } : {}, mode };
4312
+ return { rail: { method: info.method, ...info.extra ? { extra: info.extra } : {}, mode } };
4260
4313
  }
4261
4314
  const hasCustomStore = Boolean(options.isUsed || options.markUsed);
4262
4315
  const localUsed = /* @__PURE__ */ new Map();
@@ -4363,7 +4416,7 @@ function createPaymentGate(options) {
4363
4416
  function enrichReceipt(spec, receipt) {
4364
4417
  let amountFormatted = receipt.amount;
4365
4418
  try {
4366
- amountFormatted = _chunkPA6YD3HLcjs.formatUnits.call(void 0, BigInt(receipt.amount), spec.decimals);
4419
+ amountFormatted = _chunkU35MG4TFcjs.formatUnits.call(void 0, BigInt(receipt.amount), spec.decimals);
4367
4420
  } catch (e34) {
4368
4421
  }
4369
4422
  return {
@@ -4553,7 +4606,7 @@ function requirePayment(options) {
4553
4606
  try {
4554
4607
  result = await gate.verify(_nullishCoalesce(req.headers[HEADER_SIGNATURE], () => ( req.headers[HEADER_SIGNATURE_V1])));
4555
4608
  } catch (err) {
4556
- if (err instanceof _chunkPA6YD3HLcjs.SettlementError) {
4609
+ if (err instanceof _chunkU35MG4TFcjs.SettlementError) {
4557
4610
  res.status(502);
4558
4611
  res.json({ x402Version: 2, error: "settlement_failed", detail: err.message });
4559
4612
  return;
@@ -4768,4 +4821,5 @@ async function deliverReceipt(receipt, options) {
4768
4821
 
4769
4822
 
4770
4823
 
4771
- 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.REGISTER_ATTRIBUTION = REGISTER_ATTRIBUTION; 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.appendAttribution = appendAttribution; 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;
4824
+
4825
+ exports.CHAINS = CHAINS; exports.ConfirmationTimeoutError = _chunkU35MG4TFcjs.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 = _chunkU35MG4TFcjs.InsufficientFundsError; exports.InvalidEnvelopeError = _chunkU35MG4TFcjs.InvalidEnvelopeError; exports.MaxRetriesExceededError = _chunkU35MG4TFcjs.MaxRetriesExceededError; exports.MissingDriverError = _chunkU35MG4TFcjs.MissingDriverError; exports.NoCompatibleAcceptError = _chunkU35MG4TFcjs.NoCompatibleAcceptError; exports.NonReplayableBodyError = _chunkU35MG4TFcjs.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 = _chunkU35MG4TFcjs.PaymentDeclinedError; exports.PaymentTimeoutError = _chunkU35MG4TFcjs.PaymentTimeoutError; exports.PipRailClient = PipRailClient; exports.PipRailError = _chunkU35MG4TFcjs.PipRailError; exports.REGISTER_ATTRIBUTION = REGISTER_ATTRIBUTION; exports.RecipientNotReadyError = _chunkU35MG4TFcjs.RecipientNotReadyError; exports.SettlementError = _chunkU35MG4TFcjs.SettlementError; exports.UnknownTokenError = _chunkU35MG4TFcjs.UnknownTokenError; exports.UnsupportedNetworkError = _chunkU35MG4TFcjs.UnsupportedNetworkError; exports.UnsupportedSchemeError = _chunkU35MG4TFcjs.UnsupportedSchemeError; exports.WalletRequiredError = _chunkU35MG4TFcjs.WalletRequiredError; exports.WrongChainError = _chunkU35MG4TFcjs.WrongChainError; exports.WrongFamilyError = _chunkU35MG4TFcjs.WrongFamilyError; exports.X402_EXACT_PERMIT2_PROXY = X402_EXACT_PERMIT2_PROXY; exports.agentGuide = agentGuide; exports.appendAttribution = appendAttribution; 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 = _chunkU35MG4TFcjs.toInsufficientFundsError; exports.toInvalidBody = toInvalidBody; exports.verify402IndexDomain = verify402IndexDomain;