@relai-fi/x402 0.6.5 → 0.6.7

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 (78) hide show
  1. package/README.md +251 -0
  2. package/dist/bridge.cjs +109 -0
  3. package/dist/bridge.cjs.map +1 -0
  4. package/dist/bridge.d.cts +78 -0
  5. package/dist/bridge.d.ts +78 -0
  6. package/dist/bridge.js +80 -0
  7. package/dist/bridge.js.map +1 -0
  8. package/dist/client.cjs +131 -1
  9. package/dist/client.cjs.map +1 -1
  10. package/dist/client.d.cts +13 -1
  11. package/dist/client.d.ts +13 -1
  12. package/dist/client.js +131 -1
  13. package/dist/client.js.map +1 -1
  14. package/dist/index.cjs +586 -105
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +291 -30
  17. package/dist/index.d.ts +291 -30
  18. package/dist/index.js +578 -105
  19. package/dist/index.js.map +1 -1
  20. package/dist/mpp/bridge-client.cjs +23922 -0
  21. package/dist/mpp/bridge-client.cjs.map +1 -0
  22. package/dist/mpp/bridge-client.d.cts +58 -0
  23. package/dist/mpp/bridge-client.d.ts +58 -0
  24. package/dist/mpp/bridge-client.js +23892 -0
  25. package/dist/mpp/bridge-client.js.map +1 -0
  26. package/dist/mpp/bridge-method.cjs +13202 -0
  27. package/dist/mpp/bridge-method.cjs.map +1 -0
  28. package/dist/mpp/bridge-method.d.cts +69 -0
  29. package/dist/mpp/bridge-method.d.ts +69 -0
  30. package/dist/mpp/bridge-method.js +13181 -0
  31. package/dist/mpp/bridge-method.js.map +1 -0
  32. package/dist/mpp/bridge-server.cjs +13887 -0
  33. package/dist/mpp/bridge-server.cjs.map +1 -0
  34. package/dist/mpp/bridge-server.d.cts +62 -0
  35. package/dist/mpp/bridge-server.d.ts +62 -0
  36. package/dist/mpp/bridge-server.js +13866 -0
  37. package/dist/mpp/bridge-server.js.map +1 -0
  38. package/dist/mpp/evm-server.cjs +49 -33
  39. package/dist/mpp/evm-server.cjs.map +1 -1
  40. package/dist/mpp/evm-server.js +49 -33
  41. package/dist/mpp/evm-server.js.map +1 -1
  42. package/dist/mpp/verify-erc20.cjs +71 -0
  43. package/dist/mpp/verify-erc20.cjs.map +1 -0
  44. package/dist/mpp/verify-erc20.d.cts +27 -0
  45. package/dist/mpp/verify-erc20.d.ts +27 -0
  46. package/dist/mpp/verify-erc20.js +46 -0
  47. package/dist/mpp/verify-erc20.js.map +1 -0
  48. package/dist/mpp/verify-spl.cjs +96 -0
  49. package/dist/mpp/verify-spl.cjs.map +1 -0
  50. package/dist/mpp/verify-spl.d.cts +30 -0
  51. package/dist/mpp/verify-spl.d.ts +30 -0
  52. package/dist/mpp/verify-spl.js +71 -0
  53. package/dist/mpp/verify-spl.js.map +1 -0
  54. package/dist/mpp/with-bridge.cjs +23956 -0
  55. package/dist/mpp/with-bridge.cjs.map +1 -0
  56. package/dist/mpp/with-bridge.d.cts +53 -0
  57. package/dist/mpp/with-bridge.d.ts +53 -0
  58. package/dist/mpp/with-bridge.js +23926 -0
  59. package/dist/mpp/with-bridge.js.map +1 -0
  60. package/dist/plugins.d.cts +2 -2
  61. package/dist/plugins.d.ts +2 -2
  62. package/dist/react/index.cjs +131 -1
  63. package/dist/react/index.cjs.map +1 -1
  64. package/dist/react/index.d.cts +1 -1
  65. package/dist/react/index.d.ts +1 -1
  66. package/dist/react/index.js +131 -1
  67. package/dist/react/index.js.map +1 -1
  68. package/dist/{server-DaySqG5H.d.ts → server-D9ZfrFFx.d.ts} +1 -1
  69. package/dist/{server-CBZ2RjEP.d.cts → server-DgMG2zhy.d.cts} +1 -1
  70. package/dist/server.cjs +6 -39
  71. package/dist/server.cjs.map +1 -1
  72. package/dist/server.d.cts +2 -2
  73. package/dist/server.d.ts +2 -2
  74. package/dist/server.js +6 -39
  75. package/dist/server.js.map +1 -1
  76. package/dist/{types-Y9ni5XwY.d.cts → types-DjEveKgt.d.cts} +1 -1
  77. package/dist/{types-Y9ni5XwY.d.ts → types-DjEveKgt.d.ts} +1 -1
  78. package/package.json +31 -1
package/dist/index.cjs CHANGED
@@ -7021,6 +7021,7 @@ __export(index_exports, {
7021
7021
  CHAIN_IDS: () => CHAIN_IDS,
7022
7022
  EXPLORER_TX_URL: () => EXPLORER_TX_URL,
7023
7023
  NETWORK_CAIP2: () => NETWORK_CAIP2,
7024
+ NETWORK_CONFIGS: () => NETWORK_CONFIGS,
7024
7025
  NETWORK_LABELS: () => NETWORK_LABELS,
7025
7026
  NETWORK_TOKENS: () => NETWORK_TOKENS,
7026
7027
  NETWORK_V1_TO_V2: () => NETWORK_V1_TO_V2,
@@ -7032,9 +7033,12 @@ __export(index_exports, {
7032
7033
  USDC_ADDRESSES: () => USDC_ADDRESSES,
7033
7034
  USDC_BASE: () => USDC_BASE,
7034
7035
  USDC_SOLANA: () => USDC_SOLANA,
7036
+ cancelPaymentCode: () => cancelPaymentCode,
7035
7037
  convertPayloadToVersion: () => convertPayloadToVersion,
7036
7038
  convertV1ToV2: () => convertV1ToV2,
7037
7039
  convertV2ToV1: () => convertV2ToV1,
7040
+ createPayRequest: () => createPayRequest,
7041
+ createPrivateKeySigner: () => createPrivateKeySigner,
7038
7042
  createX402Client: () => createX402Client,
7039
7043
  default: () => Relai,
7040
7044
  detectPayloadVersion: () => detectPayloadVersion,
@@ -7044,6 +7048,8 @@ __export(index_exports, {
7044
7048
  formatUsd: () => formatUsd,
7045
7049
  fromAtomicUnits: () => fromAtomicUnits,
7046
7050
  generatePaymentCode: () => generatePaymentCode,
7051
+ generatePaymentCodesBatch: () => generatePaymentCodesBatch,
7052
+ getPayRequest: () => getPayRequest,
7047
7053
  getPaymentCode: () => getPaymentCode,
7048
7054
  isEvm: () => isEvm,
7049
7055
  isEvmNetwork: () => isEvmNetwork,
@@ -7053,6 +7059,8 @@ __export(index_exports, {
7053
7059
  networkV2ToV1: () => networkV2ToV1,
7054
7060
  normalizeNetwork: () => normalizeNetwork,
7055
7061
  normalizePaymentHeader: () => normalizePaymentHeader,
7062
+ payPayRequest: () => payPayRequest,
7063
+ payPayRequestWithCode: () => payPayRequestWithCode,
7056
7064
  redeemPaymentCode: () => redeemPaymentCode,
7057
7065
  resolveToken: () => resolveToken,
7058
7066
  stripePayTo: () => stripePayTo,
@@ -7624,7 +7632,6 @@ var Relai = class {
7624
7632
  const integritasMode = integritasFlow === "single" ? "single_signature_fee_included" : integritasFlow === "dual" ? "dual_signature_split" : void 0;
7625
7633
  const paymentHeader = req.headers["x-payment"] || req.headers["payment-signature"] || req.headers["x-payment-signature"];
7626
7634
  const authHeader = req.headers["authorization"] || "";
7627
- console.log(`[Relai] MPP check: paymentHeader=${!!paymentHeader}, hasMpp=${!!self.mpp}, authHeader=${authHeader?.slice(0, 30)}`);
7628
7635
  if (!paymentHeader && self.mpp && /^Payment\s+/i.test(authHeader)) {
7629
7636
  try {
7630
7637
  const mppAmount = resolvedPrice.toFixed(6);
@@ -7636,10 +7643,7 @@ var Relai = class {
7636
7643
  const mppRequest = new Request(mppUrl, { method: req.method, headers: mppHeaders });
7637
7644
  const chargeHandler = self.mpp.charge({ amount: mppAmount });
7638
7645
  const mppResult = await chargeHandler(mppRequest);
7639
- console.log(`[Relai] MPP charge result: status=${mppResult.status}, keys=${Object.keys(mppResult)}, hasChallenge=${!!mppResult.challenge}, hasWithReceipt=${!!mppResult.withReceipt}`);
7640
7646
  if (mppResult.status === 402 && mppResult.challenge instanceof Response) {
7641
- const retryAuth = mppResult.challenge.headers.get("www-authenticate");
7642
- console.log(`[Relai] MPP re-challenged (credential not accepted). New WWW-Auth: ${retryAuth?.slice(0, 60)}`);
7643
7647
  }
7644
7648
  if (mppResult.status !== 200 && !mppResult.withReceipt && mppResult.status !== 402) {
7645
7649
  if (self.plugins.length > 0) {
@@ -7682,7 +7686,10 @@ var Relai = class {
7682
7686
  const dummyResponse = new Response(null);
7683
7687
  const receiptResponse = mppResult.withReceipt(dummyResponse);
7684
7688
  const receiptHeader = receiptResponse.headers.get("payment-receipt");
7685
- if (receiptHeader) res.setHeader("Payment-Receipt", receiptHeader);
7689
+ if (receiptHeader) {
7690
+ res.setHeader?.("Payment-Receipt", receiptHeader);
7691
+ res.setHeader?.("Cache-Control", "private");
7692
+ }
7686
7693
  }
7687
7694
  options.onPaymentSettled?.(req, {
7688
7695
  success: true,
@@ -7899,12 +7906,13 @@ var Relai = class {
7899
7906
  if (mppResult?.challenge instanceof Response) {
7900
7907
  const wwwAuth = mppResult.challenge.headers.get("www-authenticate");
7901
7908
  if (wwwAuth) {
7902
- res.setHeader("WWW-Authenticate", wwwAuth);
7909
+ res.setHeader?.("WWW-Authenticate", wwwAuth);
7903
7910
  }
7904
7911
  }
7905
7912
  } catch {
7906
7913
  }
7907
7914
  }
7915
+ res.setHeader?.("Cache-Control", "no-store");
7908
7916
  return res.status(402).json(paymentRequiredResponse);
7909
7917
  }
7910
7918
  let paymentProof;
@@ -7921,39 +7929,6 @@ var Relai = class {
7921
7929
  });
7922
7930
  }
7923
7931
  }
7924
- if (paymentProof.bridged === true && paymentProof.targetTxId) {
7925
- console.log(`[Relai] Bridged payment accepted: source=${paymentProof.sourceTxId}, target=${paymentProof.targetTxId}`);
7926
- const paymentInfo2 = {
7927
- verified: true,
7928
- transactionId: paymentProof.targetTxId,
7929
- payer: paymentProof.sourceTxId || "bridge",
7930
- network,
7931
- amount: resolvedPrice
7932
- };
7933
- req.payment = paymentInfo2;
7934
- req.x402Payer = paymentProof.sourceTxId || "bridge";
7935
- req.x402Paid = true;
7936
- req.x402Transaction = paymentProof.targetTxId;
7937
- req.x402Network = network;
7938
- req.x402Bridged = true;
7939
- req.x402SourceChain = paymentProof.sourceChain;
7940
- const paymentResponse2 = {
7941
- x402Version: 2,
7942
- scheme: "exact",
7943
- network: caip2,
7944
- transaction: paymentProof.targetTxId,
7945
- payer: paymentProof.sourceTxId,
7946
- amount: amount2,
7947
- asset,
7948
- bridged: true
7949
- };
7950
- res.setHeader(
7951
- "PAYMENT-RESPONSE",
7952
- Buffer.from(JSON.stringify(paymentResponse2)).toString("base64")
7953
- );
7954
- options.onPaymentSettled?.(req, { success: true, transaction: paymentProof.targetTxId, payer: paymentProof.sourceTxId });
7955
- return next();
7956
- }
7957
7932
  let settlePayTo;
7958
7933
  if (stripeConfig) {
7959
7934
  settlePayTo = paymentProof.payload?.authorization?.to || paymentProof.accepted?.payTo || "";
@@ -8100,6 +8075,73 @@ var server_default = Relai;
8100
8075
  // src/client.ts
8101
8076
  var import_web3 = require("@solana/web3.js");
8102
8077
  var import_spl_token = require("@solana/spl-token");
8078
+
8079
+ // src/bridge.ts
8080
+ var RELAI_API_BASE = "https://api.relai.fi";
8081
+ var _cacheMap = /* @__PURE__ */ new Map();
8082
+ var CACHE_TTL = 5 * 60 * 1e3;
8083
+ async function getBridgeInfo(baseUrl = RELAI_API_BASE) {
8084
+ const key = baseUrl.replace(/\/$/, "");
8085
+ const now = Date.now();
8086
+ const cached2 = _cacheMap.get(key);
8087
+ if (cached2 && now - cached2.time < CACHE_TTL) return cached2.info;
8088
+ const url2 = `${key}/bridge/info`;
8089
+ const res = await fetch(url2);
8090
+ if (!res.ok) {
8091
+ if (cached2) return cached2.info;
8092
+ throw new Error(`[relai:bridge] Failed to fetch ${url2}: ${res.status}`);
8093
+ }
8094
+ const data = await res.json();
8095
+ const info = {
8096
+ settleEndpoint: data.settleEndpoint,
8097
+ supportedSourceChains: data.supportedSourceChains || [],
8098
+ supportedSourceAssets: data.supportedSourceAssets || [],
8099
+ payTo: data.payTo || {},
8100
+ feePayerSvm: data.feePayerSvm ?? null,
8101
+ feeBps: data.feeBps ?? 100,
8102
+ paymentFacilitator: data.paymentFacilitator || "https://facilitator.x402.fi"
8103
+ };
8104
+ _cacheMap.set(key, { info, time: now });
8105
+ return info;
8106
+ }
8107
+ async function settleBridge(settleEndpoint, body) {
8108
+ const res = await fetch(settleEndpoint, {
8109
+ method: "POST",
8110
+ headers: { "Content-Type": "application/json" },
8111
+ body: JSON.stringify(body)
8112
+ });
8113
+ if (!res.ok) {
8114
+ const err = await res.json().catch(() => ({}));
8115
+ throw new Error(`[relai:bridge] settle failed: ${err.error || res.status}${err.details ? " \u2014 " + err.details : ""}`);
8116
+ }
8117
+ return res.json();
8118
+ }
8119
+ function selectSourceChain(supportedChains, hasEvmWallet, hasSolanaWallet, preferredSourceChainId) {
8120
+ if (preferredSourceChainId && hasEvmWallet) {
8121
+ const preferred = `eip155:${preferredSourceChainId}`;
8122
+ if (supportedChains.includes(preferred)) {
8123
+ return { type: "evm", chain: preferred };
8124
+ }
8125
+ }
8126
+ if (hasSolanaWallet) {
8127
+ const sol = supportedChains.find((c) => c.startsWith("solana:"));
8128
+ if (sol) return { type: "solana", chain: sol };
8129
+ }
8130
+ if (hasEvmWallet) {
8131
+ for (const chain of supportedChains) {
8132
+ if (chain.startsWith("eip155:")) {
8133
+ return { type: "evm", chain };
8134
+ }
8135
+ }
8136
+ }
8137
+ return null;
8138
+ }
8139
+ function computeSourceAmount(targetAmount, feeBps) {
8140
+ const fee = targetAmount * BigInt(feeBps) / 10000n;
8141
+ return targetAmount + fee;
8142
+ }
8143
+
8144
+ // src/client.ts
8103
8145
  var PERMIT_NETWORKS = /* @__PURE__ */ new Set([]);
8104
8146
  var DEFAULT_EVM_RPC_URLS = {
8105
8147
  "skale-base": "https://skale-base.skalenodes.com/v1/base",
@@ -8125,7 +8167,8 @@ function createX402Client(config2) {
8125
8167
  integritas,
8126
8168
  verbose = false,
8127
8169
  defaultHeaders = {},
8128
- mpp
8170
+ mpp,
8171
+ bridge: bridgeConfig
8129
8172
  } = config2;
8130
8173
  const relayWsEnabled = relayWs?.enabled === true;
8131
8174
  const relayWsPreflightTimeoutMs = relayWs?.preflightTimeoutMs ?? 5e3;
@@ -9240,6 +9283,70 @@ function createX402Client(config2) {
9240
9283
  headers: { ...requestHeaders, "X-PAYMENT": paymentHeader }
9241
9284
  });
9242
9285
  }
9286
+ if (bridgeConfig?.enabled) {
9287
+ log("No direct wallet match \u2014 attempting auto-bridge via RelAI API");
9288
+ try {
9289
+ const info = await getBridgeInfo(bridgeConfig.baseUrl);
9290
+ const targetAccept = accepts[0];
9291
+ const hasEvm = !!effectiveWallets.evm;
9292
+ const hasSol = !!hasSolanaWallet;
9293
+ const source = selectSourceChain(info.supportedSourceChains, hasEvm, hasSol);
9294
+ if (source) {
9295
+ const bridgePayTo = info.payTo[source.chain];
9296
+ if (bridgePayTo) {
9297
+ const targetAmount = targetAccept.amount || targetAccept.maxAmountRequired;
9298
+ const sourceAmount = computeSourceAmount(BigInt(targetAmount), info.feeBps).toString();
9299
+ const sourceChainIdx = info.supportedSourceChains.indexOf(source.chain);
9300
+ const sourceAsset = sourceChainIdx >= 0 && info.supportedSourceAssets[sourceChainIdx] || (source.type === "evm" ? info.supportedSourceAssets.find((a) => a.startsWith("0x")) || targetAccept.asset : info.supportedSourceAssets.find((a) => !a.startsWith("0x")) || "");
9301
+ let sourcePaymentHeader;
9302
+ const sourceAccept = {
9303
+ scheme: "exact",
9304
+ network: source.chain,
9305
+ asset: sourceAsset,
9306
+ payTo: bridgePayTo,
9307
+ amount: sourceAmount,
9308
+ extra: {
9309
+ ...targetAccept.extra || {},
9310
+ ...source.type === "solana" && info.feePayerSvm ? { feePayer: info.feePayerSvm } : {}
9311
+ }
9312
+ };
9313
+ if (source.type === "solana" && hasSolanaWallet) {
9314
+ sourcePaymentHeader = await buildSolanaPayment(sourceAccept, requirements, url2);
9315
+ } else if (source.type === "evm") {
9316
+ const evmNetwork = normalizeNetwork(source.chain);
9317
+ const usePermit = evmNetwork && PERMIT_NETWORKS.has(evmNetwork);
9318
+ sourcePaymentHeader = usePermit ? await buildEvmPermitPayment(sourceAccept, requirements, url2) : await buildEvmPayment(sourceAccept, requirements, url2);
9319
+ } else {
9320
+ throw new Error(`[relai-x402] No wallet for source chain type: ${source.type}`);
9321
+ }
9322
+ const settleData = await settleBridge(info.settleEndpoint, {
9323
+ sourcePayment: sourcePaymentHeader,
9324
+ sourceChain: source.chain,
9325
+ targetAccept: {
9326
+ scheme: "exact",
9327
+ network: targetAccept.network,
9328
+ asset: targetAccept.asset,
9329
+ payTo: targetAccept.payTo,
9330
+ amount: targetAmount
9331
+ },
9332
+ requirements,
9333
+ resource: url2,
9334
+ paymentFacilitator: info.paymentFacilitator
9335
+ });
9336
+ if (settleData.xPayment) {
9337
+ log(`Auto-bridge settled: target=${settleData.targetTxId}`);
9338
+ return fetch(input, {
9339
+ ...requestInitWithHeaders,
9340
+ headers: { ...requestHeaders, "X-PAYMENT": settleData.xPayment }
9341
+ });
9342
+ }
9343
+ throw new Error("[relai-x402] Bridge settle did not return xPayment");
9344
+ }
9345
+ }
9346
+ } catch (bridgeErr) {
9347
+ log(`Auto-bridge failed: ${bridgeErr instanceof Error ? bridgeErr.message : bridgeErr}`);
9348
+ }
9349
+ }
9243
9350
  throw new Error(buildNoWalletError(accepts, false));
9244
9351
  }
9245
9352
  const { accept, chain } = selected;
@@ -9336,8 +9443,37 @@ function submitRelayFeedback(config2) {
9336
9443
  }
9337
9444
 
9338
9445
  // src/payment-codes.ts
9339
- var DEFAULT_FACILITATOR = "https://relai.fi/facilitator";
9340
- var DEFAULT_USDC_BASE = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
9446
+ var import_ethers2 = require("ethers");
9447
+ var NETWORK_CONFIGS = {
9448
+ "base": {
9449
+ chainId: 8453,
9450
+ usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
9451
+ domainName: "USD Coin",
9452
+ rpc: "https://mainnet.base.org",
9453
+ settlementNetwork: "base"
9454
+ },
9455
+ "base-sepolia": {
9456
+ chainId: 84532,
9457
+ usdc: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
9458
+ domainName: "USDC",
9459
+ rpc: "https://sepolia.base.org",
9460
+ settlementNetwork: "base-sepolia"
9461
+ },
9462
+ "skale-base-sepolia": {
9463
+ chainId: 324705682,
9464
+ usdc: "0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",
9465
+ domainName: "Bridged USDC (SKALE Bridge)",
9466
+ rpc: "https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",
9467
+ settlementNetwork: "skale-base-sepolia"
9468
+ },
9469
+ "skale-base": {
9470
+ chainId: 1482601649,
9471
+ usdc: "0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",
9472
+ domainName: "Bridged USDC",
9473
+ rpc: "https://skale-base.skalenodes.com/v1/base",
9474
+ settlementNetwork: "skale-base"
9475
+ }
9476
+ };
9341
9477
  var EIP3009_TYPES = {
9342
9478
  TransferWithAuthorization: [
9343
9479
  { name: "from", type: "address" },
@@ -9348,6 +9484,14 @@ var EIP3009_TYPES = {
9348
9484
  { name: "nonce", type: "bytes32" }
9349
9485
  ]
9350
9486
  };
9487
+ function createPrivateKeySigner(privateKey) {
9488
+ const wallet = new import_ethers2.ethers.Wallet(privateKey);
9489
+ return {
9490
+ getAddress: () => Promise.resolve(wallet.address),
9491
+ signTypedData: (domain2, types, value) => wallet.signTypedData(domain2, types, value)
9492
+ };
9493
+ }
9494
+ var DEFAULT_FACILITATOR = "https://relai.fi/facilitator";
9351
9495
  function randomBytes32() {
9352
9496
  const bytes = new Uint8Array(32);
9353
9497
  if (typeof globalThis.crypto !== "undefined") {
@@ -9358,69 +9502,323 @@ function randomBytes32() {
9358
9502
  }
9359
9503
  return "0x" + Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
9360
9504
  }
9361
- async function generatePaymentCode(config2, params) {
9362
- const { signer, to, value, usdcContract, ttl = 120 } = params;
9363
- const facilitatorUrl = config2.facilitatorUrl || DEFAULT_FACILITATOR;
9364
- const usdc = usdcContract || DEFAULT_USDC_BASE;
9365
- const from4 = await signer.getAddress();
9366
- const now = Math.floor(Date.now() / 1e3);
9367
- const validAfter = 0;
9368
- const validBefore = now + ttl;
9369
- const nonce = randomBytes32();
9505
+ async function fetchToAddress(facilitatorUrl, network) {
9506
+ const res = await fetch(`${facilitatorUrl}/payment-codes/relayer?network=${network}`);
9507
+ if (!res.ok) throw new Error("Failed to fetch relayer address from facilitator");
9508
+ const data = await res.json();
9509
+ if (!data.toAddress) throw new Error("Facilitator returned no toAddress");
9510
+ return data.toAddress;
9511
+ }
9512
+ async function signEip3009(signer, net, from4, toAddress, value, validAfter, validBefore, nonce, usdcOverride) {
9370
9513
  const domain2 = {
9371
- name: "USD Coin",
9514
+ name: net.domainName,
9372
9515
  version: "2",
9373
- chainId: 8453,
9374
- // Base mainnet
9375
- verifyingContract: usdc
9516
+ chainId: net.chainId,
9517
+ verifyingContract: usdcOverride ?? net.usdc
9376
9518
  };
9377
- const message = {
9519
+ return signer.signTypedData(domain2, EIP3009_TYPES, {
9378
9520
  from: from4,
9379
- to,
9380
- value: BigInt(value).toString(),
9521
+ to: toAddress,
9522
+ value,
9381
9523
  validAfter,
9382
9524
  validBefore,
9383
9525
  nonce
9384
- };
9385
- const signature2 = await signer.signTypedData(domain2, EIP3009_TYPES, message);
9526
+ });
9527
+ }
9528
+ async function generatePaymentCode(config2, params) {
9529
+ const {
9530
+ signer,
9531
+ value,
9532
+ ttl = 86400,
9533
+ description,
9534
+ payee,
9535
+ usdcContract,
9536
+ network = "base-sepolia"
9537
+ } = params;
9538
+ const facilitatorUrl = config2.facilitatorUrl ?? DEFAULT_FACILITATOR;
9539
+ const net = NETWORK_CONFIGS[network];
9540
+ if (!net) throw new Error(`Unsupported network: ${network}`);
9541
+ const from4 = await signer.getAddress();
9542
+ const now = Math.floor(Date.now() / 1e3);
9543
+ const validBefore = now + ttl;
9544
+ const nonce = randomBytes32();
9545
+ const usdc = usdcContract ?? net.usdc;
9546
+ const toAddress = await fetchToAddress(facilitatorUrl, network);
9547
+ const signature2 = await signEip3009(
9548
+ signer,
9549
+ net,
9550
+ from4,
9551
+ toAddress,
9552
+ BigInt(value).toString(),
9553
+ 0,
9554
+ validBefore,
9555
+ nonce,
9556
+ usdc
9557
+ );
9386
9558
  const res = await fetch(`${facilitatorUrl}/payment-codes`, {
9387
9559
  method: "POST",
9388
9560
  headers: { "Content-Type": "application/json" },
9389
9561
  body: JSON.stringify({
9390
9562
  from: from4,
9391
- to,
9392
9563
  value: BigInt(value).toString(),
9393
- validAfter,
9564
+ validAfter: 0,
9394
9565
  validBefore,
9395
9566
  nonce,
9396
9567
  signature: signature2,
9397
- usdcContract: usdc
9568
+ usdcContract: usdc,
9569
+ settlementNetwork: net.settlementNetwork,
9570
+ ...description ? { description } : {},
9571
+ ...payee ? { payee } : {}
9398
9572
  })
9399
9573
  });
9400
9574
  if (!res.ok) {
9401
9575
  const err = await res.json().catch(() => ({}));
9402
- throw new Error(`Failed to register payment code: ${err.error || res.status}`);
9576
+ throw new Error(`Failed to register payment code: ${err.error ?? res.status}`);
9403
9577
  }
9404
9578
  return res.json();
9405
9579
  }
9406
- async function redeemPaymentCode(config2, code) {
9407
- const facilitatorUrl = config2.facilitatorUrl || DEFAULT_FACILITATOR;
9408
- const res = await fetch(`${facilitatorUrl}/payment-codes/${code.toUpperCase()}/redeem`, {
9580
+ async function generatePaymentCodesBatch(config2, params) {
9581
+ const {
9582
+ signer,
9583
+ codes,
9584
+ payee,
9585
+ usdcContract,
9586
+ network = "base-sepolia",
9587
+ authToken
9588
+ } = params;
9589
+ const facilitatorUrl = config2.facilitatorUrl ?? DEFAULT_FACILITATOR;
9590
+ const net = NETWORK_CONFIGS[network];
9591
+ if (!net) throw new Error(`Unsupported network: ${network}`);
9592
+ if (codes.length > 20) throw new Error("Maximum 20 codes per batch");
9593
+ const from4 = await signer.getAddress();
9594
+ const usdc = usdcContract ?? net.usdc;
9595
+ const now = Math.floor(Date.now() / 1e3);
9596
+ const toAddress = await fetchToAddress(facilitatorUrl, network);
9597
+ const signedCodes = await Promise.all(
9598
+ codes.map(async (item) => {
9599
+ const validBefore = now + (item.ttl ?? 86400);
9600
+ const nonce = randomBytes32();
9601
+ const value = BigInt(item.value).toString();
9602
+ const signature2 = await signEip3009(
9603
+ signer,
9604
+ net,
9605
+ from4,
9606
+ toAddress,
9607
+ value,
9608
+ 0,
9609
+ validBefore,
9610
+ nonce,
9611
+ usdc
9612
+ );
9613
+ return { value, validAfter: 0, validBefore, nonce, signature: signature2 };
9614
+ })
9615
+ );
9616
+ const res = await fetch(`${facilitatorUrl}/payment-codes/batch`, {
9409
9617
  method: "POST",
9410
- headers: { "Content-Type": "application/json" }
9618
+ headers: {
9619
+ "Content-Type": "application/json",
9620
+ "Authorization": `Bearer ${authToken}`
9621
+ },
9622
+ body: JSON.stringify({
9623
+ from: from4,
9624
+ settlementNetwork: net.settlementNetwork,
9625
+ usdcContract: usdc,
9626
+ ...payee ? { payee } : {},
9627
+ codes: signedCodes
9628
+ })
9411
9629
  });
9412
9630
  if (!res.ok) {
9413
9631
  const err = await res.json().catch(() => ({}));
9414
- throw new Error(`Failed to redeem payment code: ${err.error || res.status}`);
9632
+ throw new Error(`Batch registration failed: ${err.error ?? res.status}`);
9633
+ }
9634
+ return res.json();
9635
+ }
9636
+ async function redeemPaymentCode(config2, code, payee) {
9637
+ const facilitatorUrl = config2.facilitatorUrl ?? DEFAULT_FACILITATOR;
9638
+ const res = await fetch(
9639
+ `${facilitatorUrl}/payment-codes/${code.trim().toUpperCase()}/redeem`,
9640
+ {
9641
+ method: "POST",
9642
+ headers: { "Content-Type": "application/json" },
9643
+ body: JSON.stringify(payee ? { payee } : {})
9644
+ }
9645
+ );
9646
+ if (!res.ok) {
9647
+ const err = await res.json().catch(() => ({}));
9648
+ throw new Error(err.error ?? `Redeem failed: ${res.status}`);
9415
9649
  }
9416
9650
  return res.json();
9417
9651
  }
9418
9652
  async function getPaymentCode(config2, code) {
9419
- const facilitatorUrl = config2.facilitatorUrl || DEFAULT_FACILITATOR;
9420
- const res = await fetch(`${facilitatorUrl}/payment-codes/${code.toUpperCase()}`);
9653
+ const facilitatorUrl = config2.facilitatorUrl ?? DEFAULT_FACILITATOR;
9654
+ const res = await fetch(
9655
+ `${facilitatorUrl}/payment-codes/${code.trim().toUpperCase()}`
9656
+ );
9657
+ if (!res.ok) {
9658
+ const err = await res.json().catch(() => ({}));
9659
+ throw new Error(`Payment code not found: ${err.error ?? res.status}`);
9660
+ }
9661
+ return res.json();
9662
+ }
9663
+ async function cancelPaymentCode(config2, code) {
9664
+ const facilitatorUrl = config2.facilitatorUrl ?? DEFAULT_FACILITATOR;
9665
+ const res = await fetch(
9666
+ `${facilitatorUrl}/payment-codes/${code.trim().toUpperCase()}`,
9667
+ { method: "DELETE" }
9668
+ );
9421
9669
  if (!res.ok) {
9422
9670
  const err = await res.json().catch(() => ({}));
9423
- throw new Error(`Payment code not found: ${err.error || res.status}`);
9671
+ throw new Error(`Cancel failed: ${err.error ?? res.status}`);
9672
+ }
9673
+ return res.json();
9674
+ }
9675
+
9676
+ // src/payment-requests.ts
9677
+ var DEFAULT_FACILITATOR2 = "https://relai.fi/facilitator";
9678
+ var EIP3009_TYPES2 = {
9679
+ TransferWithAuthorization: [
9680
+ { name: "from", type: "address" },
9681
+ { name: "to", type: "address" },
9682
+ { name: "value", type: "uint256" },
9683
+ { name: "validAfter", type: "uint256" },
9684
+ { name: "validBefore", type: "uint256" },
9685
+ { name: "nonce", type: "bytes32" }
9686
+ ]
9687
+ };
9688
+ function randomBytes322() {
9689
+ const bytes = new Uint8Array(32);
9690
+ if (typeof globalThis.crypto !== "undefined") {
9691
+ globalThis.crypto.getRandomValues(bytes);
9692
+ } else {
9693
+ const { randomBytes: randomBytes2 } = require("crypto");
9694
+ randomBytes2(32).copy(Buffer.from(bytes.buffer));
9695
+ }
9696
+ return "0x" + Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
9697
+ }
9698
+ async function createPayRequest(config2, params) {
9699
+ const {
9700
+ to,
9701
+ amount: amount2,
9702
+ network = "base-sepolia",
9703
+ description,
9704
+ ttlSeconds
9705
+ } = params;
9706
+ const facilitatorUrl = config2.facilitatorUrl ?? DEFAULT_FACILITATOR2;
9707
+ const res = await fetch(`${facilitatorUrl}/payment-requests`, {
9708
+ method: "POST",
9709
+ headers: { "Content-Type": "application/json" },
9710
+ body: JSON.stringify({
9711
+ to,
9712
+ amount: Number(amount2),
9713
+ network,
9714
+ ...description ? { description } : {},
9715
+ ...ttlSeconds ? { ttlSeconds } : {}
9716
+ })
9717
+ });
9718
+ if (!res.ok) {
9719
+ const err = await res.json().catch(() => ({}));
9720
+ throw new Error(`Failed to create payment request: ${err.error ?? res.status}`);
9721
+ }
9722
+ return res.json();
9723
+ }
9724
+ async function getPayRequest(config2, code) {
9725
+ const facilitatorUrl = config2.facilitatorUrl ?? DEFAULT_FACILITATOR2;
9726
+ const res = await fetch(
9727
+ `${facilitatorUrl}/payment-requests/${code.trim().toUpperCase()}`
9728
+ );
9729
+ if (!res.ok) {
9730
+ const err = await res.json().catch(() => ({}));
9731
+ throw new Error(`Payment request not found: ${err.error ?? res.status}`);
9732
+ }
9733
+ return res.json();
9734
+ }
9735
+ async function payPayRequest(config2, code, signer) {
9736
+ const facilitatorUrl = config2.facilitatorUrl ?? DEFAULT_FACILITATOR2;
9737
+ const info = await getPayRequest(config2, code);
9738
+ if (!info.payable) {
9739
+ throw new Error(
9740
+ info.status === "paid" ? "Payment request already paid" : "Payment request expired or not payable"
9741
+ );
9742
+ }
9743
+ const netKey = info.network;
9744
+ const net = NETWORK_CONFIGS[netKey];
9745
+ if (!net) throw new Error(`Unknown network from payment request: ${info.network}`);
9746
+ const from4 = await signer.getAddress();
9747
+ const now = Math.floor(Date.now() / 1e3);
9748
+ const validBefore = Math.min(now + 300, info.validUntil);
9749
+ const nonce = randomBytes322();
9750
+ const domain2 = {
9751
+ name: net.domainName,
9752
+ version: "2",
9753
+ chainId: net.chainId,
9754
+ verifyingContract: info.usdcContract
9755
+ };
9756
+ const signature2 = await signer.signTypedData(domain2, EIP3009_TYPES2, {
9757
+ from: from4,
9758
+ to: info.toAddress,
9759
+ // settler/relayer — NOT the merchant directly
9760
+ value: String(info.amount),
9761
+ validAfter: 0,
9762
+ validBefore,
9763
+ nonce
9764
+ });
9765
+ const res = await fetch(
9766
+ `${facilitatorUrl}/payment-requests/${code.trim().toUpperCase()}/pay`,
9767
+ {
9768
+ method: "POST",
9769
+ headers: { "Content-Type": "application/json" },
9770
+ body: JSON.stringify({ from: from4, validAfter: 0, validBefore, nonce, signature: signature2 })
9771
+ }
9772
+ );
9773
+ if (!res.ok) {
9774
+ const err = await res.json().catch(() => ({}));
9775
+ throw new Error(err.error ?? `Payment failed: ${res.status}`);
9776
+ }
9777
+ return res.json();
9778
+ }
9779
+ async function payPayRequestWithCode(config2, requestCode, paymentCode, options = {}) {
9780
+ const { allowOverpayment = true, returnChange = "code" } = options;
9781
+ const info = await getPayRequest(config2, requestCode);
9782
+ if (!info.payable) {
9783
+ throw new Error(
9784
+ info.status === "paid" ? "Payment request already paid" : "Payment request expired or not payable"
9785
+ );
9786
+ }
9787
+ const codeStatus = await getPaymentCode(config2, paymentCode);
9788
+ if (!codeStatus.redeemable) {
9789
+ throw new Error(
9790
+ codeStatus.redeemed ? "Payment code already redeemed" : "Payment code expired or not redeemable"
9791
+ );
9792
+ }
9793
+ const codeValue = BigInt(codeStatus.value);
9794
+ const reqAmount = BigInt(info.amount);
9795
+ if (codeValue < reqAmount) {
9796
+ throw new Error(
9797
+ `Payment code value (${Number(codeValue) / 1e6} USDC) is less than the request amount (${Number(reqAmount) / 1e6} USDC)`
9798
+ );
9799
+ }
9800
+ if (!allowOverpayment && codeValue > reqAmount) {
9801
+ throw new Error(
9802
+ `Payment code value (${Number(codeValue) / 1e6} USDC) exceeds the request amount (${Number(reqAmount) / 1e6} USDC). Generate a code for the exact amount, or pass { allowOverpayment: true }.`
9803
+ );
9804
+ }
9805
+ const facilitatorUrl = config2.facilitatorUrl ?? "https://relai.fi/facilitator";
9806
+ const usePartial = codeValue > reqAmount;
9807
+ const res = await fetch(
9808
+ `${facilitatorUrl}/payment-codes/${paymentCode.trim().toUpperCase()}/redeem`,
9809
+ {
9810
+ method: "POST",
9811
+ headers: { "Content-Type": "application/json" },
9812
+ body: JSON.stringify({
9813
+ payee: info.to,
9814
+ ...usePartial ? { invoiceAmount: info.amount.toString() } : {},
9815
+ ...usePartial ? { returnChangeAsCode: returnChange === "code" } : {}
9816
+ })
9817
+ }
9818
+ );
9819
+ if (!res.ok) {
9820
+ const err = await res.json().catch(() => ({}));
9821
+ throw new Error(err.error ?? `Redeem failed: ${res.status}`);
9424
9822
  }
9425
9823
  return res.json();
9426
9824
  }
@@ -22935,8 +23333,50 @@ var charge = Method_exports.from({
22935
23333
  }
22936
23334
  });
22937
23335
 
22938
- // src/mpp/evm-server.ts
23336
+ // src/mpp/verify-erc20.ts
22939
23337
  var TRANSFER_EVENT_TOPIC = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef";
23338
+ async function verifyErc20Transfer(opts) {
23339
+ const { txHash, rpcUrl, tokenAddress, recipient, expectedAmount } = opts;
23340
+ let receipt = null;
23341
+ for (let attempt = 0; attempt < 5; attempt++) {
23342
+ const receiptRes = await fetch(rpcUrl, {
23343
+ method: "POST",
23344
+ headers: { "Content-Type": "application/json" },
23345
+ body: JSON.stringify({
23346
+ jsonrpc: "2.0",
23347
+ id: 1,
23348
+ method: "eth_getTransactionReceipt",
23349
+ params: [txHash]
23350
+ })
23351
+ });
23352
+ const receiptData = await receiptRes.json();
23353
+ if (receiptData.error) {
23354
+ throw new Error(`RPC error: ${receiptData.error.message}`);
23355
+ }
23356
+ receipt = receiptData.result;
23357
+ if (receipt) break;
23358
+ await new Promise((r) => setTimeout(r, (attempt + 1) * 1e3));
23359
+ }
23360
+ if (!receipt) {
23361
+ throw new Error("Transaction not found or not yet confirmed");
23362
+ }
23363
+ if (receipt.status !== "0x1") {
23364
+ throw new Error("Transaction failed on-chain");
23365
+ }
23366
+ const recipientPadded = "0x" + recipient.slice(2).toLowerCase().padStart(64, "0");
23367
+ const tokenLower = tokenAddress.toLowerCase();
23368
+ const matchingLog = receipt.logs.find((log) => {
23369
+ if (log.address.toLowerCase() !== tokenLower) return false;
23370
+ if (log.topics[0] !== TRANSFER_EVENT_TOPIC) return false;
23371
+ if (log.topics[2]?.toLowerCase() !== recipientPadded) return false;
23372
+ return BigInt(log.data) >= expectedAmount;
23373
+ });
23374
+ if (!matchingLog) {
23375
+ throw new Error("No matching ERC-20 Transfer found for recipient and amount");
23376
+ }
23377
+ }
23378
+
23379
+ // src/mpp/evm-server.ts
22940
23380
  function evmCharge(config2) {
22941
23381
  const {
22942
23382
  recipient,
@@ -22978,39 +23418,13 @@ function evmCharge(config2) {
22978
23418
  if (!txHash || !txHash.startsWith("0x")) {
22979
23419
  throw new Error("Missing or invalid transaction hash in credential payload");
22980
23420
  }
22981
- const expectedAmount = BigInt(cred.challenge.request.amount);
22982
- const receiptRes = await fetch(rpcUrl, {
22983
- method: "POST",
22984
- headers: { "Content-Type": "application/json" },
22985
- body: JSON.stringify({
22986
- jsonrpc: "2.0",
22987
- id: 1,
22988
- method: "eth_getTransactionReceipt",
22989
- params: [txHash]
22990
- })
22991
- });
22992
- const receiptData = await receiptRes.json();
22993
- if (receiptData.error) {
22994
- throw new Error(`RPC error: ${receiptData.error.message}`);
22995
- }
22996
- const receipt = receiptData.result;
22997
- if (!receipt) {
22998
- throw new Error("Transaction not found or not yet confirmed");
22999
- }
23000
- if (receipt.status !== "0x1") {
23001
- throw new Error("Transaction failed on-chain");
23002
- }
23003
- const recipientPadded = "0x" + recipient.slice(2).toLowerCase().padStart(64, "0");
23004
- const tokenLower = tokenAddress.toLowerCase();
23005
- const matchingLog = receipt.logs.find((log) => {
23006
- if (log.address.toLowerCase() !== tokenLower) return false;
23007
- if (log.topics[0] !== TRANSFER_EVENT_TOPIC) return false;
23008
- if (log.topics[2]?.toLowerCase() !== recipientPadded) return false;
23009
- return BigInt(log.data) >= expectedAmount;
23421
+ await verifyErc20Transfer({
23422
+ txHash,
23423
+ rpcUrl,
23424
+ tokenAddress,
23425
+ recipient,
23426
+ expectedAmount: BigInt(cred.challenge.request.amount)
23010
23427
  });
23011
- if (!matchingLog) {
23012
- throw new Error("No matching ERC-20 Transfer found for recipient and amount");
23013
- }
23014
23428
  return Receipt_exports.from({
23015
23429
  method: "evm",
23016
23430
  reference: txHash,
@@ -26336,6 +26750,65 @@ async function waitForReceipt(rpcUrl, txHash, timeoutMs = 3e4) {
26336
26750
  }
26337
26751
  return false;
26338
26752
  }
26753
+
26754
+ // src/mpp/bridge-method.ts
26755
+ var charge2 = Method_exports.from({
26756
+ intent: "charge",
26757
+ name: "bridge",
26758
+ schema: {
26759
+ credential: {
26760
+ payload: zod_exports.object({
26761
+ /** "settled" = client called bridge settle, targetTxHash is proof */
26762
+ type: zod_exports.string(),
26763
+ /** Target chain tx hash (0x-prefixed) — server verifies on-chain */
26764
+ targetTxHash: zod_exports.optional(zod_exports.string()),
26765
+ /** Source chain tx hash/signature (for auditing) */
26766
+ sourceTxHash: zod_exports.optional(zod_exports.string()),
26767
+ /** CAIP-2 source chain used */
26768
+ sourceChain: zod_exports.optional(zod_exports.string())
26769
+ })
26770
+ },
26771
+ request: zod_exports.object({
26772
+ /** Amount in target token base units */
26773
+ amount: zod_exports.string(),
26774
+ /** Target ERC-20 token contract address */
26775
+ currency: zod_exports.string(),
26776
+ /** Target chain recipient address (merchant) */
26777
+ recipient: zod_exports.string(),
26778
+ /** Human-readable description */
26779
+ description: zod_exports.optional(zod_exports.string()),
26780
+ methodDetails: zod_exports.object({
26781
+ /** Target chain ID (where the merchant gets paid) */
26782
+ targetChainId: zod_exports.number(),
26783
+ /** Human-readable target network name (e.g. "skale-base") */
26784
+ targetNetwork: zod_exports.optional(zod_exports.string()),
26785
+ /** Target chain RPC URL (for server-side verification) */
26786
+ targetRpcUrl: zod_exports.optional(zod_exports.string()),
26787
+ /** Target token decimals */
26788
+ targetDecimals: zod_exports.optional(zod_exports.number()),
26789
+ /** Bridge settle endpoint URL */
26790
+ settleEndpoint: zod_exports.string(),
26791
+ /** Supported source chains (CAIP-2 format, e.g. ["eip155:8453", "solana:5eykt4..."]) */
26792
+ supportedSourceChains: zod_exports.array(zod_exports.string()),
26793
+ /** Supported source token addresses */
26794
+ supportedSourceAssets: zod_exports.optional(zod_exports.array(zod_exports.string())),
26795
+ /** Bridge receiver addresses per source chain: { [caip2]: address } */
26796
+ payToMap: zod_exports.record(zod_exports.string(), zod_exports.string()),
26797
+ /** Solana fee payer address (bridge facilitator sponsors gas) */
26798
+ feePayerSvm: zod_exports.optional(zod_exports.string()),
26799
+ /** Bridge fee in basis points */
26800
+ feeBps: zod_exports.optional(zod_exports.number()),
26801
+ /** Payment facilitator URL */
26802
+ paymentFacilitator: zod_exports.optional(zod_exports.string()),
26803
+ /** Unique reference ID (for replay protection) */
26804
+ reference: zod_exports.string()
26805
+ })
26806
+ })
26807
+ }
26808
+ });
26809
+
26810
+ // src/mpp/bridge-server.ts
26811
+ var BRIDGE_INFO_TTL_MS = 5 * 60 * 1e3;
26339
26812
  // Annotate the CommonJS export names for ESM import in node:
26340
26813
  0 && (module.exports = {
26341
26814
  BASE_MAINNET_NETWORK,
@@ -26343,6 +26816,7 @@ async function waitForReceipt(rpcUrl, txHash, timeoutMs = 3e4) {
26343
26816
  CHAIN_IDS,
26344
26817
  EXPLORER_TX_URL,
26345
26818
  NETWORK_CAIP2,
26819
+ NETWORK_CONFIGS,
26346
26820
  NETWORK_LABELS,
26347
26821
  NETWORK_TOKENS,
26348
26822
  NETWORK_V1_TO_V2,
@@ -26354,9 +26828,12 @@ async function waitForReceipt(rpcUrl, txHash, timeoutMs = 3e4) {
26354
26828
  USDC_ADDRESSES,
26355
26829
  USDC_BASE,
26356
26830
  USDC_SOLANA,
26831
+ cancelPaymentCode,
26357
26832
  convertPayloadToVersion,
26358
26833
  convertV1ToV2,
26359
26834
  convertV2ToV1,
26835
+ createPayRequest,
26836
+ createPrivateKeySigner,
26360
26837
  createX402Client,
26361
26838
  detectPayloadVersion,
26362
26839
  evmChargeClient,
@@ -26365,6 +26842,8 @@ async function waitForReceipt(rpcUrl, txHash, timeoutMs = 3e4) {
26365
26842
  formatUsd,
26366
26843
  fromAtomicUnits,
26367
26844
  generatePaymentCode,
26845
+ generatePaymentCodesBatch,
26846
+ getPayRequest,
26368
26847
  getPaymentCode,
26369
26848
  isEvm,
26370
26849
  isEvmNetwork,
@@ -26374,6 +26853,8 @@ async function waitForReceipt(rpcUrl, txHash, timeoutMs = 3e4) {
26374
26853
  networkV2ToV1,
26375
26854
  normalizeNetwork,
26376
26855
  normalizePaymentHeader,
26856
+ payPayRequest,
26857
+ payPayRequestWithCode,
26377
26858
  redeemPaymentCode,
26378
26859
  resolveToken,
26379
26860
  stripePayTo,