@piprail/sdk 1.9.0 → 1.11.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 +70 -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 +897 -265
  12. package/dist/index.d.cts +504 -45
  13. package/dist/index.d.ts +504 -45
  14. package/dist/index.js +820 -188
  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
  );
@@ -912,6 +1305,42 @@ async function resolveNetwork2(opts) {
912
1305
  }
913
1306
 
914
1307
  // src/indexes.ts
1308
+ var DIRECTORY_INFO = {
1309
+ "402index": {
1310
+ source: "402index",
1311
+ review: "probe-sync",
1312
+ auth: "none",
1313
+ chains: null,
1314
+ onSuccess: "pending-review",
1315
+ readByDiscover: true,
1316
+ caveat: "402 Index probes your URL on submit, then lists it as PENDING REVIEW \u2014 a self-registered resource is NOT in search until approved. Verify your domain on 402index.io for instant approval; otherwise it appears after manual review, so retry discover() later."
1317
+ },
1318
+ x402scan: {
1319
+ source: "x402scan",
1320
+ review: "probe-sync",
1321
+ auth: "siwx",
1322
+ chains: ["eip155:8453", "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"],
1323
+ onSuccess: "live",
1324
+ readByDiscover: false,
1325
+ caveat: "x402scan lists Base/Solana only, needs one wallet signature (SIWX), and requires a resolvable input schema (from /openapi.json or the bazaar extension in the 402 body). It goes live on x402scan.com immediately on success \u2014 but discover() does NOT read x402scan, so the listing won't appear in discover() results."
1326
+ },
1327
+ bazaar: {
1328
+ source: "bazaar",
1329
+ review: "settle-coupled",
1330
+ auth: "facilitator-only",
1331
+ chains: null,
1332
+ onSuccess: "not-listable",
1333
+ readByDiscover: true,
1334
+ caveat: "CDP Bazaar has no register endpoint \u2014 it catalogs a resource only when its own facilitator settles a payment. PipRail verifies locally with no facilitator, so a PipRail resource cannot be listed here (you can still READ Bazaar to find others). List on 402 Index or x402scan instead."
1335
+ }
1336
+ };
1337
+ function getDirectoryInfo(source) {
1338
+ return DIRECTORY_INFO[source];
1339
+ }
1340
+ function decorateOutcome(o) {
1341
+ const info = DIRECTORY_INFO[o.source];
1342
+ return { ...o, visibility: o.ok ? info.onSuccess : "not-listable", note: info.caveat };
1343
+ }
915
1344
  var BAZAAR_URL = "https://api.cdp.coinbase.com/platform/v2/x402/discovery/resources";
916
1345
  var INDEX402_SEARCH = "https://402index.io/api/v1/services";
917
1346
  var INDEX402_REGISTER = "https://402index.io/api/v1/register";
@@ -960,7 +1389,7 @@ async function searchOpenIndexes(opts = {}) {
960
1389
  async function safeSearch(run) {
961
1390
  try {
962
1391
  return await run();
963
- } catch (e12) {
1392
+ } catch (e16) {
964
1393
  return [];
965
1394
  }
966
1395
  }
@@ -1064,7 +1493,13 @@ async function register402Index(input) {
1064
1493
  body: JSON.stringify(payload)
1065
1494
  });
1066
1495
  if (res.ok) {
1067
- return { source: "402index", ok: true, status: res.status, detail: "Listed on 402 Index (searchable at 402index.io)." };
1496
+ const msg = await readIndexMessage(res);
1497
+ return {
1498
+ source: "402index",
1499
+ ok: true,
1500
+ status: res.status,
1501
+ detail: _nullishCoalesce(msg, () => ( "Registered on 402 Index \u2014 pending review (verify your domain on 402index.io for instant approval)."))
1502
+ };
1068
1503
  }
1069
1504
  const why = await readIndexError(res);
1070
1505
  return {
@@ -1077,6 +1512,14 @@ async function register402Index(input) {
1077
1512
  return { source: "402index", ok: false, detail: errMsg(err) };
1078
1513
  }
1079
1514
  }
1515
+ async function readIndexMessage(res) {
1516
+ try {
1517
+ const body = await res.json();
1518
+ return typeof body.message === "string" && body.message.length > 0 ? body.message : void 0;
1519
+ } catch (e17) {
1520
+ return void 0;
1521
+ }
1522
+ }
1080
1523
  async function readIndexError(res) {
1081
1524
  try {
1082
1525
  const body = await res.json();
@@ -1084,7 +1527,7 @@ async function readIndexError(res) {
1084
1527
  (p) => typeof p === "string" && p.length > 0
1085
1528
  );
1086
1529
  return parts.length ? [...new Set(parts)].join(" \u2014 ") : void 0;
1087
- } catch (e13) {
1530
+ } catch (e18) {
1088
1531
  return void 0;
1089
1532
  }
1090
1533
  }
@@ -1140,13 +1583,13 @@ async function readSiwxInfo(res) {
1140
1583
  try {
1141
1584
  const body = await res.json();
1142
1585
  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));
1586
+ const siwx = _optionalChain([ext, 'optionalAccess', _8 => _8["sign-in-with-x"]]);
1587
+ const info = _nullishCoalesce(_optionalChain([siwx, 'optionalAccess', _9 => _9.info]), () => ( siwx));
1145
1588
  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
1589
  return info;
1147
1590
  }
1148
1591
  return null;
1149
- } catch (e14) {
1592
+ } catch (e19) {
1150
1593
  return null;
1151
1594
  }
1152
1595
  }
@@ -1194,7 +1637,7 @@ function mapRails(accepts) {
1194
1637
  }
1195
1638
  function matchesQuery(r, query) {
1196
1639
  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)));
1640
+ 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
1641
  }
1199
1642
  function pickString(o, ...keys) {
1200
1643
  for (const k of keys) {
@@ -1226,7 +1669,7 @@ function firstArray(o, ...keys) {
1226
1669
  function hostOf(url) {
1227
1670
  try {
1228
1671
  return new URL(url).hostname;
1229
- } catch (e15) {
1672
+ } catch (e20) {
1230
1673
  return url;
1231
1674
  }
1232
1675
  }
@@ -1286,7 +1729,7 @@ function evaluatePolicy(intent, policy, spentForAssetBase) {
1286
1729
  }
1287
1730
  }
1288
1731
  if (policy.maxAmount !== void 0) {
1289
- const cap = _chunkIQGT65WScjs.floorUnits.call(void 0, policy.maxAmount, intent.decimals);
1732
+ const cap = _chunkMDLZJGLYcjs.floorUnits.call(void 0, policy.maxAmount, intent.decimals);
1290
1733
  if (intent.amountBase > cap) {
1291
1734
  return deny(
1292
1735
  `payment of ${intent.amountBase} base units exceeds policy.maxAmount ` + `(${policy.maxAmount} ${_nullishCoalesce(intent.symbol, () => ( ""))}).`.trimEnd()
@@ -1294,7 +1737,7 @@ function evaluatePolicy(intent, policy, spentForAssetBase) {
1294
1737
  }
1295
1738
  }
1296
1739
  if (policy.maxTotal !== void 0) {
1297
- const cap = _chunkIQGT65WScjs.floorUnits.call(void 0, policy.maxTotal, intent.decimals);
1740
+ const cap = _chunkMDLZJGLYcjs.floorUnits.call(void 0, policy.maxTotal, intent.decimals);
1298
1741
  if (spentForAssetBase + intent.amountBase > cap) {
1299
1742
  return deny(
1300
1743
  `this payment would push spend on ${_nullishCoalesce(intent.symbol, () => ( intent.asset))} past policy.maxTotal (${policy.maxTotal}); already spent ${spentForAssetBase} base units.`
@@ -1332,7 +1775,7 @@ var SpendLedger = (_class = class {constructor() { _class.prototype.__init.call(
1332
1775
  }
1333
1776
  /** Running total (base units) already spent on this (network, asset). */
1334
1777
  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));
1778
+ return _nullishCoalesce(_optionalChain([this, 'access', _20 => _20.buckets, 'access', _21 => _21.get, 'call', _22 => _22(keyFor(network, asset)), 'optionalAccess', _23 => _23.total]), () => ( 0n));
1336
1779
  }
1337
1780
  /** An immutable snapshot of all spend so far. */
1338
1781
  summary() {
@@ -1344,7 +1787,7 @@ var SpendLedger = (_class = class {constructor() { _class.prototype.__init.call(
1344
1787
  symbol: b.symbol,
1345
1788
  decimals: b.decimals,
1346
1789
  totalBase: b.total.toString(),
1347
- totalFormatted: _chunkIQGT65WScjs.formatUnits.call(void 0, b.total, b.decimals),
1790
+ totalFormatted: _chunkMDLZJGLYcjs.formatUnits.call(void 0, b.total, b.decimals),
1348
1791
  count: b.count
1349
1792
  })),
1350
1793
  records: [...this.records]
@@ -1381,7 +1824,7 @@ var PipRailClient = (_class2 = class {
1381
1824
  safeEmit(event) {
1382
1825
  try {
1383
1826
  this.onEvent(event);
1384
- } catch (e16) {
1827
+ } catch (e21) {
1385
1828
  }
1386
1829
  }
1387
1830
  /** Auto-mount the chain's driver, resolve the network, and bind the wallet — once. */
@@ -1406,7 +1849,7 @@ var PipRailClient = (_class2 = class {
1406
1849
  * as-is) or a plain object (serialised as JSON).
1407
1850
  */
1408
1851
  post(url, body, init) {
1409
- const headers = new Headers(_optionalChain([init, 'optionalAccess', _18 => _18.headers]));
1852
+ const headers = new Headers(_optionalChain([init, 'optionalAccess', _24 => _24.headers]));
1410
1853
  let payload;
1411
1854
  if (body === void 0 || body === null) {
1412
1855
  payload = void 0;
@@ -1437,7 +1880,7 @@ var PipRailClient = (_class2 = class {
1437
1880
  * "0.05 USDC on Base, within budget → pay it." No funds move.
1438
1881
  */
1439
1882
  async quote(url, init) {
1440
- const res = await fetch(url, { ..._nullishCoalesce(init, () => ( {})), method: _nullishCoalesce(_optionalChain([init, 'optionalAccess', _19 => _19.method]), () => ( "GET")) });
1883
+ const res = await fetch(url, { ..._nullishCoalesce(init, () => ( {})), method: _nullishCoalesce(_optionalChain([init, 'optionalAccess', _25 => _25.method]), () => ( "GET")) });
1441
1884
  if (res.status !== 402) return null;
1442
1885
  const { quote } = await this.resolveChallenge(url, res);
1443
1886
  return quote;
@@ -1456,7 +1899,7 @@ var PipRailClient = (_class2 = class {
1456
1899
  * on Tron, where a USD₮ transfer can cost real TRX.
1457
1900
  */
1458
1901
  async estimateCost(url, init) {
1459
- const res = await fetch(url, { ..._nullishCoalesce(init, () => ( {})), method: _nullishCoalesce(_optionalChain([init, 'optionalAccess', _20 => _20.method]), () => ( "GET")) });
1902
+ const res = await fetch(url, { ..._nullishCoalesce(init, () => ( {})), method: _nullishCoalesce(_optionalChain([init, 'optionalAccess', _26 => _26.method]), () => ( "GET")) });
1460
1903
  if (res.status !== 402) return null;
1461
1904
  const { net, accept, quote } = await this.resolveChallenge(url, res);
1462
1905
  const cost = await net.estimateCost(accept);
@@ -1487,11 +1930,11 @@ var PipRailClient = (_class2 = class {
1487
1930
  * the plan yourself. No funds move.
1488
1931
  */
1489
1932
  async planPayment(url, init) {
1490
- const res = await fetch(url, { ..._nullishCoalesce(init, () => ( {})), method: _nullishCoalesce(_optionalChain([init, 'optionalAccess', _21 => _21.method]), () => ( "GET")) });
1933
+ const res = await fetch(url, { ..._nullishCoalesce(init, () => ( {})), method: _nullishCoalesce(_optionalChain([init, 'optionalAccess', _27 => _27.method]), () => ( "GET")) });
1491
1934
  if (res.status !== 402) return null;
1492
1935
  const challenge = await parseChallenge(res);
1493
1936
  if (!challenge) {
1494
- throw new (0, _chunkIQGT65WScjs.InvalidEnvelopeError)("402 response did not include a parseable x402 challenge.");
1937
+ throw new (0, _chunkMDLZJGLYcjs.InvalidEnvelopeError)("402 response did not include a parseable x402 challenge.");
1495
1938
  }
1496
1939
  const { net, wallet } = await this.ensure();
1497
1940
  return this.planFromChallenge(net, wallet, challenge, url);
@@ -1515,9 +1958,15 @@ var PipRailClient = (_class2 = class {
1515
1958
  *
1516
1959
  * Nothing PipRail-hosted: these are third-party open directories. Never throws
1517
1960
  * for a read problem — an index that's down or changed simply contributes
1518
- * nothing. Honest caveat: index results are cross-scheme (mostly the
1519
- * mainstream `exact` scheme); `fetch()` pays only `onchain-proof` rails
1520
- * directly (pay `exact` resources with the experimental `drivers/evm/exact.ts`).
1961
+ * nothing. Honest caveats (see {@link DIRECTORY_INFO}):
1962
+ * - Reads **`bazaar` + `402index`** only — **NOT `x402scan`** (its reads are paid). A
1963
+ * resource you registered on x402scan is live there but will NOT appear here; don't
1964
+ * read that absence as failure. (Passing `sources:['x402scan']` explicitly yields `[]`.)
1965
+ * - A resource just listed via {@link register} may not appear yet — 402 Index reviews
1966
+ * before publishing, so retry with a brief backoff if a fresh listing is missing.
1967
+ * - Results are cross-scheme (mostly the mainstream `exact` scheme); `fetch()` pays
1968
+ * only `onchain-proof` rails directly (pay `exact` resources with the experimental
1969
+ * `drivers/evm/exact.ts`).
1521
1970
  */
1522
1971
  async discover(opts = {}) {
1523
1972
  const found = await searchOpenIndexes({
@@ -1542,12 +1991,27 @@ var PipRailClient = (_class2 = class {
1542
1991
  }
1543
1992
  /**
1544
1993
  * List a resource you run on the OPEN x402 registries, so agents can find it.
1545
- * Default target is **402 Index** — one POST, no auth, no signature, no payment
1546
- * (searchable within seconds). Add `'x402scan'` to also register via SIWX (one
1547
- * wallet signature; EVM + a Base/Solana rail). Returns one {@link RegisterOutcome}
1548
- * per target — a target the chain can't satisfy comes back `{ ok:false, detail }`,
1549
- * never a throw. An explicit, developer-invoked action; it moves no funds, and
1550
- * nothing is PipRail-hosted — you're listing on third-party open directories.
1994
+ * Default target is **402 Index** — one POST, no auth, no signature, no payment.
1995
+ * Add `'x402scan'` to also register via SIWX (one wallet signature; EVM + a
1996
+ * Base/Solana rail). Returns one {@link RegisterOutcome} per target — a target the
1997
+ * chain can't satisfy comes back `{ ok:false, detail }`, never a throw. An explicit,
1998
+ * developer-invoked action; it moves no funds, and nothing is PipRail-hosted —
1999
+ * you're listing on third-party open directories.
2000
+ *
2001
+ * **Listing is asynchronous — each outcome carries a `visibility` + `note` so an
2002
+ * agent knows when/where the resource is findable (don't assume `ok:true` means
2003
+ * "searchable now"):**
2004
+ * - **402 Index** → `visibility:'pending-review'`. It probes your URL on submit, then lists it
2005
+ * PENDING REVIEW — not searchable until approved (verify your domain on 402index.io for instant
2006
+ * approval), so `discover()` returns nothing for a fresh listing until then. Retry later.
2007
+ * - **x402scan** → `visibility:'live'`, but **`discover()` does NOT read x402scan** — the
2008
+ * listing is real on x402scan.com yet won't show up in `discover()`. Base/Solana only;
2009
+ * needs a resolvable input schema (`/openapi.json` or the `extensions.bazaar` block).
2010
+ * - **Bazaar** → `visibility:'not-listable'` for PipRail (it lists only what its facilitator
2011
+ * settles; PipRail uses none). You can still READ Bazaar via {@link discover} to find others.
2012
+ *
2013
+ * The per-source facts live in {@link DIRECTORY_INFO} (importable) if you'd rather branch
2014
+ * on them before calling.
1551
2015
  */
1552
2016
  async register(url, opts = {}) {
1553
2017
  const targets = _nullishCoalesce(opts.targets, () => ( ["402index"]));
@@ -1586,7 +2050,7 @@ var PipRailClient = (_class2 = class {
1586
2050
  });
1587
2051
  }
1588
2052
  }
1589
- return outcomes;
2053
+ return outcomes.map(decorateOutcome);
1590
2054
  }
1591
2055
  /**
1592
2056
  * The discovery signer for the bound wallet (its address + a message signer),
@@ -1607,9 +2071,9 @@ var PipRailClient = (_class2 = class {
1607
2071
  * streams throw `NonReplayableBodyError`.
1608
2072
  */
1609
2073
  async fetch(url, init) {
1610
- const body = _optionalChain([init, 'optionalAccess', _22 => _22.body]);
2074
+ const body = _optionalChain([init, 'optionalAccess', _28 => _28.body]);
1611
2075
  if (body !== void 0 && body !== null && !isReplayableBodyInit(body)) {
1612
- throw new (0, _chunkIQGT65WScjs.NonReplayableBodyError)(
2076
+ throw new (0, _chunkMDLZJGLYcjs.NonReplayableBodyError)(
1613
2077
  "fetch(): init.body is not replayable. Pass a string, FormData, URLSearchParams, ArrayBuffer, or Blob \u2014 not a ReadableStream."
1614
2078
  );
1615
2079
  }
@@ -1619,11 +2083,11 @@ var PipRailClient = (_class2 = class {
1619
2083
  const { net, wallet, challenge } = resolved;
1620
2084
  let accept = resolved.accept;
1621
2085
  let quote = resolved.quote;
1622
- const autoRoute = _nullishCoalesce(_nullishCoalesce(_optionalChain([init, 'optionalAccess', _23 => _23.autoRoute]), () => ( this.opts.autoRoute)), () => ( false));
2086
+ const autoRoute = _nullishCoalesce(_nullishCoalesce(_optionalChain([init, 'optionalAccess', _29 => _29.autoRoute]), () => ( this.opts.autoRoute)), () => ( false));
1623
2087
  if (autoRoute) {
1624
2088
  const plan = await this.planFromChallenge(net, wallet, challenge, url);
1625
2089
  if (!plan.best) {
1626
- throw new (0, _chunkIQGT65WScjs.PaymentDeclinedError)(_nullishCoalesce(plan.fundingHint, () => ( "No rail is settleable for this payment.")));
2090
+ throw new (0, _chunkMDLZJGLYcjs.PaymentDeclinedError)(_nullishCoalesce(plan.fundingHint, () => ( "No rail is settleable for this payment.")));
1627
2091
  }
1628
2092
  accept = plan.best.accept;
1629
2093
  quote = plan.best.quote;
@@ -1644,7 +2108,7 @@ var PipRailClient = (_class2 = class {
1644
2108
  async resolveChallenge(url, response) {
1645
2109
  const challenge = await parseChallenge(response);
1646
2110
  if (!challenge) {
1647
- throw new (0, _chunkIQGT65WScjs.InvalidEnvelopeError)(
2111
+ throw new (0, _chunkMDLZJGLYcjs.InvalidEnvelopeError)(
1648
2112
  "402 response did not include a parseable x402 challenge."
1649
2113
  );
1650
2114
  }
@@ -1652,7 +2116,7 @@ var PipRailClient = (_class2 = class {
1652
2116
  const candidates = this.gatherCandidates(net, challenge);
1653
2117
  if (candidates.length === 0) {
1654
2118
  const networks = challenge.accepts.map((a) => a.network).join(", ");
1655
- throw new (0, _chunkIQGT65WScjs.NoCompatibleAcceptError)(
2119
+ throw new (0, _chunkMDLZJGLYcjs.NoCompatibleAcceptError)(
1656
2120
  `No accepts[] entry for ${net.network} (challenge offered: ${networks || "none"}).`
1657
2121
  );
1658
2122
  }
@@ -1663,7 +2127,10 @@ var PipRailClient = (_class2 = class {
1663
2127
  const chosen = _nullishCoalesce(priced.find((p) => p.quote.withinPolicy), () => ( priced[0]));
1664
2128
  return { net, wallet, accept: chosen.accept, challenge, quote: chosen.quote };
1665
2129
  }
1666
- /** The candidate accepts this client could pay: our scheme, on the bound network. */
2130
+ /** The candidate accepts this client could pay: our scheme, on the bound network.
2131
+ * A dual-advertised challenge may also carry standard `exact` rails — the PipRail
2132
+ * client ignores those (it pays the backendless `onchain-proof` rail); the type
2133
+ * predicate narrows the `X402AnyAccept` union to the rails we settle. */
1667
2134
  gatherCandidates(net, challenge) {
1668
2135
  return challenge.accepts.filter(
1669
2136
  (a) => a.scheme === "onchain-proof" && net.supports(a.network)
@@ -1726,16 +2193,16 @@ var PipRailClient = (_class2 = class {
1726
2193
  if (isNative) {
1727
2194
  if (nativeKnown && bal.native < amount + fee) {
1728
2195
  blockers.push("INSUFFICIENT_TOKEN");
1729
- shortfall.token = _chunkIQGT65WScjs.formatUnits.call(void 0, amount + fee - bal.native, quote.decimals);
2196
+ shortfall.token = _chunkMDLZJGLYcjs.formatUnits.call(void 0, amount + fee - bal.native, quote.decimals);
1730
2197
  }
1731
2198
  } else {
1732
2199
  if (tokenKnown && bal.token < amount) {
1733
2200
  blockers.push("INSUFFICIENT_TOKEN");
1734
- shortfall.token = _chunkIQGT65WScjs.formatUnits.call(void 0, amount - bal.token, quote.decimals);
2201
+ shortfall.token = _chunkMDLZJGLYcjs.formatUnits.call(void 0, amount - bal.token, quote.decimals);
1735
2202
  }
1736
2203
  if (nativeKnown && bal.native < fee) {
1737
2204
  blockers.push("INSUFFICIENT_GAS");
1738
- shortfall.native = _chunkIQGT65WScjs.formatUnits.call(void 0, fee - bal.native, cost.feeDecimals);
2205
+ shortfall.native = _chunkMDLZJGLYcjs.formatUnits.call(void 0, fee - bal.native, cost.feeDecimals);
1739
2206
  } else if (nativeKnown && fee > 0n && bal.native < fee * 3n / 2n) {
1740
2207
  warnings.push("THIN_GAS_MARGIN");
1741
2208
  }
@@ -1760,8 +2227,8 @@ var PipRailClient = (_class2 = class {
1760
2227
  blockers,
1761
2228
  warnings,
1762
2229
  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
2230
+ token: bal.token != null ? _chunkMDLZJGLYcjs.formatUnits.call(void 0, bal.token, quote.decimals) : null,
2231
+ native: bal.native != null ? _chunkMDLZJGLYcjs.formatUnits.call(void 0, bal.native, cost.feeDecimals) : null
1765
2232
  },
1766
2233
  need: { token: quote.amountFormatted, native: cost.feeFormatted },
1767
2234
  ...shortfall.token || shortfall.native ? { shortfall } : {},
@@ -1772,15 +2239,15 @@ var PipRailClient = (_class2 = class {
1772
2239
  * driver's describeAsset) + the policy verdict + a symbol-mismatch flag. */
1773
2240
  buildQuote(net, accept, url, description) {
1774
2241
  if (!/^\d+$/.test(accept.amount)) {
1775
- throw new (0, _chunkIQGT65WScjs.InvalidEnvelopeError)(
2242
+ throw new (0, _chunkMDLZJGLYcjs.InvalidEnvelopeError)(
1776
2243
  `challenge amount "${accept.amount}" is not a base-unit integer.`
1777
2244
  );
1778
2245
  }
1779
2246
  const amountBase = BigInt(accept.amount);
1780
2247
  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);
2248
+ const decimals = _nullishCoalesce(_optionalChain([described, 'optionalAccess', _30 => _30.decimals]), () => ( accept.extra.decimals));
2249
+ const symbol = _nullishCoalesce(_optionalChain([described, 'optionalAccess', _31 => _31.symbol]), () => ( accept.extra.symbol));
2250
+ const amountFormatted = _chunkMDLZJGLYcjs.formatUnits.call(void 0, amountBase, decimals);
1784
2251
  const intent = {
1785
2252
  host: hostOf2(url),
1786
2253
  chain: this.opts.chain,
@@ -1820,7 +2287,7 @@ var PipRailClient = (_class2 = class {
1820
2287
  * throwing PaymentDeclinedError, before any funds move. */
1821
2288
  async authorize(quote) {
1822
2289
  if (!quote.withinPolicy) {
1823
- throw new (0, _chunkIQGT65WScjs.PaymentDeclinedError)(
2290
+ throw new (0, _chunkMDLZJGLYcjs.PaymentDeclinedError)(
1824
2291
  `Payment refused by policy: ${_nullishCoalesce(quote.policyReason, () => ( "not allowed"))}`
1825
2292
  );
1826
2293
  }
@@ -1830,12 +2297,12 @@ var PipRailClient = (_class2 = class {
1830
2297
  try {
1831
2298
  approved = await hook(quote);
1832
2299
  } catch (err) {
1833
- throw new (0, _chunkIQGT65WScjs.PaymentDeclinedError)("onBeforePay threw \u2014 refusing to pay.", {
2300
+ throw new (0, _chunkMDLZJGLYcjs.PaymentDeclinedError)("onBeforePay threw \u2014 refusing to pay.", {
1834
2301
  cause: err
1835
2302
  });
1836
2303
  }
1837
2304
  if (!approved) {
1838
- throw new (0, _chunkIQGT65WScjs.PaymentDeclinedError)(
2305
+ throw new (0, _chunkMDLZJGLYcjs.PaymentDeclinedError)(
1839
2306
  `onBeforePay declined ${quote.amountFormatted} ${_nullishCoalesce(quote.symbol, () => ( ""))}`.trimEnd() + ` on ${quote.network}.`
1840
2307
  );
1841
2308
  }
@@ -1859,7 +2326,7 @@ var PipRailClient = (_class2 = class {
1859
2326
  }
1860
2327
  async payAndConfirm(net, wallet, accept) {
1861
2328
  if (!net.supports(accept.network)) {
1862
- throw new (0, _chunkIQGT65WScjs.WrongChainError)(
2329
+ throw new (0, _chunkMDLZJGLYcjs.WrongChainError)(
1863
2330
  `Challenge expects ${accept.network} but client is on ${net.network}.`
1864
2331
  );
1865
2332
  }
@@ -1888,7 +2355,7 @@ var PipRailClient = (_class2 = class {
1888
2355
  accepted: accept,
1889
2356
  payload: { nonce: accept.extra.nonce, txHash: ref }
1890
2357
  };
1891
- const headers = new Headers(_optionalChain([originalInit, 'optionalAccess', _26 => _26.headers]));
2358
+ const headers = new Headers(_optionalChain([originalInit, 'optionalAccess', _32 => _32.headers]));
1892
2359
  headers.set(HEADER_SIGNATURE, buildSignatureHeader(signature));
1893
2360
  let lastResponse = null;
1894
2361
  let lastReason = null;
@@ -1903,7 +2370,7 @@ var PipRailClient = (_class2 = class {
1903
2370
  () => timeoutController.abort(),
1904
2371
  this.retryTimeoutMs
1905
2372
  );
1906
- const signal = _optionalChain([originalInit, 'optionalAccess', _27 => _27.signal]) && typeof AbortSignal.any === "function" ? AbortSignal.any([timeoutController.signal, originalInit.signal]) : timeoutController.signal;
2373
+ const signal = _optionalChain([originalInit, 'optionalAccess', _33 => _33.signal]) && typeof AbortSignal.any === "function" ? AbortSignal.any([timeoutController.signal, originalInit.signal]) : timeoutController.signal;
1907
2374
  try {
1908
2375
  lastResponse = await fetch(url, {
1909
2376
  ..._nullishCoalesce(originalInit, () => ( {})),
@@ -1912,7 +2379,7 @@ var PipRailClient = (_class2 = class {
1912
2379
  });
1913
2380
  } catch (err) {
1914
2381
  if (timeoutController.signal.aborted) {
1915
- throw new (0, _chunkIQGT65WScjs.PaymentTimeoutError)(
2382
+ throw new (0, _chunkMDLZJGLYcjs.PaymentTimeoutError)(
1916
2383
  `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
2384
  { cause: err, ref }
1918
2385
  );
@@ -1934,7 +2401,7 @@ var PipRailClient = (_class2 = class {
1934
2401
  kind: "payment-failed",
1935
2402
  reason: `server returned 402 after broadcasting payment ${ref}${unconfirmedNote} (${why})`
1936
2403
  });
1937
- throw new (0, _chunkIQGT65WScjs.MaxRetriesExceededError)(
2404
+ throw new (0, _chunkMDLZJGLYcjs.MaxRetriesExceededError)(
1938
2405
  `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
2406
  { ref }
1940
2407
  );
@@ -1943,7 +2410,7 @@ var PipRailClient = (_class2 = class {
1943
2410
  function safeBig(s) {
1944
2411
  try {
1945
2412
  return BigInt(s);
1946
- } catch (e17) {
2413
+ } catch (e22) {
1947
2414
  return 0n;
1948
2415
  }
1949
2416
  }
@@ -1976,10 +2443,10 @@ function buildFundingHint(options, chainLabel) {
1976
2443
  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
2444
  }
1978
2445
  const parts = [];
1979
- if (target.blockers.includes("INSUFFICIENT_TOKEN") && _optionalChain([target, 'access', _28 => _28.shortfall, 'optionalAccess', _29 => _29.token])) {
2446
+ if (target.blockers.includes("INSUFFICIENT_TOKEN") && _optionalChain([target, 'access', _34 => _34.shortfall, 'optionalAccess', _35 => _35.token])) {
1980
2447
  parts.push(`top up ${target.shortfall.token} ${sym}`);
1981
2448
  }
1982
- if (target.blockers.includes("INSUFFICIENT_GAS") && _optionalChain([target, 'access', _30 => _30.shortfall, 'optionalAccess', _31 => _31.native])) {
2449
+ if (target.blockers.includes("INSUFFICIENT_GAS") && _optionalChain([target, 'access', _36 => _36.shortfall, 'optionalAccess', _37 => _37.native])) {
1983
2450
  parts.push(`add ~${target.shortfall.native} ${target.cost.feeSymbol} for gas`);
1984
2451
  }
1985
2452
  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 +2460,7 @@ async function planAcross(clients, url, init) {
1993
2460
  const status = best ? "ready" : options.some((o) => o.state === "unknown") ? "unknown" : "blocked";
1994
2461
  return {
1995
2462
  url,
1996
- network: _nullishCoalesce(_optionalChain([best, 'optionalAccess', _32 => _32.accept, 'access', _33 => _33.network]), () => ( live[0].network)),
2463
+ network: _nullishCoalesce(_optionalChain([best, 'optionalAccess', _38 => _38.accept, 'access', _39 => _39.network]), () => ( live[0].network)),
1997
2464
  status,
1998
2465
  payable: best !== null,
1999
2466
  best,
@@ -2009,7 +2476,7 @@ function railOnNetwork(rail, matches) {
2009
2476
  function hostOf2(url) {
2010
2477
  try {
2011
2478
  return new URL(url).hostname;
2012
- } catch (e18) {
2479
+ } catch (e23) {
2013
2480
  return url;
2014
2481
  }
2015
2482
  }
@@ -2026,13 +2493,21 @@ function isReplayableBodyInit(value) {
2026
2493
  async function readInvalidReason(response) {
2027
2494
  try {
2028
2495
  const body = await response.clone().json();
2496
+ const ext = _optionalChain([body, 'optionalAccess', _40 => _40.extensions]);
2497
+ const piprail = _optionalChain([ext, 'optionalAccess', _41 => _41.piprail]);
2498
+ if (piprail && typeof piprail.code === "string") {
2499
+ return {
2500
+ error: piprail.code,
2501
+ detail: typeof piprail.detail === "string" ? piprail.detail : ""
2502
+ };
2503
+ }
2029
2504
  if (body && (body.status === "invalid" || typeof body.error === "string")) {
2030
2505
  return {
2031
2506
  error: typeof body.error === "string" ? body.error : "no error code",
2032
2507
  detail: typeof body.detail === "string" ? body.detail : ""
2033
2508
  };
2034
2509
  }
2035
- } catch (e19) {
2510
+ } catch (e24) {
2036
2511
  }
2037
2512
  return null;
2038
2513
  }
@@ -2043,7 +2518,7 @@ async function readBody(res) {
2043
2518
  if (!text) return null;
2044
2519
  try {
2045
2520
  return JSON.parse(text);
2046
- } catch (e20) {
2521
+ } catch (e25) {
2047
2522
  return text;
2048
2523
  }
2049
2524
  }
@@ -2214,7 +2689,7 @@ function paymentTools(client) {
2214
2689
  receipt: parseReceipt(res)
2215
2690
  };
2216
2691
  } catch (err) {
2217
- if (err instanceof _chunkIQGT65WScjs.PaymentDeclinedError) {
2692
+ if (err instanceof _chunkMDLZJGLYcjs.PaymentDeclinedError) {
2218
2693
  return { declined: true, reason: err.message };
2219
2694
  }
2220
2695
  throw err;
@@ -2223,7 +2698,7 @@ function paymentTools(client) {
2223
2698
  },
2224
2699
  {
2225
2700
  name: "piprail_register",
2226
- description: "List an x402 payment-gated resource YOU run on the open indexes so other agents can discover it. Default target is 402 Index \u2014 no auth, no signature, no payment; searchable within seconds. Returns one outcome per index ({ source, ok, detail }); a step the chain can't satisfy comes back ok:false with the reason. Moves no funds; nothing is PipRail-hosted.",
2701
+ description: "List an x402 payment-gated resource YOU run on the open indexes so other agents can discover it. Default target is 402 Index \u2014 no auth, no signature, no payment; a self-registered listing is pending review (verify your domain on 402index.io for instant approval). Returns one outcome per index ({ source, ok, detail, visibility, note }); a step the chain can't satisfy comes back ok:false with the reason. Moves no funds; nothing is PipRail-hosted.",
2227
2702
  annotations: {
2228
2703
  title: "Register an x402 endpoint",
2229
2704
  readOnlyHint: false,
@@ -2257,6 +2732,100 @@ function paymentTools(client) {
2257
2732
  ];
2258
2733
  }
2259
2734
 
2735
+ // src/facilitator.ts
2736
+ function safeStringify(value) {
2737
+ return JSON.stringify(value, (_k, v) => typeof v === "bigint" ? v.toString() : v);
2738
+ }
2739
+ function mapReason(reason) {
2740
+ const r = (_nullishCoalesce(reason, () => ( ""))).toLowerCase();
2741
+ if (r.includes("signature")) return "signature_invalid";
2742
+ if (r.includes("recipient")) return "wrong_recipient";
2743
+ if (r.includes("value") || r.includes("amount")) return "amount_too_low";
2744
+ if (r.includes("valid_before") || r.includes("valid_after") || r.includes("expired")) return "payment_expired";
2745
+ if (r.includes("used") || r.includes("replay") || r.includes("nonce") || r.includes("transaction_state")) {
2746
+ return "tx_already_used";
2747
+ }
2748
+ return "tx_reverted";
2749
+ }
2750
+ async function post(url, body, headers) {
2751
+ const res = await fetch(url, {
2752
+ method: "POST",
2753
+ headers: { "content-type": "application/json", ...headers },
2754
+ body: safeStringify(body)
2755
+ });
2756
+ let json = null;
2757
+ try {
2758
+ json = await res.json();
2759
+ } catch (e26) {
2760
+ }
2761
+ return { status: res.status, json };
2762
+ }
2763
+ async function settleViaFacilitator(input) {
2764
+ const base2 = input.url.replace(/\/+$/, "");
2765
+ const body = {
2766
+ x402Version: input.x402Version,
2767
+ paymentPayload: input.paymentPayload,
2768
+ paymentRequirements: input.paymentRequirements
2769
+ };
2770
+ const auth = input.authHeaders ? await input.authHeaders() : {};
2771
+ let verify;
2772
+ try {
2773
+ verify = await post(`${base2}/verify`, body, auth);
2774
+ } catch (err) {
2775
+ throw new (0, _chunkMDLZJGLYcjs.SettlementError)(
2776
+ `exact settle (facilitator ${base2}): /verify request failed (${err instanceof Error ? err.message : String(err)}).`,
2777
+ { cause: err }
2778
+ );
2779
+ }
2780
+ if (verify.status !== 200) {
2781
+ throw new (0, _chunkMDLZJGLYcjs.SettlementError)(
2782
+ `exact settle (facilitator ${base2}): /verify returned HTTP ${verify.status} (transport/auth error).`
2783
+ );
2784
+ }
2785
+ const vr = _nullishCoalesce(verify.json, () => ( {}));
2786
+ if (vr.isValid === false) {
2787
+ return {
2788
+ ok: false,
2789
+ error: mapReason(vr.invalidReason),
2790
+ detail: `Facilitator rejected the payment: ${_nullishCoalesce(vr.invalidReason, () => ( "invalid"))}${vr.invalidMessage ? ` \u2014 ${vr.invalidMessage}` : ""}.`
2791
+ };
2792
+ }
2793
+ let settle;
2794
+ try {
2795
+ settle = await post(`${base2}/settle`, body, auth);
2796
+ } catch (err) {
2797
+ throw new (0, _chunkMDLZJGLYcjs.SettlementError)(
2798
+ `exact settle (facilitator ${base2}): /settle request failed (${err instanceof Error ? err.message : String(err)}).`,
2799
+ { cause: err }
2800
+ );
2801
+ }
2802
+ if (settle.status !== 200) {
2803
+ throw new (0, _chunkMDLZJGLYcjs.SettlementError)(
2804
+ `exact settle (facilitator ${base2}): /settle returned HTTP ${settle.status} (transport/auth error).`
2805
+ );
2806
+ }
2807
+ const sr = _nullishCoalesce(settle.json, () => ( {}));
2808
+ if (!sr.success) {
2809
+ return {
2810
+ ok: false,
2811
+ error: mapReason(sr.errorReason),
2812
+ detail: `Facilitator settlement failed: ${_nullishCoalesce(sr.errorReason, () => ( "unknown"))}${sr.errorMessage ? ` \u2014 ${sr.errorMessage}` : ""}.`
2813
+ };
2814
+ }
2815
+ const receipt = {
2816
+ scheme: "exact",
2817
+ success: true,
2818
+ network: input.receipt.network,
2819
+ transaction: sr.transaction,
2820
+ asset: input.receipt.asset,
2821
+ amount: input.receipt.amount,
2822
+ payer: _nullishCoalesce(_nullishCoalesce(sr.payer, () => ( input.payerHint)), () => ( "")),
2823
+ payTo: input.receipt.payTo,
2824
+ verifiedAt: (/* @__PURE__ */ new Date()).toISOString()
2825
+ };
2826
+ return { ok: true, receipt };
2827
+ }
2828
+
2260
2829
  // src/server.ts
2261
2830
  function toInvalidBody(result) {
2262
2831
  return { x402Version: 2, status: "invalid", error: result.error, detail: result.detail };
@@ -2283,9 +2852,10 @@ function createPaymentGate(options) {
2283
2852
  const genNonce = _nullishCoalesce(options.generateNonce, () => ( (() => globalThis.crypto.randomUUID())));
2284
2853
  let resolved;
2285
2854
  function ready() {
2286
- return resolved ??= (async () => {
2855
+ if (resolved) return resolved;
2856
+ const p = (async () => {
2287
2857
  const accepts = normaliseAccepts(options);
2288
- return Promise.all(
2858
+ const specs = await Promise.all(
2289
2859
  accepts.map(async (a) => {
2290
2860
  const net = await resolveNetwork2({ chain: a.chain, rpcUrl: _nullishCoalesce(a.rpcUrl, () => ( options.rpcUrl)) });
2291
2861
  const payTo = _nullishCoalesce(a.payTo, () => ( options.payTo));
@@ -2296,11 +2866,53 @@ function createPaymentGate(options) {
2296
2866
  }
2297
2867
  net.assertValidPayTo(payTo);
2298
2868
  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 };
2869
+ const amountBase = _chunkMDLZJGLYcjs.parseUnits.call(void 0, a.amount, decimals);
2870
+ const spec = { net, asset, decimals, symbol, amountBase, amountFormatted: a.amount, payTo };
2871
+ if (options.exact) spec.exact = await resolveExactRail(net, asset);
2872
+ return spec;
2301
2873
  })
2302
2874
  );
2875
+ if (options.exact && !specs.some((s) => s.exact)) {
2876
+ throw new Error(
2877
+ "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`."
2878
+ );
2879
+ }
2880
+ return specs;
2303
2881
  })();
2882
+ p.catch(() => {
2883
+ if (resolved === p) resolved = void 0;
2884
+ });
2885
+ resolved = p;
2886
+ return p;
2887
+ }
2888
+ async function resolveExactRail(net, asset) {
2889
+ const cfg = options.exact;
2890
+ if (net.family !== "evm" || asset === "native" || !net.exactDomain || !net.settleExactSelf) {
2891
+ return void 0;
2892
+ }
2893
+ const domain = await net.exactDomain(asset);
2894
+ if (!domain) {
2895
+ throw new Error(
2896
+ `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.)`
2897
+ );
2898
+ }
2899
+ if (cfg.settle === "self") {
2900
+ if (cfg.relayer === void 0) {
2901
+ throw new Error(
2902
+ "requirePayment: exact `settle: 'self'` needs a `relayer` wallet (the gas-paying key that broadcasts transferWithAuthorization), e.g. exact: { settle: 'self', relayer: { privateKey } }."
2903
+ );
2904
+ }
2905
+ const relayer = net.bindWallet(cfg.relayer);
2906
+ return { domain, mode: { kind: "self", relayer } };
2907
+ }
2908
+ return {
2909
+ domain,
2910
+ mode: {
2911
+ kind: "facilitator",
2912
+ url: cfg.settle.facilitator,
2913
+ ...cfg.settle.authHeaders ? { authHeaders: cfg.settle.authHeaders } : {}
2914
+ }
2915
+ };
2304
2916
  }
2305
2917
  const hasCustomStore = Boolean(options.isUsed || options.markUsed);
2306
2918
  const localUsed = /* @__PURE__ */ new Set();
@@ -2337,93 +2949,191 @@ function createPaymentGate(options) {
2337
2949
  }
2338
2950
  };
2339
2951
  }
2340
- async function challenge(resourceUrl = "") {
2952
+ function buildExactAccept(s) {
2953
+ const d = s.exact.domain;
2954
+ return {
2955
+ scheme: "exact",
2956
+ network: s.net.network,
2957
+ amount: s.amountBase.toString(),
2958
+ asset: s.asset,
2959
+ payTo: s.payTo,
2960
+ maxTimeoutSeconds,
2961
+ extra: {
2962
+ assetTransferMethod: "eip3009",
2963
+ name: d.name,
2964
+ version: d.version,
2965
+ minConfirmations,
2966
+ decimals: s.decimals,
2967
+ amountFormatted: s.amountFormatted,
2968
+ ...s.symbol ? { symbol: s.symbol } : {}
2969
+ }
2970
+ };
2971
+ }
2972
+ function buildAccepts(specs, nonce) {
2973
+ const out = [];
2974
+ for (const s of specs) {
2975
+ if (s.exact) out.push(buildExactAccept(s));
2976
+ out.push(buildAccept(s, nonce));
2977
+ }
2978
+ return out;
2979
+ }
2980
+ async function makeChallenge(resourceUrl, opts) {
2341
2981
  const specs = await ready();
2342
2982
  const nonce = genNonce();
2343
2983
  const challenge2 = {
2344
2984
  x402Version: 2,
2345
- error: null,
2346
2985
  resource: {
2347
2986
  url: resourceUrl,
2348
2987
  ...options.description ? { description: options.description } : {}
2349
2988
  },
2350
- accepts: specs.map((s) => buildAccept(s, nonce))
2989
+ accepts: buildAccepts(specs, nonce),
2990
+ ..._optionalChain([opts, 'optionalAccess', _42 => _42.error]) ? { error: opts.error } : {},
2991
+ ..._optionalChain([opts, 'optionalAccess', _43 => _43.extensions]) ? { extensions: opts.extensions } : {}
2351
2992
  };
2352
2993
  return { challenge: challenge2, requiredHeader: buildChallengeHeader(challenge2) };
2353
2994
  }
2995
+ async function challenge(resourceUrl = "") {
2996
+ return makeChallenge(resourceUrl);
2997
+ }
2354
2998
  async function asChallenge() {
2355
- const { challenge: c, requiredHeader } = await challenge();
2999
+ const { challenge: c, requiredHeader } = await makeChallenge("");
2356
3000
  return { kind: "challenge", challenge: c, requiredHeader, statusCode: 402 };
2357
3001
  }
3002
+ async function rejection(code, detail) {
3003
+ const { challenge: c, requiredHeader } = await makeChallenge("", {
3004
+ error: `${code}: ${detail}`,
3005
+ extensions: { piprail: { code, detail } }
3006
+ });
3007
+ return { kind: "invalid", error: code, detail, challenge: c, requiredHeader, statusCode: 402 };
3008
+ }
3009
+ function fireOnPaid(receipt) {
3010
+ if (options.onPaid) {
3011
+ try {
3012
+ options.onPaid(receipt);
3013
+ } catch (e27) {
3014
+ }
3015
+ }
3016
+ }
2358
3017
  async function describe(resourceUrl = "") {
2359
3018
  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
- }));
3019
+ const accepts = [];
3020
+ for (const s of specs) {
3021
+ const base2 = {
3022
+ network: s.net.network,
3023
+ asset: s.asset,
3024
+ payTo: s.payTo,
3025
+ amount: s.amountBase.toString(),
3026
+ amountFormatted: s.amountFormatted,
3027
+ decimals: s.decimals,
3028
+ maxTimeoutSeconds,
3029
+ ...s.symbol ? { symbol: s.symbol } : {}
3030
+ };
3031
+ if (s.exact) accepts.push({ scheme: "exact", ...base2 });
3032
+ accepts.push({ scheme: "onchain-proof", ...base2 });
3033
+ }
2371
3034
  return {
2372
3035
  url: resourceUrl,
2373
3036
  ...options.description ? { description: options.description } : {},
2374
3037
  accepts
2375
3038
  };
2376
3039
  }
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
- }
3040
+ async function verifyOnchainProof(sig) {
2384
3041
  const specs = await ready();
2385
3042
  const spec = specs.find(
2386
3043
  (s) => s.net.network === sig.accepted.network && s.asset === sig.accepted.asset
2387
3044
  );
2388
3045
  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
- };
3046
+ return rejection(
3047
+ "transfer_not_found",
3048
+ `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(", ")}).`
3049
+ );
2395
3050
  }
2396
3051
  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
- }
3052
+ if (await claimTx(ref)) return rejection("tx_already_used", `Proof ${ref} was already redeemed.`);
2405
3053
  const result = await spec.net.verify(ref, buildAccept(spec, sig.payload.nonce));
2406
3054
  if (!result.ok) {
2407
3055
  await settleTx(ref, false);
2408
- return {
2409
- kind: "invalid",
2410
- error: result.error,
2411
- detail: result.detail,
2412
- statusCode: 402
2413
- };
3056
+ return rejection(result.error, result.detail);
2414
3057
  }
2415
3058
  await settleTx(ref, true);
2416
- if (options.onPaid) {
2417
- try {
2418
- options.onPaid(result.receipt);
2419
- } catch (e21) {
3059
+ fireOnPaid(result.receipt);
3060
+ return { kind: "paid", receipt: result.receipt, receiptHeader: buildReceiptHeader(result.receipt) };
3061
+ }
3062
+ async function verifyExact(exact) {
3063
+ const specs = await ready();
3064
+ const exactSpecs = specs.filter((s) => s.exact);
3065
+ if (exactSpecs.length === 0) {
3066
+ return rejection("transfer_not_found", "This resource offers no standard `exact` rail.");
3067
+ }
3068
+ const isCaip = exact.network.startsWith("eip155:");
3069
+ let candidates = isCaip ? exactSpecs.filter((s) => s.net.network === exact.network) : exactSpecs;
3070
+ if (exact.asset) {
3071
+ candidates = candidates.filter((s) => s.asset.toLowerCase() === exact.asset.toLowerCase());
3072
+ }
3073
+ let spec = candidates[0];
3074
+ if (!isCaip && !exact.asset && exactSpecs.length > 1) spec = void 0;
3075
+ if (!spec && !isCaip && !exact.asset && exactSpecs.length === 1) spec = exactSpecs[0];
3076
+ if (!spec || !spec.exact) {
3077
+ return rejection(
3078
+ "transfer_not_found",
3079
+ `No \`exact\` rail offered for ${exact.network}${exact.asset ? `/${exact.asset}` : ""} (offered: ${exactSpecs.map((s) => `${s.asset}@${s.net.network}`).join(", ")}).`
3080
+ );
3081
+ }
3082
+ const nonce = exact.payload.authorization.nonce;
3083
+ if (await claimTx(nonce)) {
3084
+ return rejection("tx_already_used", `Authorization nonce ${nonce} was already redeemed.`);
3085
+ }
3086
+ const accept = buildExactAccept(spec);
3087
+ const mode = spec.exact.mode;
3088
+ let result;
3089
+ try {
3090
+ if (mode.kind === "self") {
3091
+ result = await spec.net.settleExactSelf({ relayer: mode.relayer, payload: exact.payload, accept });
3092
+ } else {
3093
+ result = await settleViaFacilitator({
3094
+ url: mode.url,
3095
+ ...mode.authHeaders ? { authHeaders: mode.authHeaders } : {},
3096
+ // PipRail always builds a v2-shaped paymentRequirements (CAIP-2 network + `amount`),
3097
+ // so force x402Version:2 — echoing a v1 client's version here would hand the facilitator
3098
+ // a self-inconsistent request (v1 envelope, v2 requirements). The inner payload is
3099
+ // byte-identical across versions, so forwarding it verbatim is fine.
3100
+ x402Version: 2,
3101
+ paymentPayload: exact.raw,
3102
+ paymentRequirements: {
3103
+ scheme: "exact",
3104
+ network: accept.network,
3105
+ asset: accept.asset,
3106
+ amount: accept.amount,
3107
+ payTo: accept.payTo,
3108
+ maxTimeoutSeconds: accept.maxTimeoutSeconds,
3109
+ extra: { name: accept.extra.name, version: accept.extra.version }
3110
+ },
3111
+ receipt: { network: accept.network, asset: accept.asset, payTo: accept.payTo, amount: accept.amount },
3112
+ payerHint: exact.payload.authorization.from
3113
+ });
2420
3114
  }
3115
+ } catch (err) {
3116
+ await settleTx(nonce, false);
3117
+ throw err;
2421
3118
  }
2422
- return {
2423
- kind: "paid",
2424
- receipt: result.receipt,
2425
- receiptHeader: buildReceiptHeader(result.receipt)
2426
- };
3119
+ if (!result.ok) {
3120
+ await settleTx(nonce, false);
3121
+ return rejection(result.error, result.detail);
3122
+ }
3123
+ await settleTx(nonce, true);
3124
+ fireOnPaid(result.receipt);
3125
+ return { kind: "paid", receipt: result.receipt, receiptHeader: buildReceiptHeader(result.receipt) };
3126
+ }
3127
+ async function verify(paymentSignature) {
3128
+ const raw = normaliseHeader(paymentSignature);
3129
+ if (!raw) return asChallenge();
3130
+ const sig = parseSignatureHeader(raw);
3131
+ if (sig && sig.accepted && typeof sig.accepted.network === "string" && typeof sig.accepted.asset === "string") {
3132
+ return verifyOnchainProof(sig);
3133
+ }
3134
+ const exact = parseExactPaymentHeader(raw);
3135
+ if (exact) return verifyExact(exact);
3136
+ return asChallenge();
2427
3137
  }
2428
3138
  return { challenge, verify, describe };
2429
3139
  }
@@ -2432,14 +3142,20 @@ function requirePayment(options) {
2432
3142
  return async (req, res, next) => {
2433
3143
  let result;
2434
3144
  try {
2435
- result = await gate.verify(req.headers[HEADER_SIGNATURE]);
3145
+ result = await gate.verify(_nullishCoalesce(req.headers[HEADER_SIGNATURE], () => ( req.headers[HEADER_SIGNATURE_V1])));
2436
3146
  } catch (err) {
3147
+ if (err instanceof _chunkMDLZJGLYcjs.SettlementError) {
3148
+ res.status(502);
3149
+ res.json({ x402Version: 2, error: "settlement_failed", detail: err.message });
3150
+ return;
3151
+ }
2437
3152
  next(err);
2438
3153
  return;
2439
3154
  }
2440
3155
  switch (result.kind) {
2441
3156
  case "paid":
2442
3157
  res.setHeader(HEADER_RESPONSE, result.receiptHeader);
3158
+ res.setHeader(HEADER_RESPONSE_V1, result.receiptHeader);
2443
3159
  return next();
2444
3160
  case "challenge":
2445
3161
  res.setHeader(HEADER_REQUIRED, result.requiredHeader);
@@ -2447,8 +3163,9 @@ function requirePayment(options) {
2447
3163
  res.json(result.challenge);
2448
3164
  return;
2449
3165
  case "invalid":
3166
+ res.setHeader(HEADER_REQUIRED, result.requiredHeader);
2450
3167
  res.status(result.statusCode);
2451
- res.json(toInvalidBody(result));
3168
+ res.json(result.challenge);
2452
3169
  return;
2453
3170
  }
2454
3171
  };
@@ -2458,110 +3175,12 @@ function normaliseHeader(value) {
2458
3175
  return value;
2459
3176
  }
2460
3177
 
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
3178
  // src/discovery.ts
2560
3179
  var GENERATOR = "@piprail/sdk \xB7 https://piprail.com";
2561
3180
  function pathOf(url) {
2562
3181
  try {
2563
3182
  return new URL(url).pathname || "/";
2564
- } catch (e22) {
3183
+ } catch (e28) {
2565
3184
  return url.startsWith("/") ? url : `/${url}`;
2566
3185
  }
2567
3186
  }
@@ -2658,4 +3277,17 @@ function buildX402DnsTxt(input) {
2658
3277
 
2659
3278
 
2660
3279
 
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;
3280
+
3281
+
3282
+
3283
+
3284
+
3285
+
3286
+
3287
+
3288
+
3289
+
3290
+
3291
+
3292
+
3293
+ exports.CHAINS = CHAINS; exports.ConfirmationTimeoutError = _chunkMDLZJGLYcjs.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 = _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.decorateOutcome = decorateOutcome; exports.eip3009Abi = eip3009Abi; exports.encodeXPaymentHeader = encodeXPaymentHeader; exports.evaluatePolicy = evaluatePolicy; exports.getDirectoryInfo = getDirectoryInfo; 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;