@piprail/sdk 1.9.0 → 1.10.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.
Files changed (29) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/ERRORS.md +21 -8
  3. package/README.md +20 -0
  4. package/STANDARDS.md +5 -2
  5. package/dist/{algorand-IJJKE35X.cjs → algorand-MXUSKX46.cjs} +17 -17
  6. package/dist/{algorand-B67G4335.js → algorand-WGVF4KTU.js} +1 -1
  7. package/dist/{aptos-YQWTGFRZ.js → aptos-LPBLSEIQ.js} +1 -1
  8. package/dist/{aptos-X3G2UBYW.cjs → aptos-YT7SXWPF.cjs} +16 -16
  9. package/dist/{chunk-IQGT65WS.cjs → chunk-MDLZJGLY.cjs} +20 -16
  10. package/dist/{chunk-QDS6FBZP.js → chunk-SVMGHASK.js} +4 -0
  11. package/dist/index.cjs +811 -253
  12. package/dist/index.d.cts +400 -31
  13. package/dist/index.d.ts +400 -31
  14. package/dist/index.js +734 -176
  15. package/dist/{near-GGUHLXAF.cjs → near-7ZDNISUX.cjs} +19 -19
  16. package/dist/{near-7MBBCDUE.js → near-K6BDBABG.js} +1 -1
  17. package/dist/{solana-W24TCJV4.cjs → solana-PU7N2M64.cjs} +14 -14
  18. package/dist/{solana-7WJVZGDW.js → solana-S3UFI3FE.js} +1 -1
  19. package/dist/{stellar-HV6VGZX3.js → stellar-Q5PO23SC.js} +1 -1
  20. package/dist/{stellar-YMY3K2YB.cjs → stellar-VDQOFQEO.cjs} +21 -21
  21. package/dist/{sui-32KVESR5.cjs → sui-FKSMLKRF.cjs} +17 -17
  22. package/dist/{sui-2WFWVFJX.js → sui-WOXRKJXS.js} +1 -1
  23. package/dist/{ton-FIQGV2LC.cjs → ton-VK6KRJHP.cjs} +14 -14
  24. package/dist/{ton-DGZB7W4U.js → ton-WPTXGLVK.js} +1 -1
  25. package/dist/{tron-RLIL2FDI.js → tron-6GXBXTR4.js} +1 -1
  26. package/dist/{tron-ZSXAPZ2C.cjs → tron-WLOF5OUV.cjs} +24 -24
  27. package/dist/{xrpl-2PKP7HOI.cjs → xrpl-CMNI25BV.cjs} +21 -21
  28. package/dist/{xrpl-UEC2GYVV.js → xrpl-HEAPEXAM.js} +1 -1
  29. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -20,7 +20,8 @@
20
20
 
21
21
 
22
22
 
23
- var _chunkIQGT65WScjs = require('./chunk-IQGT65WS.cjs');
23
+
24
+ var _chunkMDLZJGLYcjs = require('./chunk-MDLZJGLY.cjs');
24
25
 
25
26
  // src/drivers/registry.ts
26
27
  var byFamily = /* @__PURE__ */ new Map();
@@ -49,13 +50,13 @@ function resolveNetwork(opts) {
49
50
  const family = familyForChain(opts.chain);
50
51
  const driver = byFamily.get(family);
51
52
  if (!driver) {
52
- throw new (0, _chunkIQGT65WScjs.UnsupportedNetworkError)(
53
+ throw new (0, _chunkMDLZJGLYcjs.UnsupportedNetworkError)(
53
54
  `No driver registered for the "${family}" family \u2014 it may not be mounted yet (use the async resolveNetwork()).`
54
55
  );
55
56
  }
56
57
  const net = driver.resolve(opts);
57
58
  if (!net) {
58
- throw new (0, _chunkIQGT65WScjs.UnsupportedNetworkError)(
59
+ throw new (0, _chunkMDLZJGLYcjs.UnsupportedNetworkError)(
59
60
  `The ${family} driver didn't recognise this chain input.`
60
61
  );
61
62
  }
@@ -311,12 +312,12 @@ function createWalletAdapter(config, resolved) {
311
312
  }
312
313
  const wc = config.walletClient;
313
314
  if (!wc.account) {
314
- throw new (0, _chunkIQGT65WScjs.WrongFamilyError)(
315
+ throw new (0, _chunkMDLZJGLYcjs.WrongFamilyError)(
315
316
  "chain is EVM; the provided walletClient has no attached account. Use `createWalletClient({ account, chain, transport })`, or pass { privateKey }."
316
317
  );
317
318
  }
318
319
  if (wc.chain && wc.chain.id !== resolved.chainId) {
319
- throw new (0, _chunkIQGT65WScjs.WrongChainError)(
320
+ throw new (0, _chunkMDLZJGLYcjs.WrongChainError)(
320
321
  `PipRailClient: walletClient is on chain ${wc.chain.id} but the SDK was configured with chain ${resolved.chainId}. They must match.`
321
322
  );
322
323
  }
@@ -483,24 +484,371 @@ function sumTransfersTo(logs, asset, payTo) {
483
484
  return { total, from };
484
485
  }
485
486
 
487
+ // src/drivers/evm/exact.ts
488
+
489
+
490
+
491
+
492
+
493
+ var EXACT_NETWORK_SLUGS = {
494
+ ethereum: 1,
495
+ base: 8453,
496
+ "base-sepolia": 84532,
497
+ arbitrum: 42161,
498
+ optimism: 10,
499
+ polygon: 137,
500
+ avalanche: 43114
501
+ };
502
+ function chainIdForExactNetwork(slug) {
503
+ return _nullishCoalesce(EXACT_NETWORK_SLUGS[slug], () => ( null));
504
+ }
505
+ var EIP3009_TYPES = {
506
+ TransferWithAuthorization: [
507
+ { name: "from", type: "address" },
508
+ { name: "to", type: "address" },
509
+ { name: "value", type: "uint256" },
510
+ { name: "validAfter", type: "uint256" },
511
+ { name: "validBefore", type: "uint256" },
512
+ { name: "nonce", type: "bytes32" }
513
+ ]
514
+ };
515
+ function parseExactRequirements(body) {
516
+ if (!body || typeof body !== "object") return null;
517
+ const accepts = body.accepts;
518
+ if (!Array.isArray(accepts)) return null;
519
+ const out = [];
520
+ for (const raw of accepts) {
521
+ if (!raw || typeof raw !== "object") continue;
522
+ const a = raw;
523
+ if (a.scheme !== "exact") continue;
524
+ const amount = _nullishCoalesce(a.maxAmountRequired, () => ( a.amount));
525
+ if (typeof a.network !== "string" || typeof amount !== "string" || typeof a.asset !== "string" || typeof a.payTo !== "string") {
526
+ continue;
527
+ }
528
+ out.push({
529
+ scheme: "exact",
530
+ network: a.network,
531
+ maxAmountRequired: amount,
532
+ asset: a.asset,
533
+ payTo: a.payTo,
534
+ maxTimeoutSeconds: typeof a.maxTimeoutSeconds === "number" ? a.maxTimeoutSeconds : 600,
535
+ ...a.extra && typeof a.extra === "object" ? { extra: a.extra } : {},
536
+ ...typeof a.description === "string" ? { description: a.description } : {},
537
+ ...typeof a.resource === "string" ? { resource: a.resource } : {}
538
+ });
539
+ }
540
+ return out;
541
+ }
542
+ async function buildExactAuthorization(params) {
543
+ const { account, accept, chainId, now, nonce } = params;
544
+ if (!account.signTypedData) {
545
+ throw new Error("buildExactAuthorization: the account cannot sign EIP-712 typed data.");
546
+ }
547
+ const authorization = {
548
+ from: account.address,
549
+ to: accept.payTo,
550
+ value: accept.maxAmountRequired,
551
+ validAfter: "0",
552
+ validBefore: String(now + accept.maxTimeoutSeconds),
553
+ nonce
554
+ };
555
+ const signature = await account.signTypedData({
556
+ domain: {
557
+ name: _nullishCoalesce(_optionalChain([accept, 'access', _ => _.extra, 'optionalAccess', _2 => _2.name]), () => ( "USD Coin")),
558
+ version: _nullishCoalesce(_optionalChain([accept, 'access', _3 => _3.extra, 'optionalAccess', _4 => _4.version]), () => ( "2")),
559
+ chainId,
560
+ verifyingContract: accept.asset
561
+ },
562
+ types: EIP3009_TYPES,
563
+ primaryType: "TransferWithAuthorization",
564
+ message: {
565
+ from: authorization.from,
566
+ to: authorization.to,
567
+ value: BigInt(authorization.value),
568
+ validAfter: BigInt(authorization.validAfter),
569
+ validBefore: BigInt(authorization.validBefore),
570
+ nonce: authorization.nonce
571
+ }
572
+ });
573
+ return { authorization, signature };
574
+ }
575
+ function base64(str) {
576
+ if (typeof Buffer !== "undefined") return Buffer.from(str, "utf8").toString("base64");
577
+ if (typeof btoa === "function" && typeof TextEncoder !== "undefined") {
578
+ const bytes = new TextEncoder().encode(str);
579
+ let binary = "";
580
+ for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
581
+ return btoa(binary);
582
+ }
583
+ throw new Error("No base64 encoder available in this runtime.");
584
+ }
585
+ function encodeXPaymentHeader(input) {
586
+ const payload = {
587
+ x402Version: _nullishCoalesce(input.x402Version, () => ( 1)),
588
+ scheme: "exact",
589
+ network: input.network,
590
+ payload: { signature: input.signature, authorization: input.authorization }
591
+ };
592
+ return base64(JSON.stringify(payload));
593
+ }
594
+ var eip3009Abi = [
595
+ {
596
+ type: "function",
597
+ name: "transferWithAuthorization",
598
+ stateMutability: "nonpayable",
599
+ outputs: [],
600
+ inputs: [
601
+ { name: "from", type: "address" },
602
+ { name: "to", type: "address" },
603
+ { name: "value", type: "uint256" },
604
+ { name: "validAfter", type: "uint256" },
605
+ { name: "validBefore", type: "uint256" },
606
+ { name: "nonce", type: "bytes32" },
607
+ { name: "v", type: "uint8" },
608
+ { name: "r", type: "bytes32" },
609
+ { name: "s", type: "bytes32" }
610
+ ]
611
+ },
612
+ {
613
+ type: "function",
614
+ name: "transferWithAuthorization",
615
+ stateMutability: "nonpayable",
616
+ outputs: [],
617
+ inputs: [
618
+ { name: "from", type: "address" },
619
+ { name: "to", type: "address" },
620
+ { name: "value", type: "uint256" },
621
+ { name: "validAfter", type: "uint256" },
622
+ { name: "validBefore", type: "uint256" },
623
+ { name: "nonce", type: "bytes32" },
624
+ { name: "signature", type: "bytes" }
625
+ ]
626
+ },
627
+ {
628
+ type: "function",
629
+ name: "authorizationState",
630
+ stateMutability: "view",
631
+ inputs: [
632
+ { name: "authorizer", type: "address" },
633
+ { name: "nonce", type: "bytes32" }
634
+ ],
635
+ outputs: [{ type: "bool" }]
636
+ },
637
+ { type: "function", name: "name", stateMutability: "view", inputs: [], outputs: [{ type: "string" }] },
638
+ { type: "function", name: "version", stateMutability: "view", inputs: [], outputs: [{ type: "string" }] }
639
+ ];
640
+ var ZERO_ADDR = "0x0000000000000000000000000000000000000000";
641
+ var ZERO_NONCE = `0x${"00".repeat(32)}`;
642
+ async function readExactDomain(publicClient, asset) {
643
+ if (asset === "native") return null;
644
+ let token;
645
+ try {
646
+ token = _viem.getAddress.call(void 0, asset);
647
+ } catch (e6) {
648
+ return null;
649
+ }
650
+ try {
651
+ const [name, version] = await Promise.all([
652
+ publicClient.readContract({ address: token, abi: eip3009Abi, functionName: "name" }),
653
+ publicClient.readContract({ address: token, abi: eip3009Abi, functionName: "version" }),
654
+ // The EIP-3009 probe: this view exists only on EIP-3009 tokens; it reverts on
655
+ // a plain ERC-20 / USDT, marking the token as not exact-payable.
656
+ publicClient.readContract({
657
+ address: token,
658
+ abi: eip3009Abi,
659
+ functionName: "authorizationState",
660
+ args: [ZERO_ADDR, ZERO_NONCE]
661
+ })
662
+ ]);
663
+ if (typeof name !== "string" || typeof version !== "string" || !name || !version) return null;
664
+ return { name, version };
665
+ } catch (e7) {
666
+ return null;
667
+ }
668
+ }
669
+ function shorten(msg) {
670
+ const oneLine = msg.replace(/\s+/g, " ").trim();
671
+ return oneLine.length > 200 ? `${oneLine.slice(0, 200)}\u2026` : oneLine;
672
+ }
673
+ async function verifyAndSettleExactEvm(input) {
674
+ const { publicClient, walletClient, account, chain, payload, accept } = input;
675
+ const token = _viem.getAddress.call(void 0, accept.asset);
676
+ const payTo = _viem.getAddress.call(void 0, accept.payTo);
677
+ const requiredAmount = BigInt(accept.amount);
678
+ let from;
679
+ let to;
680
+ let value;
681
+ let validAfter;
682
+ let validBefore;
683
+ let nonce;
684
+ try {
685
+ from = _viem.getAddress.call(void 0, payload.authorization.from);
686
+ to = _viem.getAddress.call(void 0, payload.authorization.to);
687
+ value = BigInt(payload.authorization.value);
688
+ validAfter = BigInt(payload.authorization.validAfter);
689
+ validBefore = BigInt(payload.authorization.validBefore);
690
+ nonce = payload.authorization.nonce;
691
+ if (!/^0x[0-9a-fA-F]{64}$/.test(nonce)) throw new Error("nonce must be 32-byte hex");
692
+ if (!/^0x[0-9a-fA-F]+$/.test(payload.signature)) throw new Error("signature must be hex");
693
+ } catch (err) {
694
+ return {
695
+ ok: false,
696
+ error: "signature_invalid",
697
+ detail: `Malformed exact authorization: ${err instanceof Error ? err.message : String(err)}.`
698
+ };
699
+ }
700
+ if (to !== payTo) {
701
+ return { ok: false, error: "wrong_recipient", detail: `Authorization pays ${to}, not ${payTo}.` };
702
+ }
703
+ if (value < requiredAmount) {
704
+ return { ok: false, error: "amount_too_low", detail: `Authorized ${value}, required ${requiredAmount}.` };
705
+ }
706
+ const now = BigInt(Math.floor(Date.now() / 1e3));
707
+ if (validBefore <= now) {
708
+ return { ok: false, error: "payment_expired", detail: `Authorization expired: validBefore ${validBefore} <= now ${now}.` };
709
+ }
710
+ let fromCode;
711
+ try {
712
+ fromCode = await publicClient.getCode({ address: from });
713
+ } catch (e8) {
714
+ return { ok: false, error: "tx_not_found", detail: `Could not read code at ${from} (transient RPC) \u2014 retry.` };
715
+ }
716
+ const isContractWallet = Boolean(fromCode && fromCode !== "0x");
717
+ if (!isContractWallet) {
718
+ let recovered;
719
+ try {
720
+ recovered = await _viem.recoverTypedDataAddress.call(void 0, {
721
+ domain: {
722
+ name: accept.extra.name,
723
+ version: accept.extra.version,
724
+ chainId: chain.id,
725
+ verifyingContract: token
726
+ },
727
+ types: EIP3009_TYPES,
728
+ primaryType: "TransferWithAuthorization",
729
+ message: { from, to, value, validAfter, validBefore, nonce },
730
+ signature: payload.signature
731
+ });
732
+ } catch (err) {
733
+ return { ok: false, error: "signature_invalid", detail: `Not a valid EIP-712 signature: ${shorten(err instanceof Error ? err.message : String(err))}.` };
734
+ }
735
+ if (recovered !== from) {
736
+ return { ok: false, error: "signature_invalid", detail: `Signature recovered to ${recovered}, not the authorizer ${from}.` };
737
+ }
738
+ }
739
+ try {
740
+ const used = await publicClient.readContract({
741
+ address: token,
742
+ abi: eip3009Abi,
743
+ functionName: "authorizationState",
744
+ args: [from, nonce]
745
+ });
746
+ if (used) {
747
+ return { ok: false, error: "tx_already_used", detail: `Authorization nonce ${nonce} already used or canceled on-chain.` };
748
+ }
749
+ } catch (e9) {
750
+ return { ok: false, error: "tx_not_found", detail: "Could not read authorizationState (transient RPC) \u2014 retry." };
751
+ }
752
+ const baseArgs = [from, to, value, validAfter, validBefore, nonce];
753
+ const isEcdsa = !isContractWallet && payload.signature.length - 2 === 130;
754
+ let writeArgs;
755
+ if (isEcdsa) {
756
+ const { r, s, yParity } = _viem.parseSignature.call(void 0, payload.signature);
757
+ writeArgs = [...baseArgs, BigInt(yParity + 27), r, s];
758
+ } else {
759
+ writeArgs = [...baseArgs, payload.signature];
760
+ }
761
+ try {
762
+ await publicClient.simulateContract({
763
+ account,
764
+ address: token,
765
+ abi: eip3009Abi,
766
+ functionName: "transferWithAuthorization",
767
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
768
+ args: writeArgs
769
+ });
770
+ } catch (err) {
771
+ const msg = err instanceof Error ? err.message : String(err);
772
+ if (/used or canceled/i.test(msg)) return { ok: false, error: "tx_already_used", detail: "Authorization is used or canceled." };
773
+ if (/expired|not yet valid/i.test(msg)) return { ok: false, error: "payment_expired", detail: shorten(msg) };
774
+ if (/invalid signature/i.test(msg)) return { ok: false, error: "signature_invalid", detail: shorten(msg) };
775
+ return { ok: false, error: "tx_reverted", detail: `transferWithAuthorization would revert: ${shorten(msg)}` };
776
+ }
777
+ let txHash;
778
+ try {
779
+ txHash = await walletClient.writeContract({
780
+ account,
781
+ chain,
782
+ address: token,
783
+ abi: eip3009Abi,
784
+ functionName: "transferWithAuthorization",
785
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
786
+ args: writeArgs
787
+ });
788
+ } catch (err) {
789
+ throw new (0, _chunkMDLZJGLYcjs.SettlementError)(
790
+ `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.`,
791
+ { cause: err }
792
+ );
793
+ }
794
+ try {
795
+ const confirmations = _nullishCoalesce(accept.extra.minConfirmations, () => ( 1));
796
+ const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash, confirmations });
797
+ if (receipt.status !== "success") {
798
+ return { ok: false, error: "tx_reverted", detail: `Settlement tx ${txHash} reverted on-chain.` };
799
+ }
800
+ } catch (err) {
801
+ throw new (0, _chunkMDLZJGLYcjs.SettlementError)(
802
+ `exact settle: broadcast ${txHash} but couldn't confirm it (${shorten(err instanceof Error ? err.message : String(err))}).`,
803
+ { cause: err }
804
+ );
805
+ }
806
+ return {
807
+ ok: true,
808
+ receipt: {
809
+ scheme: "exact",
810
+ success: true,
811
+ network: accept.network,
812
+ transaction: txHash,
813
+ asset: accept.asset,
814
+ amount: accept.amount,
815
+ payer: from,
816
+ payTo: accept.payTo,
817
+ verifiedAt: (/* @__PURE__ */ new Date()).toISOString()
818
+ }
819
+ };
820
+ }
821
+
486
822
  // src/x402.ts
487
823
  var HEADER_REQUIRED = "payment-required";
488
824
  var HEADER_SIGNATURE = "payment-signature";
489
825
  var HEADER_RESPONSE = "payment-response";
490
- function decodeBase64(b64) {
491
- if (typeof atob === "function") return atob(b64);
492
- if (typeof Buffer !== "undefined") return Buffer.from(b64, "base64").toString("utf8");
493
- throw new Error("No base64 decoder available in this runtime.");
494
- }
826
+ var HEADER_SIGNATURE_V1 = "x-payment";
827
+ var HEADER_RESPONSE_V1 = "x-payment-response";
495
828
  function encodeBase64(str) {
496
- if (typeof btoa === "function") return btoa(str);
497
829
  if (typeof Buffer !== "undefined") return Buffer.from(str, "utf8").toString("base64");
830
+ if (typeof btoa === "function" && typeof TextEncoder !== "undefined") {
831
+ const bytes = new TextEncoder().encode(str);
832
+ let binary = "";
833
+ for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
834
+ return btoa(binary);
835
+ }
498
836
  throw new Error("No base64 encoder available in this runtime.");
499
837
  }
838
+ function decodeBase64(b64) {
839
+ if (typeof Buffer !== "undefined") return Buffer.from(b64, "base64").toString("utf8");
840
+ if (typeof atob === "function" && typeof TextDecoder !== "undefined") {
841
+ const binary = atob(b64);
842
+ const bytes = new Uint8Array(binary.length);
843
+ for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
844
+ return new TextDecoder().decode(bytes);
845
+ }
846
+ throw new Error("No base64 decoder available in this runtime.");
847
+ }
500
848
  function fromBase64Json(b64) {
501
849
  try {
502
850
  return JSON.parse(decodeBase64(b64));
503
- } catch (e6) {
851
+ } catch (e10) {
504
852
  return null;
505
853
  }
506
854
  }
@@ -534,7 +882,7 @@ async function parseChallenge(response) {
534
882
  try {
535
883
  const body = await response.clone().json();
536
884
  if (isValidChallenge(body)) return body;
537
- } catch (e7) {
885
+ } catch (e11) {
538
886
  }
539
887
  return null;
540
888
  }
@@ -549,7 +897,7 @@ function parseSignatureHeader(value) {
549
897
  if (!parsed || typeof parsed !== "object") return null;
550
898
  const v = parsed;
551
899
  const accepted = v.accepted;
552
- const scheme = _nullishCoalesce(_optionalChain([accepted, 'optionalAccess', _ => _.scheme]), () => ( v.scheme));
900
+ const scheme = _nullishCoalesce(_optionalChain([accepted, 'optionalAccess', _5 => _5.scheme]), () => ( v.scheme));
553
901
  if (scheme !== "onchain-proof") return null;
554
902
  const payload = v.payload;
555
903
  if (!payload || typeof payload.txHash !== "string" || typeof payload.nonce !== "string") {
@@ -557,6 +905,36 @@ function parseSignatureHeader(value) {
557
905
  }
558
906
  return parsed;
559
907
  }
908
+ function parseExactPaymentHeader(value) {
909
+ const parsed = fromBase64Json(value);
910
+ if (!parsed || typeof parsed !== "object") return null;
911
+ const v = parsed;
912
+ const accepted = _nullishCoalesce(v.accepted, () => ( null));
913
+ const scheme = _nullishCoalesce(_optionalChain([accepted, 'optionalAccess', _6 => _6.scheme]), () => ( v.scheme));
914
+ if (scheme !== "exact") return null;
915
+ const network = _nullishCoalesce(_optionalChain([accepted, 'optionalAccess', _7 => _7.network]), () => ( v.network));
916
+ if (typeof network !== "string") return null;
917
+ const payload = v.payload;
918
+ if (!payload || typeof payload !== "object") return null;
919
+ const signature = payload.signature;
920
+ const authorization = payload.authorization;
921
+ if (typeof signature !== "string" || !authorization || typeof authorization !== "object") return null;
922
+ for (const k of ["from", "to", "value", "validAfter", "validBefore", "nonce"]) {
923
+ if (typeof authorization[k] !== "string") return null;
924
+ }
925
+ const x402Version = typeof v.x402Version === "number" ? v.x402Version : 2;
926
+ const asset = accepted && typeof accepted.asset === "string" ? accepted.asset : void 0;
927
+ return {
928
+ x402Version,
929
+ network,
930
+ ...asset ? { asset } : {},
931
+ payload: {
932
+ signature,
933
+ authorization
934
+ },
935
+ raw: v
936
+ };
937
+ }
560
938
  function isValidChallenge(value) {
561
939
  if (!value || typeof value !== "object") return false;
562
940
  const v = value;
@@ -568,7 +946,7 @@ function isValidChallenge(value) {
568
946
  function isValidReceipt(value) {
569
947
  if (!value || typeof value !== "object") return false;
570
948
  const v = value;
571
- if (v.scheme !== "onchain-proof") return false;
949
+ if (v.scheme !== "onchain-proof" && v.scheme !== "exact") return false;
572
950
  if (typeof v.transaction !== "string" && typeof v.txHash !== "string") return false;
573
951
  if (typeof v.payer !== "string") return false;
574
952
  return true;
@@ -591,7 +969,7 @@ var evmDriver = {
591
969
  let resolved;
592
970
  try {
593
971
  resolved = resolveChain(opts.chain, opts.rpcUrl);
594
- } catch (e8) {
972
+ } catch (e12) {
595
973
  return null;
596
974
  }
597
975
  return makeEvmNetwork(resolved);
@@ -619,15 +997,15 @@ function makeEvmNetwork(resolved) {
619
997
  const info = resolved.tokens[token.toUpperCase()];
620
998
  if (!info) {
621
999
  const known = Object.keys(resolved.tokens).join(", ") || "(none built in)";
622
- throw new (0, _chunkIQGT65WScjs.UnknownTokenError)(
1000
+ throw new (0, _chunkMDLZJGLYcjs.UnknownTokenError)(
623
1001
  `token "${token}" isn't built in for ${resolved.chain.name} (known: ${known}). Pass { address, decimals } instead, or use 'native'.`
624
1002
  );
625
1003
  }
626
1004
  return { asset: info.address, decimals: info.decimals, symbol: info.symbol };
627
1005
  }
628
- _chunkIQGT65WScjs.rejectForeignToken.call(void 0, token, "evm", network);
1006
+ _chunkMDLZJGLYcjs.rejectForeignToken.call(void 0, token, "evm", network);
629
1007
  if (!("address" in token)) {
630
- throw new (0, _chunkIQGT65WScjs.WrongFamilyError)(
1008
+ throw new (0, _chunkMDLZJGLYcjs.WrongFamilyError)(
631
1009
  `chain ${network} is EVM; a custom token must be { address, decimals }.`
632
1010
  );
633
1011
  }
@@ -647,7 +1025,7 @@ function makeEvmNetwork(resolved) {
647
1025
  let normalized;
648
1026
  try {
649
1027
  normalized = _viem.getAddress.call(void 0, asset);
650
- } catch (e9) {
1028
+ } catch (e13) {
651
1029
  return null;
652
1030
  }
653
1031
  for (const info of Object.values(resolved.tokens)) {
@@ -659,14 +1037,14 @@ function makeEvmNetwork(resolved) {
659
1037
  },
660
1038
  assertValidPayTo(payTo) {
661
1039
  if (!_viem.isAddress.call(void 0, payTo)) {
662
- throw new (0, _chunkIQGT65WScjs.WrongFamilyError)(
1040
+ throw new (0, _chunkMDLZJGLYcjs.WrongFamilyError)(
663
1041
  `chain ${network} is EVM, but payTo "${payTo}" is not a valid 0x address.`
664
1042
  );
665
1043
  }
666
1044
  },
667
1045
  bindWallet(wallet) {
668
1046
  if (typeof wallet !== "object" || wallet === null || !("privateKey" in wallet) && !("walletClient" in wallet)) {
669
- throw new (0, _chunkIQGT65WScjs.WrongFamilyError)(
1047
+ throw new (0, _chunkMDLZJGLYcjs.WrongFamilyError)(
670
1048
  `chain ${network} is EVM; wallet must be { privateKey } or { walletClient }.`
671
1049
  );
672
1050
  }
@@ -683,12 +1061,12 @@ function makeEvmNetwork(resolved) {
683
1061
  });
684
1062
  } catch (err) {
685
1063
  if (isViemInsufficientFunds(err)) {
686
- throw new (0, _chunkIQGT65WScjs.InsufficientFundsError)(
1064
+ throw new (0, _chunkMDLZJGLYcjs.InsufficientFundsError)(
687
1065
  err instanceof Error ? err.message : "Insufficient funds for payment.",
688
1066
  { cause: err }
689
1067
  );
690
1068
  }
691
- throw _nullishCoalesce(_chunkIQGT65WScjs.toInsufficientFundsError.call(void 0, err), () => ( err));
1069
+ throw _nullishCoalesce(_chunkMDLZJGLYcjs.toInsufficientFundsError.call(void 0, err), () => ( err));
692
1070
  }
693
1071
  },
694
1072
  async confirm(ref, minConfirmations) {
@@ -699,7 +1077,7 @@ function makeEvmNetwork(resolved) {
699
1077
  });
700
1078
  return { height: receipt.blockNumber.toString() };
701
1079
  } catch (err) {
702
- throw new (0, _chunkIQGT65WScjs.ConfirmationTimeoutError)(
1080
+ throw new (0, _chunkMDLZJGLYcjs.ConfirmationTimeoutError)(
703
1081
  `EVM tx ${ref} did not reach ${minConfirmations} confirmation(s) in time.`,
704
1082
  { cause: err }
705
1083
  );
@@ -710,16 +1088,16 @@ function makeEvmNetwork(resolved) {
710
1088
  const gasLimit = accept.asset === "native" ? 21000n : 65000n;
711
1089
  try {
712
1090
  const gasPrice = await publicClient.getGasPrice();
713
- return _chunkIQGT65WScjs.nativeCost.call(void 0, {
1091
+ return _chunkMDLZJGLYcjs.nativeCost.call(void 0, {
714
1092
  symbol,
715
1093
  decimals,
716
1094
  fee: gasPrice * gasLimit,
717
1095
  basis: "estimated",
718
1096
  detail: `~${gasLimit} gas @ ${gasPrice} wei/gas`
719
1097
  });
720
- } catch (e10) {
1098
+ } catch (e14) {
721
1099
  const gasPrice = 5000000000n;
722
- return _chunkIQGT65WScjs.nativeCost.call(void 0, {
1100
+ return _chunkMDLZJGLYcjs.nativeCost.call(void 0, {
723
1101
  symbol,
724
1102
  decimals,
725
1103
  fee: gasPrice * gasLimit,
@@ -740,7 +1118,7 @@ function makeEvmNetwork(resolved) {
740
1118
  functionName: "balanceOf",
741
1119
  args: [owner]
742
1120
  });
743
- } catch (e11) {
1121
+ } catch (e15) {
744
1122
  token = null;
745
1123
  }
746
1124
  return { token, native };
@@ -767,6 +1145,21 @@ function makeEvmNetwork(resolved) {
767
1145
  accept,
768
1146
  minConfirmations: accept.extra.minConfirmations
769
1147
  });
1148
+ },
1149
+ // Standard x402 `exact` rail (EIP-3009), seller side — EVM only.
1150
+ async exactDomain(asset) {
1151
+ return readExactDomain(publicClient, asset);
1152
+ },
1153
+ async settleExactSelf({ relayer, payload, accept }) {
1154
+ const a = relayer._native;
1155
+ return verifyAndSettleExactEvm({
1156
+ publicClient,
1157
+ walletClient: a.walletClient,
1158
+ account: a.account,
1159
+ chain: resolved.chain,
1160
+ payload,
1161
+ accept
1162
+ });
770
1163
  }
771
1164
  };
772
1165
  }
@@ -783,9 +1176,9 @@ var loaders = {
783
1176
  solana: async () => {
784
1177
  let mod;
785
1178
  try {
786
- mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./solana-W24TCJV4.cjs")));
1179
+ mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./solana-PU7N2M64.cjs")));
787
1180
  } catch (cause) {
788
- throw new (0, _chunkIQGT65WScjs.MissingDriverError)(
1181
+ throw new (0, _chunkMDLZJGLYcjs.MissingDriverError)(
789
1182
  `Solana selected, but its packages aren't installed. Run: npm install @solana/web3.js @solana/spl-token bs58`,
790
1183
  { cause }
791
1184
  );
@@ -795,9 +1188,9 @@ var loaders = {
795
1188
  ton: async () => {
796
1189
  let mod;
797
1190
  try {
798
- mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./ton-FIQGV2LC.cjs")));
1191
+ mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./ton-VK6KRJHP.cjs")));
799
1192
  } catch (cause) {
800
- throw new (0, _chunkIQGT65WScjs.MissingDriverError)(
1193
+ throw new (0, _chunkMDLZJGLYcjs.MissingDriverError)(
801
1194
  `TON selected, but its packages aren't installed. Run: npm install @ton/ton @ton/core @ton/crypto`,
802
1195
  { cause }
803
1196
  );
@@ -807,9 +1200,9 @@ var loaders = {
807
1200
  stellar: async () => {
808
1201
  let mod;
809
1202
  try {
810
- mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./stellar-YMY3K2YB.cjs")));
1203
+ mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./stellar-VDQOFQEO.cjs")));
811
1204
  } catch (cause) {
812
- throw new (0, _chunkIQGT65WScjs.MissingDriverError)(
1205
+ throw new (0, _chunkMDLZJGLYcjs.MissingDriverError)(
813
1206
  `Stellar selected, but its package isn't installed. Run: npm install @stellar/stellar-sdk`,
814
1207
  { cause }
815
1208
  );
@@ -819,9 +1212,9 @@ var loaders = {
819
1212
  xrpl: async () => {
820
1213
  let mod;
821
1214
  try {
822
- mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./xrpl-2PKP7HOI.cjs")));
1215
+ mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./xrpl-CMNI25BV.cjs")));
823
1216
  } catch (cause) {
824
- throw new (0, _chunkIQGT65WScjs.MissingDriverError)(
1217
+ throw new (0, _chunkMDLZJGLYcjs.MissingDriverError)(
825
1218
  `XRPL selected, but its package isn't installed. Run: npm install xrpl`,
826
1219
  { cause }
827
1220
  );
@@ -831,9 +1224,9 @@ var loaders = {
831
1224
  tron: async () => {
832
1225
  let mod;
833
1226
  try {
834
- mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./tron-ZSXAPZ2C.cjs")));
1227
+ mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./tron-WLOF5OUV.cjs")));
835
1228
  } catch (cause) {
836
- throw new (0, _chunkIQGT65WScjs.MissingDriverError)(
1229
+ throw new (0, _chunkMDLZJGLYcjs.MissingDriverError)(
837
1230
  `Tron selected, but its package isn't installed. Run: npm install tronweb`,
838
1231
  { cause }
839
1232
  );
@@ -843,9 +1236,9 @@ var loaders = {
843
1236
  sui: async () => {
844
1237
  let mod;
845
1238
  try {
846
- mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./sui-32KVESR5.cjs")));
1239
+ mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./sui-FKSMLKRF.cjs")));
847
1240
  } catch (cause) {
848
- throw new (0, _chunkIQGT65WScjs.MissingDriverError)(
1241
+ throw new (0, _chunkMDLZJGLYcjs.MissingDriverError)(
849
1242
  `Sui selected, but its package isn't installed. Run: npm install @mysten/sui`,
850
1243
  { cause }
851
1244
  );
@@ -855,9 +1248,9 @@ var loaders = {
855
1248
  near: async () => {
856
1249
  let mod;
857
1250
  try {
858
- mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./near-GGUHLXAF.cjs")));
1251
+ mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./near-7ZDNISUX.cjs")));
859
1252
  } catch (cause) {
860
- throw new (0, _chunkIQGT65WScjs.MissingDriverError)(
1253
+ throw new (0, _chunkMDLZJGLYcjs.MissingDriverError)(
861
1254
  `NEAR selected, but its package isn't installed. Run: npm install near-api-js`,
862
1255
  { cause }
863
1256
  );
@@ -867,9 +1260,9 @@ var loaders = {
867
1260
  aptos: async () => {
868
1261
  let mod;
869
1262
  try {
870
- mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./aptos-X3G2UBYW.cjs")));
1263
+ mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./aptos-YT7SXWPF.cjs")));
871
1264
  } catch (cause) {
872
- throw new (0, _chunkIQGT65WScjs.MissingDriverError)(
1265
+ throw new (0, _chunkMDLZJGLYcjs.MissingDriverError)(
873
1266
  `Aptos selected, but its package isn't installed. Run: npm install @aptos-labs/ts-sdk`,
874
1267
  { cause }
875
1268
  );
@@ -879,9 +1272,9 @@ var loaders = {
879
1272
  algorand: async () => {
880
1273
  let mod;
881
1274
  try {
882
- mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./algorand-IJJKE35X.cjs")));
1275
+ mod = await Promise.resolve().then(() => _interopRequireWildcard(require("./algorand-MXUSKX46.cjs")));
883
1276
  } catch (cause) {
884
- throw new (0, _chunkIQGT65WScjs.MissingDriverError)(
1277
+ throw new (0, _chunkMDLZJGLYcjs.MissingDriverError)(
885
1278
  `Algorand selected, but its package isn't installed. Run: npm install algosdk`,
886
1279
  { cause }
887
1280
  );
@@ -960,7 +1353,7 @@ async function searchOpenIndexes(opts = {}) {
960
1353
  async function safeSearch(run) {
961
1354
  try {
962
1355
  return await run();
963
- } catch (e12) {
1356
+ } catch (e16) {
964
1357
  return [];
965
1358
  }
966
1359
  }
@@ -1084,7 +1477,7 @@ async function readIndexError(res) {
1084
1477
  (p) => typeof p === "string" && p.length > 0
1085
1478
  );
1086
1479
  return parts.length ? [...new Set(parts)].join(" \u2014 ") : void 0;
1087
- } catch (e13) {
1480
+ } catch (e17) {
1088
1481
  return void 0;
1089
1482
  }
1090
1483
  }
@@ -1140,13 +1533,13 @@ async function readSiwxInfo(res) {
1140
1533
  try {
1141
1534
  const body = await res.json();
1142
1535
  const ext = body.extensions;
1143
- const siwx = _optionalChain([ext, 'optionalAccess', _2 => _2["sign-in-with-x"]]);
1144
- const info = _nullishCoalesce(_optionalChain([siwx, 'optionalAccess', _3 => _3.info]), () => ( siwx));
1536
+ const siwx = _optionalChain([ext, 'optionalAccess', _8 => _8["sign-in-with-x"]]);
1537
+ const info = _nullishCoalesce(_optionalChain([siwx, 'optionalAccess', _9 => _9.info]), () => ( siwx));
1145
1538
  if (info && typeof info.domain === "string" && info.domain.length > 0 && typeof info.nonce === "string" && info.nonce.length > 0 && typeof info.uri === "string" && info.uri.length > 0) {
1146
1539
  return info;
1147
1540
  }
1148
1541
  return null;
1149
- } catch (e14) {
1542
+ } catch (e18) {
1150
1543
  return null;
1151
1544
  }
1152
1545
  }
@@ -1194,7 +1587,7 @@ function mapRails(accepts) {
1194
1587
  }
1195
1588
  function matchesQuery(r, query) {
1196
1589
  const q = query.toLowerCase();
1197
- return r.resource.toLowerCase().includes(q) || (_nullishCoalesce(_optionalChain([r, 'access', _4 => _4.name, 'optionalAccess', _5 => _5.toLowerCase, 'call', _6 => _6(), 'access', _7 => _7.includes, 'call', _8 => _8(q)]), () => ( false))) || (_nullishCoalesce(_optionalChain([r, 'access', _9 => _9.description, 'optionalAccess', _10 => _10.toLowerCase, 'call', _11 => _11(), 'access', _12 => _12.includes, 'call', _13 => _13(q)]), () => ( false)));
1590
+ return r.resource.toLowerCase().includes(q) || (_nullishCoalesce(_optionalChain([r, 'access', _10 => _10.name, 'optionalAccess', _11 => _11.toLowerCase, 'call', _12 => _12(), 'access', _13 => _13.includes, 'call', _14 => _14(q)]), () => ( false))) || (_nullishCoalesce(_optionalChain([r, 'access', _15 => _15.description, 'optionalAccess', _16 => _16.toLowerCase, 'call', _17 => _17(), 'access', _18 => _18.includes, 'call', _19 => _19(q)]), () => ( false)));
1198
1591
  }
1199
1592
  function pickString(o, ...keys) {
1200
1593
  for (const k of keys) {
@@ -1226,7 +1619,7 @@ function firstArray(o, ...keys) {
1226
1619
  function hostOf(url) {
1227
1620
  try {
1228
1621
  return new URL(url).hostname;
1229
- } catch (e15) {
1622
+ } catch (e19) {
1230
1623
  return url;
1231
1624
  }
1232
1625
  }
@@ -1286,7 +1679,7 @@ function evaluatePolicy(intent, policy, spentForAssetBase) {
1286
1679
  }
1287
1680
  }
1288
1681
  if (policy.maxAmount !== void 0) {
1289
- const cap = _chunkIQGT65WScjs.floorUnits.call(void 0, policy.maxAmount, intent.decimals);
1682
+ const cap = _chunkMDLZJGLYcjs.floorUnits.call(void 0, policy.maxAmount, intent.decimals);
1290
1683
  if (intent.amountBase > cap) {
1291
1684
  return deny(
1292
1685
  `payment of ${intent.amountBase} base units exceeds policy.maxAmount ` + `(${policy.maxAmount} ${_nullishCoalesce(intent.symbol, () => ( ""))}).`.trimEnd()
@@ -1294,7 +1687,7 @@ function evaluatePolicy(intent, policy, spentForAssetBase) {
1294
1687
  }
1295
1688
  }
1296
1689
  if (policy.maxTotal !== void 0) {
1297
- const cap = _chunkIQGT65WScjs.floorUnits.call(void 0, policy.maxTotal, intent.decimals);
1690
+ const cap = _chunkMDLZJGLYcjs.floorUnits.call(void 0, policy.maxTotal, intent.decimals);
1298
1691
  if (spentForAssetBase + intent.amountBase > cap) {
1299
1692
  return deny(
1300
1693
  `this payment would push spend on ${_nullishCoalesce(intent.symbol, () => ( intent.asset))} past policy.maxTotal (${policy.maxTotal}); already spent ${spentForAssetBase} base units.`
@@ -1332,7 +1725,7 @@ var SpendLedger = (_class = class {constructor() { _class.prototype.__init.call(
1332
1725
  }
1333
1726
  /** Running total (base units) already spent on this (network, asset). */
1334
1727
  totalFor(network, asset) {
1335
- return _nullishCoalesce(_optionalChain([this, 'access', _14 => _14.buckets, 'access', _15 => _15.get, 'call', _16 => _16(keyFor(network, asset)), 'optionalAccess', _17 => _17.total]), () => ( 0n));
1728
+ return _nullishCoalesce(_optionalChain([this, 'access', _20 => _20.buckets, 'access', _21 => _21.get, 'call', _22 => _22(keyFor(network, asset)), 'optionalAccess', _23 => _23.total]), () => ( 0n));
1336
1729
  }
1337
1730
  /** An immutable snapshot of all spend so far. */
1338
1731
  summary() {
@@ -1344,7 +1737,7 @@ var SpendLedger = (_class = class {constructor() { _class.prototype.__init.call(
1344
1737
  symbol: b.symbol,
1345
1738
  decimals: b.decimals,
1346
1739
  totalBase: b.total.toString(),
1347
- totalFormatted: _chunkIQGT65WScjs.formatUnits.call(void 0, b.total, b.decimals),
1740
+ totalFormatted: _chunkMDLZJGLYcjs.formatUnits.call(void 0, b.total, b.decimals),
1348
1741
  count: b.count
1349
1742
  })),
1350
1743
  records: [...this.records]
@@ -1381,7 +1774,7 @@ var PipRailClient = (_class2 = class {
1381
1774
  safeEmit(event) {
1382
1775
  try {
1383
1776
  this.onEvent(event);
1384
- } catch (e16) {
1777
+ } catch (e20) {
1385
1778
  }
1386
1779
  }
1387
1780
  /** Auto-mount the chain's driver, resolve the network, and bind the wallet — once. */
@@ -1406,7 +1799,7 @@ var PipRailClient = (_class2 = class {
1406
1799
  * as-is) or a plain object (serialised as JSON).
1407
1800
  */
1408
1801
  post(url, body, init) {
1409
- const headers = new Headers(_optionalChain([init, 'optionalAccess', _18 => _18.headers]));
1802
+ const headers = new Headers(_optionalChain([init, 'optionalAccess', _24 => _24.headers]));
1410
1803
  let payload;
1411
1804
  if (body === void 0 || body === null) {
1412
1805
  payload = void 0;
@@ -1437,7 +1830,7 @@ var PipRailClient = (_class2 = class {
1437
1830
  * "0.05 USDC on Base, within budget → pay it." No funds move.
1438
1831
  */
1439
1832
  async quote(url, init) {
1440
- const res = await fetch(url, { ..._nullishCoalesce(init, () => ( {})), method: _nullishCoalesce(_optionalChain([init, 'optionalAccess', _19 => _19.method]), () => ( "GET")) });
1833
+ const res = await fetch(url, { ..._nullishCoalesce(init, () => ( {})), method: _nullishCoalesce(_optionalChain([init, 'optionalAccess', _25 => _25.method]), () => ( "GET")) });
1441
1834
  if (res.status !== 402) return null;
1442
1835
  const { quote } = await this.resolveChallenge(url, res);
1443
1836
  return quote;
@@ -1456,7 +1849,7 @@ var PipRailClient = (_class2 = class {
1456
1849
  * on Tron, where a USD₮ transfer can cost real TRX.
1457
1850
  */
1458
1851
  async estimateCost(url, init) {
1459
- const res = await fetch(url, { ..._nullishCoalesce(init, () => ( {})), method: _nullishCoalesce(_optionalChain([init, 'optionalAccess', _20 => _20.method]), () => ( "GET")) });
1852
+ const res = await fetch(url, { ..._nullishCoalesce(init, () => ( {})), method: _nullishCoalesce(_optionalChain([init, 'optionalAccess', _26 => _26.method]), () => ( "GET")) });
1460
1853
  if (res.status !== 402) return null;
1461
1854
  const { net, accept, quote } = await this.resolveChallenge(url, res);
1462
1855
  const cost = await net.estimateCost(accept);
@@ -1487,11 +1880,11 @@ var PipRailClient = (_class2 = class {
1487
1880
  * the plan yourself. No funds move.
1488
1881
  */
1489
1882
  async planPayment(url, init) {
1490
- const res = await fetch(url, { ..._nullishCoalesce(init, () => ( {})), method: _nullishCoalesce(_optionalChain([init, 'optionalAccess', _21 => _21.method]), () => ( "GET")) });
1883
+ const res = await fetch(url, { ..._nullishCoalesce(init, () => ( {})), method: _nullishCoalesce(_optionalChain([init, 'optionalAccess', _27 => _27.method]), () => ( "GET")) });
1491
1884
  if (res.status !== 402) return null;
1492
1885
  const challenge = await parseChallenge(res);
1493
1886
  if (!challenge) {
1494
- throw new (0, _chunkIQGT65WScjs.InvalidEnvelopeError)("402 response did not include a parseable x402 challenge.");
1887
+ throw new (0, _chunkMDLZJGLYcjs.InvalidEnvelopeError)("402 response did not include a parseable x402 challenge.");
1495
1888
  }
1496
1889
  const { net, wallet } = await this.ensure();
1497
1890
  return this.planFromChallenge(net, wallet, challenge, url);
@@ -1607,9 +2000,9 @@ var PipRailClient = (_class2 = class {
1607
2000
  * streams throw `NonReplayableBodyError`.
1608
2001
  */
1609
2002
  async fetch(url, init) {
1610
- const body = _optionalChain([init, 'optionalAccess', _22 => _22.body]);
2003
+ const body = _optionalChain([init, 'optionalAccess', _28 => _28.body]);
1611
2004
  if (body !== void 0 && body !== null && !isReplayableBodyInit(body)) {
1612
- throw new (0, _chunkIQGT65WScjs.NonReplayableBodyError)(
2005
+ throw new (0, _chunkMDLZJGLYcjs.NonReplayableBodyError)(
1613
2006
  "fetch(): init.body is not replayable. Pass a string, FormData, URLSearchParams, ArrayBuffer, or Blob \u2014 not a ReadableStream."
1614
2007
  );
1615
2008
  }
@@ -1619,11 +2012,11 @@ var PipRailClient = (_class2 = class {
1619
2012
  const { net, wallet, challenge } = resolved;
1620
2013
  let accept = resolved.accept;
1621
2014
  let quote = resolved.quote;
1622
- const autoRoute = _nullishCoalesce(_nullishCoalesce(_optionalChain([init, 'optionalAccess', _23 => _23.autoRoute]), () => ( this.opts.autoRoute)), () => ( false));
2015
+ const autoRoute = _nullishCoalesce(_nullishCoalesce(_optionalChain([init, 'optionalAccess', _29 => _29.autoRoute]), () => ( this.opts.autoRoute)), () => ( false));
1623
2016
  if (autoRoute) {
1624
2017
  const plan = await this.planFromChallenge(net, wallet, challenge, url);
1625
2018
  if (!plan.best) {
1626
- throw new (0, _chunkIQGT65WScjs.PaymentDeclinedError)(_nullishCoalesce(plan.fundingHint, () => ( "No rail is settleable for this payment.")));
2019
+ throw new (0, _chunkMDLZJGLYcjs.PaymentDeclinedError)(_nullishCoalesce(plan.fundingHint, () => ( "No rail is settleable for this payment.")));
1627
2020
  }
1628
2021
  accept = plan.best.accept;
1629
2022
  quote = plan.best.quote;
@@ -1644,7 +2037,7 @@ var PipRailClient = (_class2 = class {
1644
2037
  async resolveChallenge(url, response) {
1645
2038
  const challenge = await parseChallenge(response);
1646
2039
  if (!challenge) {
1647
- throw new (0, _chunkIQGT65WScjs.InvalidEnvelopeError)(
2040
+ throw new (0, _chunkMDLZJGLYcjs.InvalidEnvelopeError)(
1648
2041
  "402 response did not include a parseable x402 challenge."
1649
2042
  );
1650
2043
  }
@@ -1652,7 +2045,7 @@ var PipRailClient = (_class2 = class {
1652
2045
  const candidates = this.gatherCandidates(net, challenge);
1653
2046
  if (candidates.length === 0) {
1654
2047
  const networks = challenge.accepts.map((a) => a.network).join(", ");
1655
- throw new (0, _chunkIQGT65WScjs.NoCompatibleAcceptError)(
2048
+ throw new (0, _chunkMDLZJGLYcjs.NoCompatibleAcceptError)(
1656
2049
  `No accepts[] entry for ${net.network} (challenge offered: ${networks || "none"}).`
1657
2050
  );
1658
2051
  }
@@ -1663,7 +2056,10 @@ var PipRailClient = (_class2 = class {
1663
2056
  const chosen = _nullishCoalesce(priced.find((p) => p.quote.withinPolicy), () => ( priced[0]));
1664
2057
  return { net, wallet, accept: chosen.accept, challenge, quote: chosen.quote };
1665
2058
  }
1666
- /** The candidate accepts this client could pay: our scheme, on the bound network. */
2059
+ /** The candidate accepts this client could pay: our scheme, on the bound network.
2060
+ * A dual-advertised challenge may also carry standard `exact` rails — the PipRail
2061
+ * client ignores those (it pays the backendless `onchain-proof` rail); the type
2062
+ * predicate narrows the `X402AnyAccept` union to the rails we settle. */
1667
2063
  gatherCandidates(net, challenge) {
1668
2064
  return challenge.accepts.filter(
1669
2065
  (a) => a.scheme === "onchain-proof" && net.supports(a.network)
@@ -1726,16 +2122,16 @@ var PipRailClient = (_class2 = class {
1726
2122
  if (isNative) {
1727
2123
  if (nativeKnown && bal.native < amount + fee) {
1728
2124
  blockers.push("INSUFFICIENT_TOKEN");
1729
- shortfall.token = _chunkIQGT65WScjs.formatUnits.call(void 0, amount + fee - bal.native, quote.decimals);
2125
+ shortfall.token = _chunkMDLZJGLYcjs.formatUnits.call(void 0, amount + fee - bal.native, quote.decimals);
1730
2126
  }
1731
2127
  } else {
1732
2128
  if (tokenKnown && bal.token < amount) {
1733
2129
  blockers.push("INSUFFICIENT_TOKEN");
1734
- shortfall.token = _chunkIQGT65WScjs.formatUnits.call(void 0, amount - bal.token, quote.decimals);
2130
+ shortfall.token = _chunkMDLZJGLYcjs.formatUnits.call(void 0, amount - bal.token, quote.decimals);
1735
2131
  }
1736
2132
  if (nativeKnown && bal.native < fee) {
1737
2133
  blockers.push("INSUFFICIENT_GAS");
1738
- shortfall.native = _chunkIQGT65WScjs.formatUnits.call(void 0, fee - bal.native, cost.feeDecimals);
2134
+ shortfall.native = _chunkMDLZJGLYcjs.formatUnits.call(void 0, fee - bal.native, cost.feeDecimals);
1739
2135
  } else if (nativeKnown && fee > 0n && bal.native < fee * 3n / 2n) {
1740
2136
  warnings.push("THIN_GAS_MARGIN");
1741
2137
  }
@@ -1760,8 +2156,8 @@ var PipRailClient = (_class2 = class {
1760
2156
  blockers,
1761
2157
  warnings,
1762
2158
  balance: {
1763
- token: bal.token != null ? _chunkIQGT65WScjs.formatUnits.call(void 0, bal.token, quote.decimals) : null,
1764
- native: bal.native != null ? _chunkIQGT65WScjs.formatUnits.call(void 0, bal.native, cost.feeDecimals) : null
2159
+ token: bal.token != null ? _chunkMDLZJGLYcjs.formatUnits.call(void 0, bal.token, quote.decimals) : null,
2160
+ native: bal.native != null ? _chunkMDLZJGLYcjs.formatUnits.call(void 0, bal.native, cost.feeDecimals) : null
1765
2161
  },
1766
2162
  need: { token: quote.amountFormatted, native: cost.feeFormatted },
1767
2163
  ...shortfall.token || shortfall.native ? { shortfall } : {},
@@ -1772,15 +2168,15 @@ var PipRailClient = (_class2 = class {
1772
2168
  * driver's describeAsset) + the policy verdict + a symbol-mismatch flag. */
1773
2169
  buildQuote(net, accept, url, description) {
1774
2170
  if (!/^\d+$/.test(accept.amount)) {
1775
- throw new (0, _chunkIQGT65WScjs.InvalidEnvelopeError)(
2171
+ throw new (0, _chunkMDLZJGLYcjs.InvalidEnvelopeError)(
1776
2172
  `challenge amount "${accept.amount}" is not a base-unit integer.`
1777
2173
  );
1778
2174
  }
1779
2175
  const amountBase = BigInt(accept.amount);
1780
2176
  const described = net.describeAsset(accept.asset);
1781
- const decimals = _nullishCoalesce(_optionalChain([described, 'optionalAccess', _24 => _24.decimals]), () => ( accept.extra.decimals));
1782
- const symbol = _nullishCoalesce(_optionalChain([described, 'optionalAccess', _25 => _25.symbol]), () => ( accept.extra.symbol));
1783
- const amountFormatted = _chunkIQGT65WScjs.formatUnits.call(void 0, amountBase, decimals);
2177
+ const decimals = _nullishCoalesce(_optionalChain([described, 'optionalAccess', _30 => _30.decimals]), () => ( accept.extra.decimals));
2178
+ const symbol = _nullishCoalesce(_optionalChain([described, 'optionalAccess', _31 => _31.symbol]), () => ( accept.extra.symbol));
2179
+ const amountFormatted = _chunkMDLZJGLYcjs.formatUnits.call(void 0, amountBase, decimals);
1784
2180
  const intent = {
1785
2181
  host: hostOf2(url),
1786
2182
  chain: this.opts.chain,
@@ -1820,7 +2216,7 @@ var PipRailClient = (_class2 = class {
1820
2216
  * throwing PaymentDeclinedError, before any funds move. */
1821
2217
  async authorize(quote) {
1822
2218
  if (!quote.withinPolicy) {
1823
- throw new (0, _chunkIQGT65WScjs.PaymentDeclinedError)(
2219
+ throw new (0, _chunkMDLZJGLYcjs.PaymentDeclinedError)(
1824
2220
  `Payment refused by policy: ${_nullishCoalesce(quote.policyReason, () => ( "not allowed"))}`
1825
2221
  );
1826
2222
  }
@@ -1830,12 +2226,12 @@ var PipRailClient = (_class2 = class {
1830
2226
  try {
1831
2227
  approved = await hook(quote);
1832
2228
  } catch (err) {
1833
- throw new (0, _chunkIQGT65WScjs.PaymentDeclinedError)("onBeforePay threw \u2014 refusing to pay.", {
2229
+ throw new (0, _chunkMDLZJGLYcjs.PaymentDeclinedError)("onBeforePay threw \u2014 refusing to pay.", {
1834
2230
  cause: err
1835
2231
  });
1836
2232
  }
1837
2233
  if (!approved) {
1838
- throw new (0, _chunkIQGT65WScjs.PaymentDeclinedError)(
2234
+ throw new (0, _chunkMDLZJGLYcjs.PaymentDeclinedError)(
1839
2235
  `onBeforePay declined ${quote.amountFormatted} ${_nullishCoalesce(quote.symbol, () => ( ""))}`.trimEnd() + ` on ${quote.network}.`
1840
2236
  );
1841
2237
  }
@@ -1859,7 +2255,7 @@ var PipRailClient = (_class2 = class {
1859
2255
  }
1860
2256
  async payAndConfirm(net, wallet, accept) {
1861
2257
  if (!net.supports(accept.network)) {
1862
- throw new (0, _chunkIQGT65WScjs.WrongChainError)(
2258
+ throw new (0, _chunkMDLZJGLYcjs.WrongChainError)(
1863
2259
  `Challenge expects ${accept.network} but client is on ${net.network}.`
1864
2260
  );
1865
2261
  }
@@ -1888,7 +2284,7 @@ var PipRailClient = (_class2 = class {
1888
2284
  accepted: accept,
1889
2285
  payload: { nonce: accept.extra.nonce, txHash: ref }
1890
2286
  };
1891
- const headers = new Headers(_optionalChain([originalInit, 'optionalAccess', _26 => _26.headers]));
2287
+ const headers = new Headers(_optionalChain([originalInit, 'optionalAccess', _32 => _32.headers]));
1892
2288
  headers.set(HEADER_SIGNATURE, buildSignatureHeader(signature));
1893
2289
  let lastResponse = null;
1894
2290
  let lastReason = null;
@@ -1903,7 +2299,7 @@ var PipRailClient = (_class2 = class {
1903
2299
  () => timeoutController.abort(),
1904
2300
  this.retryTimeoutMs
1905
2301
  );
1906
- const signal = _optionalChain([originalInit, 'optionalAccess', _27 => _27.signal]) && typeof AbortSignal.any === "function" ? AbortSignal.any([timeoutController.signal, originalInit.signal]) : timeoutController.signal;
2302
+ const signal = _optionalChain([originalInit, 'optionalAccess', _33 => _33.signal]) && typeof AbortSignal.any === "function" ? AbortSignal.any([timeoutController.signal, originalInit.signal]) : timeoutController.signal;
1907
2303
  try {
1908
2304
  lastResponse = await fetch(url, {
1909
2305
  ..._nullishCoalesce(originalInit, () => ( {})),
@@ -1912,7 +2308,7 @@ var PipRailClient = (_class2 = class {
1912
2308
  });
1913
2309
  } catch (err) {
1914
2310
  if (timeoutController.signal.aborted) {
1915
- throw new (0, _chunkIQGT65WScjs.PaymentTimeoutError)(
2311
+ throw new (0, _chunkMDLZJGLYcjs.PaymentTimeoutError)(
1916
2312
  `Server did not respond within ${this.retryTimeoutMs}ms after broadcasting payment ${ref}. Re-verify or re-submit ref=${ref} \u2014 do NOT re-pay.`,
1917
2313
  { cause: err, ref }
1918
2314
  );
@@ -1934,7 +2330,7 @@ var PipRailClient = (_class2 = class {
1934
2330
  kind: "payment-failed",
1935
2331
  reason: `server returned 402 after broadcasting payment ${ref}${unconfirmedNote} (${why})`
1936
2332
  });
1937
- throw new (0, _chunkIQGT65WScjs.MaxRetriesExceededError)(
2333
+ throw new (0, _chunkMDLZJGLYcjs.MaxRetriesExceededError)(
1938
2334
  `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).`,
1939
2335
  { ref }
1940
2336
  );
@@ -1943,7 +2339,7 @@ var PipRailClient = (_class2 = class {
1943
2339
  function safeBig(s) {
1944
2340
  try {
1945
2341
  return BigInt(s);
1946
- } catch (e17) {
2342
+ } catch (e21) {
1947
2343
  return 0n;
1948
2344
  }
1949
2345
  }
@@ -1976,10 +2372,10 @@ function buildFundingHint(options, chainLabel) {
1976
2372
  return `Couldn't fully read your wallet on ${chainLabel} (RPC throttled) \u2014 retry; you may already be able to pay ${target.quote.amountFormatted} ${sym}.`;
1977
2373
  }
1978
2374
  const parts = [];
1979
- if (target.blockers.includes("INSUFFICIENT_TOKEN") && _optionalChain([target, 'access', _28 => _28.shortfall, 'optionalAccess', _29 => _29.token])) {
2375
+ if (target.blockers.includes("INSUFFICIENT_TOKEN") && _optionalChain([target, 'access', _34 => _34.shortfall, 'optionalAccess', _35 => _35.token])) {
1980
2376
  parts.push(`top up ${target.shortfall.token} ${sym}`);
1981
2377
  }
1982
- if (target.blockers.includes("INSUFFICIENT_GAS") && _optionalChain([target, 'access', _30 => _30.shortfall, 'optionalAccess', _31 => _31.native])) {
2378
+ if (target.blockers.includes("INSUFFICIENT_GAS") && _optionalChain([target, 'access', _36 => _36.shortfall, 'optionalAccess', _37 => _37.native])) {
1983
2379
  parts.push(`add ~${target.shortfall.native} ${target.cost.feeSymbol} for gas`);
1984
2380
  }
1985
2381
  return parts.length ? `Can't settle on ${chainLabel}: ${parts.join(" and ")} (to pay ${target.quote.amountFormatted} ${sym}).` : `Can't settle on ${chainLabel} for ${target.quote.amountFormatted} ${sym}.`;
@@ -1993,7 +2389,7 @@ async function planAcross(clients, url, init) {
1993
2389
  const status = best ? "ready" : options.some((o) => o.state === "unknown") ? "unknown" : "blocked";
1994
2390
  return {
1995
2391
  url,
1996
- network: _nullishCoalesce(_optionalChain([best, 'optionalAccess', _32 => _32.accept, 'access', _33 => _33.network]), () => ( live[0].network)),
2392
+ network: _nullishCoalesce(_optionalChain([best, 'optionalAccess', _38 => _38.accept, 'access', _39 => _39.network]), () => ( live[0].network)),
1997
2393
  status,
1998
2394
  payable: best !== null,
1999
2395
  best,
@@ -2009,7 +2405,7 @@ function railOnNetwork(rail, matches) {
2009
2405
  function hostOf2(url) {
2010
2406
  try {
2011
2407
  return new URL(url).hostname;
2012
- } catch (e18) {
2408
+ } catch (e22) {
2013
2409
  return url;
2014
2410
  }
2015
2411
  }
@@ -2026,13 +2422,21 @@ function isReplayableBodyInit(value) {
2026
2422
  async function readInvalidReason(response) {
2027
2423
  try {
2028
2424
  const body = await response.clone().json();
2425
+ const ext = _optionalChain([body, 'optionalAccess', _40 => _40.extensions]);
2426
+ const piprail = _optionalChain([ext, 'optionalAccess', _41 => _41.piprail]);
2427
+ if (piprail && typeof piprail.code === "string") {
2428
+ return {
2429
+ error: piprail.code,
2430
+ detail: typeof piprail.detail === "string" ? piprail.detail : ""
2431
+ };
2432
+ }
2029
2433
  if (body && (body.status === "invalid" || typeof body.error === "string")) {
2030
2434
  return {
2031
2435
  error: typeof body.error === "string" ? body.error : "no error code",
2032
2436
  detail: typeof body.detail === "string" ? body.detail : ""
2033
2437
  };
2034
2438
  }
2035
- } catch (e19) {
2439
+ } catch (e23) {
2036
2440
  }
2037
2441
  return null;
2038
2442
  }
@@ -2043,7 +2447,7 @@ async function readBody(res) {
2043
2447
  if (!text) return null;
2044
2448
  try {
2045
2449
  return JSON.parse(text);
2046
- } catch (e20) {
2450
+ } catch (e24) {
2047
2451
  return text;
2048
2452
  }
2049
2453
  }
@@ -2214,7 +2618,7 @@ function paymentTools(client) {
2214
2618
  receipt: parseReceipt(res)
2215
2619
  };
2216
2620
  } catch (err) {
2217
- if (err instanceof _chunkIQGT65WScjs.PaymentDeclinedError) {
2621
+ if (err instanceof _chunkMDLZJGLYcjs.PaymentDeclinedError) {
2218
2622
  return { declined: true, reason: err.message };
2219
2623
  }
2220
2624
  throw err;
@@ -2257,6 +2661,100 @@ function paymentTools(client) {
2257
2661
  ];
2258
2662
  }
2259
2663
 
2664
+ // src/facilitator.ts
2665
+ function safeStringify(value) {
2666
+ return JSON.stringify(value, (_k, v) => typeof v === "bigint" ? v.toString() : v);
2667
+ }
2668
+ function mapReason(reason) {
2669
+ const r = (_nullishCoalesce(reason, () => ( ""))).toLowerCase();
2670
+ if (r.includes("signature")) return "signature_invalid";
2671
+ if (r.includes("recipient")) return "wrong_recipient";
2672
+ if (r.includes("value") || r.includes("amount")) return "amount_too_low";
2673
+ if (r.includes("valid_before") || r.includes("valid_after") || r.includes("expired")) return "payment_expired";
2674
+ if (r.includes("used") || r.includes("replay") || r.includes("nonce") || r.includes("transaction_state")) {
2675
+ return "tx_already_used";
2676
+ }
2677
+ return "tx_reverted";
2678
+ }
2679
+ async function post(url, body, headers) {
2680
+ const res = await fetch(url, {
2681
+ method: "POST",
2682
+ headers: { "content-type": "application/json", ...headers },
2683
+ body: safeStringify(body)
2684
+ });
2685
+ let json = null;
2686
+ try {
2687
+ json = await res.json();
2688
+ } catch (e25) {
2689
+ }
2690
+ return { status: res.status, json };
2691
+ }
2692
+ async function settleViaFacilitator(input) {
2693
+ const base2 = input.url.replace(/\/+$/, "");
2694
+ const body = {
2695
+ x402Version: input.x402Version,
2696
+ paymentPayload: input.paymentPayload,
2697
+ paymentRequirements: input.paymentRequirements
2698
+ };
2699
+ const auth = input.authHeaders ? await input.authHeaders() : {};
2700
+ let verify;
2701
+ try {
2702
+ verify = await post(`${base2}/verify`, body, auth);
2703
+ } catch (err) {
2704
+ throw new (0, _chunkMDLZJGLYcjs.SettlementError)(
2705
+ `exact settle (facilitator ${base2}): /verify request failed (${err instanceof Error ? err.message : String(err)}).`,
2706
+ { cause: err }
2707
+ );
2708
+ }
2709
+ if (verify.status !== 200) {
2710
+ throw new (0, _chunkMDLZJGLYcjs.SettlementError)(
2711
+ `exact settle (facilitator ${base2}): /verify returned HTTP ${verify.status} (transport/auth error).`
2712
+ );
2713
+ }
2714
+ const vr = _nullishCoalesce(verify.json, () => ( {}));
2715
+ if (vr.isValid === false) {
2716
+ return {
2717
+ ok: false,
2718
+ error: mapReason(vr.invalidReason),
2719
+ detail: `Facilitator rejected the payment: ${_nullishCoalesce(vr.invalidReason, () => ( "invalid"))}${vr.invalidMessage ? ` \u2014 ${vr.invalidMessage}` : ""}.`
2720
+ };
2721
+ }
2722
+ let settle;
2723
+ try {
2724
+ settle = await post(`${base2}/settle`, body, auth);
2725
+ } catch (err) {
2726
+ throw new (0, _chunkMDLZJGLYcjs.SettlementError)(
2727
+ `exact settle (facilitator ${base2}): /settle request failed (${err instanceof Error ? err.message : String(err)}).`,
2728
+ { cause: err }
2729
+ );
2730
+ }
2731
+ if (settle.status !== 200) {
2732
+ throw new (0, _chunkMDLZJGLYcjs.SettlementError)(
2733
+ `exact settle (facilitator ${base2}): /settle returned HTTP ${settle.status} (transport/auth error).`
2734
+ );
2735
+ }
2736
+ const sr = _nullishCoalesce(settle.json, () => ( {}));
2737
+ if (!sr.success) {
2738
+ return {
2739
+ ok: false,
2740
+ error: mapReason(sr.errorReason),
2741
+ detail: `Facilitator settlement failed: ${_nullishCoalesce(sr.errorReason, () => ( "unknown"))}${sr.errorMessage ? ` \u2014 ${sr.errorMessage}` : ""}.`
2742
+ };
2743
+ }
2744
+ const receipt = {
2745
+ scheme: "exact",
2746
+ success: true,
2747
+ network: input.receipt.network,
2748
+ transaction: sr.transaction,
2749
+ asset: input.receipt.asset,
2750
+ amount: input.receipt.amount,
2751
+ payer: _nullishCoalesce(_nullishCoalesce(sr.payer, () => ( input.payerHint)), () => ( "")),
2752
+ payTo: input.receipt.payTo,
2753
+ verifiedAt: (/* @__PURE__ */ new Date()).toISOString()
2754
+ };
2755
+ return { ok: true, receipt };
2756
+ }
2757
+
2260
2758
  // src/server.ts
2261
2759
  function toInvalidBody(result) {
2262
2760
  return { x402Version: 2, status: "invalid", error: result.error, detail: result.detail };
@@ -2283,9 +2781,10 @@ function createPaymentGate(options) {
2283
2781
  const genNonce = _nullishCoalesce(options.generateNonce, () => ( (() => globalThis.crypto.randomUUID())));
2284
2782
  let resolved;
2285
2783
  function ready() {
2286
- return resolved ??= (async () => {
2784
+ if (resolved) return resolved;
2785
+ const p = (async () => {
2287
2786
  const accepts = normaliseAccepts(options);
2288
- return Promise.all(
2787
+ const specs = await Promise.all(
2289
2788
  accepts.map(async (a) => {
2290
2789
  const net = await resolveNetwork2({ chain: a.chain, rpcUrl: _nullishCoalesce(a.rpcUrl, () => ( options.rpcUrl)) });
2291
2790
  const payTo = _nullishCoalesce(a.payTo, () => ( options.payTo));
@@ -2296,11 +2795,53 @@ function createPaymentGate(options) {
2296
2795
  }
2297
2796
  net.assertValidPayTo(payTo);
2298
2797
  const { asset, decimals, symbol } = net.resolveToken(a.token);
2299
- const amountBase = _chunkIQGT65WScjs.parseUnits.call(void 0, a.amount, decimals);
2300
- return { net, asset, decimals, symbol, amountBase, amountFormatted: a.amount, payTo };
2798
+ const amountBase = _chunkMDLZJGLYcjs.parseUnits.call(void 0, a.amount, decimals);
2799
+ const spec = { net, asset, decimals, symbol, amountBase, amountFormatted: a.amount, payTo };
2800
+ if (options.exact) spec.exact = await resolveExactRail(net, asset);
2801
+ return spec;
2301
2802
  })
2302
2803
  );
2804
+ if (options.exact && !specs.some((s) => s.exact)) {
2805
+ throw new Error(
2806
+ "requirePayment: `exact` was requested but none of the offered rails support it. The standard `exact` rail is EVM + EIP-3009 only (USDC / EURC) \u2014 not native coins, not USDT, not non-EVM chains. Offer an EVM EIP-3009 token, or drop `exact`."
2807
+ );
2808
+ }
2809
+ return specs;
2303
2810
  })();
2811
+ p.catch(() => {
2812
+ if (resolved === p) resolved = void 0;
2813
+ });
2814
+ resolved = p;
2815
+ return p;
2816
+ }
2817
+ async function resolveExactRail(net, asset) {
2818
+ const cfg = options.exact;
2819
+ if (net.family !== "evm" || asset === "native" || !net.exactDomain || !net.settleExactSelf) {
2820
+ return void 0;
2821
+ }
2822
+ const domain = await net.exactDomain(asset);
2823
+ if (!domain) {
2824
+ throw new Error(
2825
+ `requirePayment: \`exact\` requested for asset ${asset} on ${net.network}, but it isn't an EIP-3009 token (couldn't read name()/version()/authorizationState). The exact rail supports USDC / EURC and other EIP-3009 tokens \u2014 USDT and native coins need onchain-proof. (Or check your rpcUrl is reachable.)`
2826
+ );
2827
+ }
2828
+ if (cfg.settle === "self") {
2829
+ if (cfg.relayer === void 0) {
2830
+ throw new Error(
2831
+ "requirePayment: exact `settle: 'self'` needs a `relayer` wallet (the gas-paying key that broadcasts transferWithAuthorization), e.g. exact: { settle: 'self', relayer: { privateKey } }."
2832
+ );
2833
+ }
2834
+ const relayer = net.bindWallet(cfg.relayer);
2835
+ return { domain, mode: { kind: "self", relayer } };
2836
+ }
2837
+ return {
2838
+ domain,
2839
+ mode: {
2840
+ kind: "facilitator",
2841
+ url: cfg.settle.facilitator,
2842
+ ...cfg.settle.authHeaders ? { authHeaders: cfg.settle.authHeaders } : {}
2843
+ }
2844
+ };
2304
2845
  }
2305
2846
  const hasCustomStore = Boolean(options.isUsed || options.markUsed);
2306
2847
  const localUsed = /* @__PURE__ */ new Set();
@@ -2337,93 +2878,191 @@ function createPaymentGate(options) {
2337
2878
  }
2338
2879
  };
2339
2880
  }
2340
- async function challenge(resourceUrl = "") {
2881
+ function buildExactAccept(s) {
2882
+ const d = s.exact.domain;
2883
+ return {
2884
+ scheme: "exact",
2885
+ network: s.net.network,
2886
+ amount: s.amountBase.toString(),
2887
+ asset: s.asset,
2888
+ payTo: s.payTo,
2889
+ maxTimeoutSeconds,
2890
+ extra: {
2891
+ assetTransferMethod: "eip3009",
2892
+ name: d.name,
2893
+ version: d.version,
2894
+ minConfirmations,
2895
+ decimals: s.decimals,
2896
+ amountFormatted: s.amountFormatted,
2897
+ ...s.symbol ? { symbol: s.symbol } : {}
2898
+ }
2899
+ };
2900
+ }
2901
+ function buildAccepts(specs, nonce) {
2902
+ const out = [];
2903
+ for (const s of specs) {
2904
+ if (s.exact) out.push(buildExactAccept(s));
2905
+ out.push(buildAccept(s, nonce));
2906
+ }
2907
+ return out;
2908
+ }
2909
+ async function makeChallenge(resourceUrl, opts) {
2341
2910
  const specs = await ready();
2342
2911
  const nonce = genNonce();
2343
2912
  const challenge2 = {
2344
2913
  x402Version: 2,
2345
- error: null,
2346
2914
  resource: {
2347
2915
  url: resourceUrl,
2348
2916
  ...options.description ? { description: options.description } : {}
2349
2917
  },
2350
- accepts: specs.map((s) => buildAccept(s, nonce))
2918
+ accepts: buildAccepts(specs, nonce),
2919
+ ..._optionalChain([opts, 'optionalAccess', _42 => _42.error]) ? { error: opts.error } : {},
2920
+ ..._optionalChain([opts, 'optionalAccess', _43 => _43.extensions]) ? { extensions: opts.extensions } : {}
2351
2921
  };
2352
2922
  return { challenge: challenge2, requiredHeader: buildChallengeHeader(challenge2) };
2353
2923
  }
2924
+ async function challenge(resourceUrl = "") {
2925
+ return makeChallenge(resourceUrl);
2926
+ }
2354
2927
  async function asChallenge() {
2355
- const { challenge: c, requiredHeader } = await challenge();
2928
+ const { challenge: c, requiredHeader } = await makeChallenge("");
2356
2929
  return { kind: "challenge", challenge: c, requiredHeader, statusCode: 402 };
2357
2930
  }
2931
+ async function rejection(code, detail) {
2932
+ const { challenge: c, requiredHeader } = await makeChallenge("", {
2933
+ error: `${code}: ${detail}`,
2934
+ extensions: { piprail: { code, detail } }
2935
+ });
2936
+ return { kind: "invalid", error: code, detail, challenge: c, requiredHeader, statusCode: 402 };
2937
+ }
2938
+ function fireOnPaid(receipt) {
2939
+ if (options.onPaid) {
2940
+ try {
2941
+ options.onPaid(receipt);
2942
+ } catch (e26) {
2943
+ }
2944
+ }
2945
+ }
2358
2946
  async function describe(resourceUrl = "") {
2359
2947
  const specs = await ready();
2360
- const accepts = specs.map((s) => ({
2361
- scheme: "onchain-proof",
2362
- network: s.net.network,
2363
- asset: s.asset,
2364
- payTo: s.payTo,
2365
- amount: s.amountBase.toString(),
2366
- amountFormatted: s.amountFormatted,
2367
- decimals: s.decimals,
2368
- maxTimeoutSeconds,
2369
- ...s.symbol ? { symbol: s.symbol } : {}
2370
- }));
2948
+ const accepts = [];
2949
+ for (const s of specs) {
2950
+ const base2 = {
2951
+ network: s.net.network,
2952
+ asset: s.asset,
2953
+ payTo: s.payTo,
2954
+ amount: s.amountBase.toString(),
2955
+ amountFormatted: s.amountFormatted,
2956
+ decimals: s.decimals,
2957
+ maxTimeoutSeconds,
2958
+ ...s.symbol ? { symbol: s.symbol } : {}
2959
+ };
2960
+ if (s.exact) accepts.push({ scheme: "exact", ...base2 });
2961
+ accepts.push({ scheme: "onchain-proof", ...base2 });
2962
+ }
2371
2963
  return {
2372
2964
  url: resourceUrl,
2373
2965
  ...options.description ? { description: options.description } : {},
2374
2966
  accepts
2375
2967
  };
2376
2968
  }
2377
- async function verify(paymentSignature) {
2378
- const raw = normaliseHeader(paymentSignature);
2379
- if (!raw) return asChallenge();
2380
- const sig = parseSignatureHeader(raw);
2381
- if (!sig || !sig.accepted || typeof sig.accepted.network !== "string" || typeof sig.accepted.asset !== "string") {
2382
- return asChallenge();
2383
- }
2969
+ async function verifyOnchainProof(sig) {
2384
2970
  const specs = await ready();
2385
2971
  const spec = specs.find(
2386
2972
  (s) => s.net.network === sig.accepted.network && s.asset === sig.accepted.asset
2387
2973
  );
2388
2974
  if (!spec) {
2389
- return {
2390
- kind: "invalid",
2391
- error: "transfer_not_found",
2392
- detail: `Proof claims ${sig.accepted.asset} on ${sig.accepted.network}, which this resource doesn't accept (offered: ${specs.map((s) => `${s.asset}@${s.net.network}`).join(", ")}).`,
2393
- statusCode: 402
2394
- };
2975
+ return rejection(
2976
+ "transfer_not_found",
2977
+ `Proof claims ${sig.accepted.asset} on ${sig.accepted.network}, which this resource doesn't accept (offered: ${specs.map((s) => `${s.asset}@${s.net.network}`).join(", ")}).`
2978
+ );
2395
2979
  }
2396
2980
  const ref = sig.payload.txHash;
2397
- if (await claimTx(ref)) {
2398
- return {
2399
- kind: "invalid",
2400
- error: "tx_already_used",
2401
- detail: `Proof ${ref} was already redeemed.`,
2402
- statusCode: 402
2403
- };
2404
- }
2981
+ if (await claimTx(ref)) return rejection("tx_already_used", `Proof ${ref} was already redeemed.`);
2405
2982
  const result = await spec.net.verify(ref, buildAccept(spec, sig.payload.nonce));
2406
2983
  if (!result.ok) {
2407
2984
  await settleTx(ref, false);
2408
- return {
2409
- kind: "invalid",
2410
- error: result.error,
2411
- detail: result.detail,
2412
- statusCode: 402
2413
- };
2985
+ return rejection(result.error, result.detail);
2414
2986
  }
2415
2987
  await settleTx(ref, true);
2416
- if (options.onPaid) {
2417
- try {
2418
- options.onPaid(result.receipt);
2419
- } catch (e21) {
2988
+ fireOnPaid(result.receipt);
2989
+ return { kind: "paid", receipt: result.receipt, receiptHeader: buildReceiptHeader(result.receipt) };
2990
+ }
2991
+ async function verifyExact(exact) {
2992
+ const specs = await ready();
2993
+ const exactSpecs = specs.filter((s) => s.exact);
2994
+ if (exactSpecs.length === 0) {
2995
+ return rejection("transfer_not_found", "This resource offers no standard `exact` rail.");
2996
+ }
2997
+ const isCaip = exact.network.startsWith("eip155:");
2998
+ let candidates = isCaip ? exactSpecs.filter((s) => s.net.network === exact.network) : exactSpecs;
2999
+ if (exact.asset) {
3000
+ candidates = candidates.filter((s) => s.asset.toLowerCase() === exact.asset.toLowerCase());
3001
+ }
3002
+ let spec = candidates[0];
3003
+ if (!isCaip && !exact.asset && exactSpecs.length > 1) spec = void 0;
3004
+ if (!spec && !isCaip && !exact.asset && exactSpecs.length === 1) spec = exactSpecs[0];
3005
+ if (!spec || !spec.exact) {
3006
+ return rejection(
3007
+ "transfer_not_found",
3008
+ `No \`exact\` rail offered for ${exact.network}${exact.asset ? `/${exact.asset}` : ""} (offered: ${exactSpecs.map((s) => `${s.asset}@${s.net.network}`).join(", ")}).`
3009
+ );
3010
+ }
3011
+ const nonce = exact.payload.authorization.nonce;
3012
+ if (await claimTx(nonce)) {
3013
+ return rejection("tx_already_used", `Authorization nonce ${nonce} was already redeemed.`);
3014
+ }
3015
+ const accept = buildExactAccept(spec);
3016
+ const mode = spec.exact.mode;
3017
+ let result;
3018
+ try {
3019
+ if (mode.kind === "self") {
3020
+ result = await spec.net.settleExactSelf({ relayer: mode.relayer, payload: exact.payload, accept });
3021
+ } else {
3022
+ result = await settleViaFacilitator({
3023
+ url: mode.url,
3024
+ ...mode.authHeaders ? { authHeaders: mode.authHeaders } : {},
3025
+ // PipRail always builds a v2-shaped paymentRequirements (CAIP-2 network + `amount`),
3026
+ // so force x402Version:2 — echoing a v1 client's version here would hand the facilitator
3027
+ // a self-inconsistent request (v1 envelope, v2 requirements). The inner payload is
3028
+ // byte-identical across versions, so forwarding it verbatim is fine.
3029
+ x402Version: 2,
3030
+ paymentPayload: exact.raw,
3031
+ paymentRequirements: {
3032
+ scheme: "exact",
3033
+ network: accept.network,
3034
+ asset: accept.asset,
3035
+ amount: accept.amount,
3036
+ payTo: accept.payTo,
3037
+ maxTimeoutSeconds: accept.maxTimeoutSeconds,
3038
+ extra: { name: accept.extra.name, version: accept.extra.version }
3039
+ },
3040
+ receipt: { network: accept.network, asset: accept.asset, payTo: accept.payTo, amount: accept.amount },
3041
+ payerHint: exact.payload.authorization.from
3042
+ });
2420
3043
  }
3044
+ } catch (err) {
3045
+ await settleTx(nonce, false);
3046
+ throw err;
2421
3047
  }
2422
- return {
2423
- kind: "paid",
2424
- receipt: result.receipt,
2425
- receiptHeader: buildReceiptHeader(result.receipt)
2426
- };
3048
+ if (!result.ok) {
3049
+ await settleTx(nonce, false);
3050
+ return rejection(result.error, result.detail);
3051
+ }
3052
+ await settleTx(nonce, true);
3053
+ fireOnPaid(result.receipt);
3054
+ return { kind: "paid", receipt: result.receipt, receiptHeader: buildReceiptHeader(result.receipt) };
3055
+ }
3056
+ async function verify(paymentSignature) {
3057
+ const raw = normaliseHeader(paymentSignature);
3058
+ if (!raw) return asChallenge();
3059
+ const sig = parseSignatureHeader(raw);
3060
+ if (sig && sig.accepted && typeof sig.accepted.network === "string" && typeof sig.accepted.asset === "string") {
3061
+ return verifyOnchainProof(sig);
3062
+ }
3063
+ const exact = parseExactPaymentHeader(raw);
3064
+ if (exact) return verifyExact(exact);
3065
+ return asChallenge();
2427
3066
  }
2428
3067
  return { challenge, verify, describe };
2429
3068
  }
@@ -2432,14 +3071,20 @@ function requirePayment(options) {
2432
3071
  return async (req, res, next) => {
2433
3072
  let result;
2434
3073
  try {
2435
- result = await gate.verify(req.headers[HEADER_SIGNATURE]);
3074
+ result = await gate.verify(_nullishCoalesce(req.headers[HEADER_SIGNATURE], () => ( req.headers[HEADER_SIGNATURE_V1])));
2436
3075
  } catch (err) {
3076
+ if (err instanceof _chunkMDLZJGLYcjs.SettlementError) {
3077
+ res.status(502);
3078
+ res.json({ x402Version: 2, error: "settlement_failed", detail: err.message });
3079
+ return;
3080
+ }
2437
3081
  next(err);
2438
3082
  return;
2439
3083
  }
2440
3084
  switch (result.kind) {
2441
3085
  case "paid":
2442
3086
  res.setHeader(HEADER_RESPONSE, result.receiptHeader);
3087
+ res.setHeader(HEADER_RESPONSE_V1, result.receiptHeader);
2443
3088
  return next();
2444
3089
  case "challenge":
2445
3090
  res.setHeader(HEADER_REQUIRED, result.requiredHeader);
@@ -2447,8 +3092,9 @@ function requirePayment(options) {
2447
3092
  res.json(result.challenge);
2448
3093
  return;
2449
3094
  case "invalid":
3095
+ res.setHeader(HEADER_REQUIRED, result.requiredHeader);
2450
3096
  res.status(result.statusCode);
2451
- res.json(toInvalidBody(result));
3097
+ res.json(result.challenge);
2452
3098
  return;
2453
3099
  }
2454
3100
  };
@@ -2458,110 +3104,12 @@ function normaliseHeader(value) {
2458
3104
  return value;
2459
3105
  }
2460
3106
 
2461
- // src/drivers/evm/exact.ts
2462
- var EXACT_NETWORK_SLUGS = {
2463
- ethereum: 1,
2464
- base: 8453,
2465
- "base-sepolia": 84532,
2466
- arbitrum: 42161,
2467
- optimism: 10,
2468
- polygon: 137,
2469
- avalanche: 43114
2470
- };
2471
- function chainIdForExactNetwork(slug) {
2472
- return _nullishCoalesce(EXACT_NETWORK_SLUGS[slug], () => ( null));
2473
- }
2474
- var EIP3009_TYPES = {
2475
- TransferWithAuthorization: [
2476
- { name: "from", type: "address" },
2477
- { name: "to", type: "address" },
2478
- { name: "value", type: "uint256" },
2479
- { name: "validAfter", type: "uint256" },
2480
- { name: "validBefore", type: "uint256" },
2481
- { name: "nonce", type: "bytes32" }
2482
- ]
2483
- };
2484
- function parseExactRequirements(body) {
2485
- if (!body || typeof body !== "object") return null;
2486
- const accepts = body.accepts;
2487
- if (!Array.isArray(accepts)) return null;
2488
- const out = [];
2489
- for (const raw of accepts) {
2490
- if (!raw || typeof raw !== "object") continue;
2491
- const a = raw;
2492
- if (a.scheme !== "exact") continue;
2493
- const amount = _nullishCoalesce(a.maxAmountRequired, () => ( a.amount));
2494
- if (typeof a.network !== "string" || typeof amount !== "string" || typeof a.asset !== "string" || typeof a.payTo !== "string") {
2495
- continue;
2496
- }
2497
- out.push({
2498
- scheme: "exact",
2499
- network: a.network,
2500
- maxAmountRequired: amount,
2501
- asset: a.asset,
2502
- payTo: a.payTo,
2503
- maxTimeoutSeconds: typeof a.maxTimeoutSeconds === "number" ? a.maxTimeoutSeconds : 600,
2504
- ...a.extra && typeof a.extra === "object" ? { extra: a.extra } : {},
2505
- ...typeof a.description === "string" ? { description: a.description } : {},
2506
- ...typeof a.resource === "string" ? { resource: a.resource } : {}
2507
- });
2508
- }
2509
- return out;
2510
- }
2511
- async function buildExactAuthorization(params) {
2512
- const { account, accept, chainId, now, nonce } = params;
2513
- if (!account.signTypedData) {
2514
- throw new Error("buildExactAuthorization: the account cannot sign EIP-712 typed data.");
2515
- }
2516
- const authorization = {
2517
- from: account.address,
2518
- to: accept.payTo,
2519
- value: accept.maxAmountRequired,
2520
- validAfter: "0",
2521
- validBefore: String(now + accept.maxTimeoutSeconds),
2522
- nonce
2523
- };
2524
- const signature = await account.signTypedData({
2525
- domain: {
2526
- name: _nullishCoalesce(_optionalChain([accept, 'access', _34 => _34.extra, 'optionalAccess', _35 => _35.name]), () => ( "USD Coin")),
2527
- version: _nullishCoalesce(_optionalChain([accept, 'access', _36 => _36.extra, 'optionalAccess', _37 => _37.version]), () => ( "2")),
2528
- chainId,
2529
- verifyingContract: accept.asset
2530
- },
2531
- types: EIP3009_TYPES,
2532
- primaryType: "TransferWithAuthorization",
2533
- message: {
2534
- from: authorization.from,
2535
- to: authorization.to,
2536
- value: BigInt(authorization.value),
2537
- validAfter: BigInt(authorization.validAfter),
2538
- validBefore: BigInt(authorization.validBefore),
2539
- nonce: authorization.nonce
2540
- }
2541
- });
2542
- return { authorization, signature };
2543
- }
2544
- function base64(str) {
2545
- if (typeof btoa === "function") return btoa(str);
2546
- if (typeof Buffer !== "undefined") return Buffer.from(str, "utf8").toString("base64");
2547
- throw new Error("No base64 encoder available in this runtime.");
2548
- }
2549
- function encodeXPaymentHeader(input) {
2550
- const payload = {
2551
- x402Version: _nullishCoalesce(input.x402Version, () => ( 1)),
2552
- scheme: "exact",
2553
- network: input.network,
2554
- payload: { signature: input.signature, authorization: input.authorization }
2555
- };
2556
- return base64(JSON.stringify(payload));
2557
- }
2558
-
2559
3107
  // src/discovery.ts
2560
3108
  var GENERATOR = "@piprail/sdk \xB7 https://piprail.com";
2561
3109
  function pathOf(url) {
2562
3110
  try {
2563
3111
  return new URL(url).pathname || "/";
2564
- } catch (e22) {
3112
+ } catch (e27) {
2565
3113
  return url.startsWith("/") ? url : `/${url}`;
2566
3114
  }
2567
3115
  }
@@ -2658,4 +3206,14 @@ function buildX402DnsTxt(input) {
2658
3206
 
2659
3207
 
2660
3208
 
2661
- exports.CHAINS = CHAINS; exports.ConfirmationTimeoutError = _chunkIQGT65WScjs.ConfirmationTimeoutError; exports.EIP3009_TYPES = EIP3009_TYPES; exports.EXACT_NETWORK_SLUGS = EXACT_NETWORK_SLUGS; exports.GENERATOR = GENERATOR; exports.InsufficientFundsError = _chunkIQGT65WScjs.InsufficientFundsError; exports.InvalidEnvelopeError = _chunkIQGT65WScjs.InvalidEnvelopeError; exports.MaxRetriesExceededError = _chunkIQGT65WScjs.MaxRetriesExceededError; exports.MissingDriverError = _chunkIQGT65WScjs.MissingDriverError; exports.NoCompatibleAcceptError = _chunkIQGT65WScjs.NoCompatibleAcceptError; exports.NonReplayableBodyError = _chunkIQGT65WScjs.NonReplayableBodyError; exports.PaymentDeclinedError = _chunkIQGT65WScjs.PaymentDeclinedError; exports.PaymentTimeoutError = _chunkIQGT65WScjs.PaymentTimeoutError; exports.PipRailClient = PipRailClient; exports.PipRailError = _chunkIQGT65WScjs.PipRailError; exports.RecipientNotReadyError = _chunkIQGT65WScjs.RecipientNotReadyError; exports.UnknownTokenError = _chunkIQGT65WScjs.UnknownTokenError; exports.UnsupportedNetworkError = _chunkIQGT65WScjs.UnsupportedNetworkError; exports.WrongChainError = _chunkIQGT65WScjs.WrongChainError; exports.WrongFamilyError = _chunkIQGT65WScjs.WrongFamilyError; exports.buildChallengeHeader = buildChallengeHeader; exports.buildExactAuthorization = buildExactAuthorization; exports.buildOpenApi = buildOpenApi; exports.buildReceiptHeader = buildReceiptHeader; exports.buildSignatureHeader = buildSignatureHeader; exports.buildWellKnownX402 = buildWellKnownX402; exports.buildX402DnsTxt = buildX402DnsTxt; exports.chainIdForExactNetwork = chainIdForExactNetwork; exports.createPaymentGate = createPaymentGate; exports.encodeXPaymentHeader = encodeXPaymentHeader; exports.evaluatePolicy = evaluatePolicy; exports.normalizeNetwork = normalizeNetwork; exports.parseChallenge = parseChallenge; exports.parseExactRequirements = parseExactRequirements; exports.parseReceipt = parseReceipt; exports.parseSignatureHeader = parseSignatureHeader; exports.paymentTools = paymentTools; exports.pickAccept = pickAccept; exports.planAcross = planAcross; exports.register402Index = register402Index; exports.registerDriver = registerDriver; exports.registerX402Scan = registerX402Scan; exports.requirePayment = requirePayment; exports.resolveChain = resolveChain; exports.searchOpenIndexes = searchOpenIndexes; exports.toInsufficientFundsError = _chunkIQGT65WScjs.toInsufficientFundsError; exports.toInvalidBody = toInvalidBody;
3209
+
3210
+
3211
+
3212
+
3213
+
3214
+
3215
+
3216
+
3217
+
3218
+
3219
+ exports.CHAINS = CHAINS; exports.ConfirmationTimeoutError = _chunkMDLZJGLYcjs.ConfirmationTimeoutError; 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 = _chunkMDLZJGLYcjs.InsufficientFundsError; exports.InvalidEnvelopeError = _chunkMDLZJGLYcjs.InvalidEnvelopeError; exports.MaxRetriesExceededError = _chunkMDLZJGLYcjs.MaxRetriesExceededError; exports.MissingDriverError = _chunkMDLZJGLYcjs.MissingDriverError; exports.NoCompatibleAcceptError = _chunkMDLZJGLYcjs.NoCompatibleAcceptError; exports.NonReplayableBodyError = _chunkMDLZJGLYcjs.NonReplayableBodyError; exports.PaymentDeclinedError = _chunkMDLZJGLYcjs.PaymentDeclinedError; exports.PaymentTimeoutError = _chunkMDLZJGLYcjs.PaymentTimeoutError; exports.PipRailClient = PipRailClient; exports.PipRailError = _chunkMDLZJGLYcjs.PipRailError; exports.RecipientNotReadyError = _chunkMDLZJGLYcjs.RecipientNotReadyError; exports.SettlementError = _chunkMDLZJGLYcjs.SettlementError; exports.UnknownTokenError = _chunkMDLZJGLYcjs.UnknownTokenError; exports.UnsupportedNetworkError = _chunkMDLZJGLYcjs.UnsupportedNetworkError; exports.WrongChainError = _chunkMDLZJGLYcjs.WrongChainError; exports.WrongFamilyError = _chunkMDLZJGLYcjs.WrongFamilyError; exports.buildChallengeHeader = buildChallengeHeader; exports.buildExactAuthorization = buildExactAuthorization; exports.buildOpenApi = buildOpenApi; exports.buildReceiptHeader = buildReceiptHeader; exports.buildSignatureHeader = buildSignatureHeader; exports.buildWellKnownX402 = buildWellKnownX402; exports.buildX402DnsTxt = buildX402DnsTxt; exports.chainIdForExactNetwork = chainIdForExactNetwork; exports.createPaymentGate = createPaymentGate; exports.eip3009Abi = eip3009Abi; exports.encodeXPaymentHeader = encodeXPaymentHeader; exports.evaluatePolicy = evaluatePolicy; exports.normalizeNetwork = normalizeNetwork; exports.parseChallenge = parseChallenge; exports.parseExactPaymentHeader = parseExactPaymentHeader; exports.parseExactRequirements = parseExactRequirements; exports.parseReceipt = parseReceipt; 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.toInsufficientFundsError = _chunkMDLZJGLYcjs.toInsufficientFundsError; exports.toInvalidBody = toInvalidBody;