@relai-fi/x402 0.6.8 → 0.6.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4454,19 +4454,26 @@ function submitRelayFeedback(config2) {
4454
4454
 
4455
4455
  // src/solana-payment-codes.ts
4456
4456
  var DEFAULT_FACILITATOR = "https://relai.fi/facilitator";
4457
- function generateCode() {
4457
+ function generateCode(network, claimLink = false) {
4458
4458
  const chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
4459
- const bytes = new Uint8Array(8);
4459
+ const randomLength = claimLink ? 6 : 7;
4460
+ const bytes = new Uint8Array(randomLength);
4460
4461
  if (typeof globalThis !== "undefined" && globalThis.crypto?.getRandomValues) {
4461
4462
  globalThis.crypto.getRandomValues(bytes);
4462
4463
  } else {
4463
4464
  const { randomBytes } = __require("crypto");
4464
- randomBytes(8).copy(Buffer.from(bytes.buffer));
4465
+ randomBytes(randomLength).copy(Buffer.from(bytes.buffer));
4465
4466
  }
4466
- let code = "";
4467
- for (let i = 0; i < 8; i++) code += chars[bytes[i] % chars.length];
4467
+ let code = network === "solana-devnet" ? "D" : "S";
4468
+ if (claimLink) code += "Z";
4469
+ for (let i = 0; i < bytes.length; i++) code += chars[bytes[i] % chars.length];
4468
4470
  return code;
4469
4471
  }
4472
+ function buildClaimUrl(facilitatorUrl, claimToken) {
4473
+ if (!claimToken) return null;
4474
+ const origin = new URL(facilitatorUrl).origin;
4475
+ return new URL(`/claim/${claimToken}`, origin).toString();
4476
+ }
4470
4477
  async function anchorDisc(name) {
4471
4478
  const preimage = new TextEncoder().encode(`global:${name}`);
4472
4479
  if (typeof globalThis !== "undefined" && globalThis.crypto?.subtle) {
@@ -4476,14 +4483,21 @@ async function anchorDisc(name) {
4476
4483
  const { createHash } = __require("crypto");
4477
4484
  return new Uint8Array(createHash("sha256").update(preimage).digest()).slice(0, 8);
4478
4485
  }
4486
+ function writeBigInt64LE(target, value, offset) {
4487
+ let remaining = BigInt.asUintN(64, value);
4488
+ for (let index = 0; index < 8; index += 1) {
4489
+ target[offset + index] = Number(remaining & 0xffn);
4490
+ remaining >>= 8n;
4491
+ }
4492
+ }
4479
4493
  async function buildInstructionData(name, codeBytes, extra) {
4480
4494
  const disc = await anchorDisc(name);
4481
4495
  if (name === "create_vault" && extra) {
4482
4496
  const buf2 = Buffer.alloc(32);
4483
4497
  Buffer.from(disc).copy(buf2, 0);
4484
4498
  Buffer.from(codeBytes).copy(buf2, 8);
4485
- buf2.writeBigUInt64LE(extra.amount, 16);
4486
- buf2.writeBigInt64LE(extra.validUntil, 24);
4499
+ writeBigInt64LE(buf2, extra.amount, 16);
4500
+ writeBigInt64LE(buf2, extra.validUntil, 24);
4487
4501
  return buf2;
4488
4502
  }
4489
4503
  const buf = Buffer.alloc(16);
@@ -4493,7 +4507,7 @@ async function buildInstructionData(name, codeBytes, extra) {
4493
4507
  }
4494
4508
  async function generateSolanaPaymentCode(config2, wallet, params) {
4495
4509
  const facilitatorUrl = config2.facilitatorUrl ?? DEFAULT_FACILITATOR;
4496
- const { solanaRpcUrl, ttlSeconds = 86400 } = params;
4510
+ const { solanaRpcUrl, ttlSeconds = 86400, claimLink = false } = params;
4497
4511
  const amount2 = BigInt(params.amount);
4498
4512
  if (amount2 <= 0n) throw new Error("amount must be positive");
4499
4513
  if (!wallet.publicKey) throw new Error("Solana wallet not connected");
@@ -4504,7 +4518,7 @@ async function generateSolanaPaymentCode(config2, wallet, params) {
4504
4518
  const relayerAddr = relayerInfo.address;
4505
4519
  const programId = relayerInfo.programId;
4506
4520
  const usdcMint = relayerInfo.networks?.[network]?.usdc ?? (network === "solana-devnet" ? "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU" : "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
4507
- const code = generateCode();
4521
+ const code = generateCode(network, claimLink);
4508
4522
  const codeBytes = new TextEncoder().encode(code);
4509
4523
  const {
4510
4524
  Connection: Connection2,
@@ -4536,6 +4550,8 @@ async function generateSolanaPaymentCode(config2, wallet, params) {
4536
4550
  const createVaultIx = new TransactionInstruction({
4537
4551
  programId: programPK,
4538
4552
  keys: [
4553
+ { pubkey: relayerPK, isSigner: true, isWritable: true },
4554
+ // caller / fee payer
4539
4555
  { pubkey: buyerPK, isSigner: true, isWritable: true },
4540
4556
  // buyer
4541
4557
  { pubkey: vaultPda, isSigner: false, isWritable: true },
@@ -4567,7 +4583,9 @@ async function generateSolanaPaymentCode(config2, wallet, params) {
4567
4583
  code,
4568
4584
  amount: amount2.toString(),
4569
4585
  network,
4570
- ttlSeconds
4586
+ ttlSeconds,
4587
+ claimLink,
4588
+ ...params.description ? { description: params.description } : {}
4571
4589
  };
4572
4590
  const res = await fetch(`${facilitatorUrl}/solana-payment-codes`, {
4573
4591
  method: "POST",
@@ -4578,7 +4596,129 @@ async function generateSolanaPaymentCode(config2, wallet, params) {
4578
4596
  const err = await res.json().catch(() => ({}));
4579
4597
  throw new Error(err.error ?? `generateSolanaPaymentCode failed: ${res.status}`);
4580
4598
  }
4581
- return res.json();
4599
+ const payload = await res.json();
4600
+ if (payload.claimLink === true) {
4601
+ const claimToken = typeof payload.claimToken === "string" ? payload.claimToken : null;
4602
+ const sanitized = { ...payload };
4603
+ delete sanitized.claimToken;
4604
+ delete sanitized.id;
4605
+ delete sanitized.code;
4606
+ return {
4607
+ ...sanitized,
4608
+ claimLink: true,
4609
+ claimUrl: buildClaimUrl(facilitatorUrl, claimToken)
4610
+ };
4611
+ }
4612
+ return payload;
4613
+ }
4614
+ async function generateSolanaPaymentCodesBatch(config2, wallet, params) {
4615
+ const facilitatorUrl = config2.facilitatorUrl ?? DEFAULT_FACILITATOR;
4616
+ const items = Array.isArray(params.items) ? params.items : [];
4617
+ if (items.length === 0) throw new Error("items must not be empty");
4618
+ if (items.length > 10) throw new Error("Maximum 10 Solana batch items are supported per transaction");
4619
+ if (!wallet.publicKey) throw new Error("Solana wallet not connected");
4620
+ const infoRes = await fetch(`${facilitatorUrl}/solana-payment-codes/relayer-info`);
4621
+ if (!infoRes.ok) throw new Error("Failed to fetch Solana relayer info");
4622
+ const relayerInfo = await infoRes.json();
4623
+ const network = params.network ?? relayerInfo.defaultNetwork ?? "solana";
4624
+ const relayerAddr = relayerInfo.address;
4625
+ const programId = relayerInfo.programId;
4626
+ const usdcMint = relayerInfo.networks?.[network]?.usdc ?? (network === "solana-devnet" ? "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU" : "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
4627
+ const {
4628
+ Connection: Connection2,
4629
+ PublicKey: PublicKey2,
4630
+ TransactionMessage: TransactionMessage2,
4631
+ VersionedTransaction: VersionedTransaction2,
4632
+ TransactionInstruction
4633
+ } = await import("@solana/web3.js");
4634
+ const {
4635
+ getAssociatedTokenAddressSync,
4636
+ TOKEN_PROGRAM_ID: TOKEN_PROGRAM_ID2,
4637
+ ASSOCIATED_TOKEN_PROGRAM_ID
4638
+ } = await import("@solana/spl-token");
4639
+ const rpcUrl = params.solanaRpcUrl ?? (network === "solana-devnet" ? "https://api.devnet.solana.com" : "https://api.mainnet-beta.solana.com");
4640
+ const connection = new Connection2(rpcUrl, "confirmed");
4641
+ const programPK = new PublicKey2(programId);
4642
+ const mintPK = new PublicKey2(usdcMint);
4643
+ const buyerPK = new PublicKey2(wallet.publicKey.toString());
4644
+ const relayerPK = new PublicKey2(relayerAddr);
4645
+ const buyerAta = getAssociatedTokenAddressSync(mintPK, buyerPK, false, TOKEN_PROGRAM_ID2);
4646
+ const systemProgram = new PublicKey2("11111111111111111111111111111111");
4647
+ const usedCodes = /* @__PURE__ */ new Set();
4648
+ const preparedItems = [];
4649
+ const instructions = [];
4650
+ let totalAmount = 0n;
4651
+ for (const item of items) {
4652
+ const amount2 = BigInt(item.amount);
4653
+ if (amount2 <= 0n) throw new Error("Each batch item amount must be positive");
4654
+ const ttlSeconds = Math.min(Math.max(Math.round(Number(item.ttlSeconds ?? 86400)), 60), 604800);
4655
+ const validUntil = BigInt(Math.floor(Date.now() / 1e3) + ttlSeconds);
4656
+ let code = generateCode(network, false);
4657
+ while (usedCodes.has(code)) code = generateCode(network, false);
4658
+ usedCodes.add(code);
4659
+ const codeBytes = new TextEncoder().encode(code);
4660
+ const [vaultPda] = PublicKey2.findProgramAddressSync(
4661
+ [Buffer.from("vault"), Buffer.from(codeBytes)],
4662
+ programPK
4663
+ );
4664
+ const vaultAta = getAssociatedTokenAddressSync(mintPK, vaultPda, true, TOKEN_PROGRAM_ID2);
4665
+ const ixData = await buildInstructionData("create_vault", codeBytes, { amount: amount2, validUntil });
4666
+ instructions.push(new TransactionInstruction({
4667
+ programId: programPK,
4668
+ keys: [
4669
+ { pubkey: relayerPK, isSigner: true, isWritable: true },
4670
+ { pubkey: buyerPK, isSigner: true, isWritable: true },
4671
+ { pubkey: vaultPda, isSigner: false, isWritable: true },
4672
+ { pubkey: vaultAta, isSigner: false, isWritable: true },
4673
+ { pubkey: buyerAta, isSigner: false, isWritable: true },
4674
+ { pubkey: mintPK, isSigner: false, isWritable: false },
4675
+ { pubkey: TOKEN_PROGRAM_ID2, isSigner: false, isWritable: false },
4676
+ { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
4677
+ { pubkey: systemProgram, isSigner: false, isWritable: false }
4678
+ ],
4679
+ data: ixData
4680
+ }));
4681
+ preparedItems.push({
4682
+ code,
4683
+ amount: amount2,
4684
+ ttlSeconds,
4685
+ description: item.description,
4686
+ validUntil
4687
+ });
4688
+ totalAmount += amount2;
4689
+ }
4690
+ const { blockhash } = await connection.getLatestBlockhash("confirmed");
4691
+ const message = new TransactionMessage2({
4692
+ payerKey: relayerPK,
4693
+ recentBlockhash: blockhash,
4694
+ instructions
4695
+ }).compileToV0Message();
4696
+ const tx = new VersionedTransaction2(message);
4697
+ const signed = await wallet.signTransaction(tx);
4698
+ const serialized = Buffer.from(signed.serialize()).toString("base64");
4699
+ const res = await fetch(`${facilitatorUrl}/solana-payment-codes/batch`, {
4700
+ method: "POST",
4701
+ headers: { "Content-Type": "application/json" },
4702
+ body: JSON.stringify({
4703
+ transaction: serialized,
4704
+ network,
4705
+ items: preparedItems.map((item) => ({
4706
+ code: item.code,
4707
+ amount: item.amount.toString(),
4708
+ ttlSeconds: item.ttlSeconds,
4709
+ ...item.description ? { description: item.description } : {}
4710
+ }))
4711
+ })
4712
+ });
4713
+ if (!res.ok) {
4714
+ const err = await res.json().catch(() => ({}));
4715
+ throw new Error(err.error ?? `generateSolanaPaymentCodesBatch failed: ${res.status}`);
4716
+ }
4717
+ const payload = await res.json();
4718
+ return {
4719
+ ...payload,
4720
+ totalAmount: typeof payload.totalAmount === "string" ? payload.totalAmount : totalAmount.toString()
4721
+ };
4582
4722
  }
4583
4723
  async function getSolanaPaymentCode(config2, code) {
4584
4724
  const facilitatorUrl = config2.facilitatorUrl ?? DEFAULT_FACILITATOR;
@@ -4648,6 +4788,8 @@ async function cancelSolanaPaymentCode(config2, code, wallet, options = {}) {
4648
4788
  const cancelIx = new TransactionInstruction({
4649
4789
  programId: programPK,
4650
4790
  keys: [
4791
+ { pubkey: relayerPK, isSigner: true, isWritable: true },
4792
+ // caller / fee payer
4651
4793
  { pubkey: buyerPK, isSigner: true, isWritable: true },
4652
4794
  // buyer (must sign)
4653
4795
  { pubkey: vaultPda, isSigner: false, isWritable: true },
@@ -4737,6 +4879,7 @@ function createPrivateKeySigner(privateKey) {
4737
4879
  };
4738
4880
  }
4739
4881
  var DEFAULT_FACILITATOR2 = "https://relai.fi/facilitator";
4882
+ var AUTHORIZATION_WINDOW_SECONDS = 3600;
4740
4883
  function randomBytes32() {
4741
4884
  const bytes = new Uint8Array(32);
4742
4885
  if (typeof globalThis.crypto !== "undefined") {
@@ -4754,6 +4897,14 @@ async function fetchToAddress(facilitatorUrl, network) {
4754
4897
  if (!data.toAddress) throw new Error("Facilitator returned no toAddress");
4755
4898
  return data.toAddress;
4756
4899
  }
4900
+ async function fetchEscrowAddress(facilitatorUrl, network) {
4901
+ const res = await fetch(`${facilitatorUrl}/payment-codes/relayer-address`);
4902
+ if (!res.ok) throw new Error("Failed to fetch escrow address from facilitator");
4903
+ const data = await res.json();
4904
+ const escrowAddress = data.escrowAddresses?.[network];
4905
+ if (!escrowAddress) throw new Error(`Facilitator returned no escrow address for ${network}`);
4906
+ return escrowAddress;
4907
+ }
4757
4908
  async function signEip3009(signer, net, from4, toAddress, value, validAfter, validBefore, nonce, usdcOverride) {
4758
4909
  const domain2 = {
4759
4910
  name: net.domainName,
@@ -4828,8 +4979,7 @@ async function generatePaymentCodesBatch(config2, params) {
4828
4979
  codes,
4829
4980
  payee,
4830
4981
  usdcContract,
4831
- network = "base-sepolia",
4832
- authToken
4982
+ network = "base-sepolia"
4833
4983
  } = params;
4834
4984
  const facilitatorUrl = config2.facilitatorUrl ?? DEFAULT_FACILITATOR2;
4835
4985
  const net = NETWORK_CONFIGS[network];
@@ -4839,44 +4989,76 @@ async function generatePaymentCodesBatch(config2, params) {
4839
4989
  const usdc = usdcContract ?? net.usdc;
4840
4990
  const now = Math.floor(Date.now() / 1e3);
4841
4991
  const toAddress = await fetchToAddress(facilitatorUrl, network);
4842
- const signedCodes = await Promise.all(
4843
- codes.map(async (item) => {
4992
+ const escrowAddress = await fetchEscrowAddress(facilitatorUrl, network);
4993
+ const results = [];
4994
+ const failed = [];
4995
+ for (let index = 0; index < codes.length; index += 1) {
4996
+ const item = codes[index];
4997
+ try {
4844
4998
  const validBefore = now + (item.ttl ?? 86400);
4999
+ const authorizationValidBefore = Math.min(validBefore, now + AUTHORIZATION_WINDOW_SECONDS);
4845
5000
  const nonce = randomBytes32();
4846
5001
  const value = BigInt(item.value).toString();
5002
+ const authorization = {
5003
+ from: from4,
5004
+ to: escrowAddress,
5005
+ value,
5006
+ validAfter: 0,
5007
+ validBefore: authorizationValidBefore,
5008
+ nonce
5009
+ };
4847
5010
  const signature2 = await signEip3009(
4848
5011
  signer,
4849
5012
  net,
4850
5013
  from4,
4851
- toAddress,
5014
+ escrowAddress,
4852
5015
  value,
4853
- 0,
4854
- validBefore,
4855
- nonce,
5016
+ authorization.validAfter,
5017
+ authorization.validBefore,
5018
+ authorization.nonce,
4856
5019
  usdc
4857
5020
  );
4858
- return { value, validAfter: 0, validBefore, nonce, signature: signature2 };
4859
- })
4860
- );
4861
- const res = await fetch(`${facilitatorUrl}/payment-codes/batch`, {
4862
- method: "POST",
4863
- headers: {
4864
- "Content-Type": "application/json",
4865
- "Authorization": `Bearer ${authToken}`
4866
- },
4867
- body: JSON.stringify({
4868
- from: from4,
4869
- settlementNetwork: net.settlementNetwork,
4870
- usdcContract: usdc,
4871
- ...payee ? { payee } : {},
4872
- codes: signedCodes
4873
- })
4874
- });
4875
- if (!res.ok) {
4876
- const err = await res.json().catch(() => ({}));
4877
- throw new Error(`Batch registration failed: ${err.error ?? res.status}`);
5021
+ const res = await fetch(`${facilitatorUrl}/payment-codes`, {
5022
+ method: "POST",
5023
+ headers: { "Content-Type": "application/json" },
5024
+ body: JSON.stringify({
5025
+ from: from4,
5026
+ value,
5027
+ validBefore,
5028
+ usdcContract: usdc,
5029
+ settlementNetwork: net.settlementNetwork,
5030
+ escrowMode: true,
5031
+ ...payee ? { payee } : {},
5032
+ signature: signature2,
5033
+ authorization
5034
+ })
5035
+ });
5036
+ if (!res.ok) {
5037
+ const err = await res.json().catch(() => ({}));
5038
+ failed.push({ index, error: String(err.error ?? err.detail ?? res.status) });
5039
+ continue;
5040
+ }
5041
+ const payload = await res.json();
5042
+ results.push({
5043
+ code: String(payload.code ?? ""),
5044
+ validBefore: Number(payload.validBefore ?? validBefore),
5045
+ expiresIn: Number(payload.expiresIn ?? validBefore - Math.floor(Date.now() / 1e3)),
5046
+ locked: Boolean(payload.locked ?? payee)
5047
+ });
5048
+ } catch (error48) {
5049
+ failed.push({
5050
+ index,
5051
+ error: error48 instanceof Error ? error48.message : String(error48)
5052
+ });
5053
+ }
4878
5054
  }
4879
- return res.json();
5055
+ return {
5056
+ registered: results.length,
5057
+ codes: results,
5058
+ failed,
5059
+ relayerAddress: toAddress,
5060
+ settlementNetwork: net.settlementNetwork
5061
+ };
4880
5062
  }
4881
5063
  async function redeemPaymentCode(config2, code, payee) {
4882
5064
  const facilitatorUrl = config2.facilitatorUrl ?? DEFAULT_FACILITATOR2;
@@ -5145,6 +5327,528 @@ async function payPayRequestWithSolana(config2, requestCode, wallet, options = {
5145
5327
  return res.json();
5146
5328
  }
5147
5329
 
5330
+ // src/current-payment-codes.ts
5331
+ import { ethers as ethers3 } from "ethers";
5332
+ import bs58 from "bs58";
5333
+ var DEFAULT_FACILITATOR4 = "https://relai.fi/facilitator";
5334
+ var TRANSFER_WITH_AUTHORIZATION_DOMAIN_VERSION = "2";
5335
+ var AUTHORIZATION_WINDOW_SECONDS2 = 3600;
5336
+ var EVM_ESCROW_ABI = ["function cancel(bytes8 code) external"];
5337
+ var EIP3009_TYPES3 = {
5338
+ TransferWithAuthorization: [
5339
+ { name: "from", type: "address" },
5340
+ { name: "to", type: "address" },
5341
+ { name: "value", type: "uint256" },
5342
+ { name: "validAfter", type: "uint256" },
5343
+ { name: "validBefore", type: "uint256" },
5344
+ { name: "nonce", type: "bytes32" }
5345
+ ]
5346
+ };
5347
+ function isEvmAddress(value) {
5348
+ return /^0x[0-9a-fA-F]{40}$/i.test(value);
5349
+ }
5350
+ function codeToBytes8(code) {
5351
+ const normalized = code.trim().toUpperCase();
5352
+ const bytes = ethers3.toUtf8Bytes(normalized);
5353
+ if (bytes.length !== 8) throw new Error("Payment code must be exactly 8 characters long");
5354
+ return ethers3.hexlify(bytes);
5355
+ }
5356
+ function randomBytes323() {
5357
+ const bytes = new Uint8Array(32);
5358
+ if (typeof globalThis.crypto !== "undefined" && globalThis.crypto?.getRandomValues) {
5359
+ globalThis.crypto.getRandomValues(bytes);
5360
+ } else {
5361
+ const { randomBytes } = __require("crypto");
5362
+ randomBytes(32).copy(Buffer.from(bytes.buffer));
5363
+ }
5364
+ return `0x${Array.from(bytes).map((byte) => byte.toString(16).padStart(2, "0")).join("")}`;
5365
+ }
5366
+ function extractClaimToken(claimUrlOrToken) {
5367
+ const normalized = claimUrlOrToken.trim();
5368
+ if (!normalized) throw new Error("Claim URL or claim token is required");
5369
+ const directValue = normalized.split("?")[0]?.split("#")[0]?.trim() ?? "";
5370
+ if (!directValue.includes("/")) return directValue;
5371
+ try {
5372
+ const url2 = new URL(normalized);
5373
+ const segments = url2.pathname.split("/").filter(Boolean);
5374
+ return segments[segments.length - 1] ?? "";
5375
+ } catch {
5376
+ const segments = directValue.split("/").filter(Boolean);
5377
+ return segments[segments.length - 1] ?? "";
5378
+ }
5379
+ }
5380
+ function buildClaimUrl2(facilitatorUrl, claimToken) {
5381
+ if (!claimToken) return null;
5382
+ const origin = new URL(facilitatorUrl).origin;
5383
+ return new URL(`/claim/${claimToken}`, origin).toString();
5384
+ }
5385
+ function buildCancelAuthorizationMessage(code, owner, issuedAt) {
5386
+ return [
5387
+ "RelAI Codes",
5388
+ "Authorize payment code cancellation",
5389
+ `Code: ${code.trim().toUpperCase()}`,
5390
+ `Owner: ${owner.toLowerCase()}`,
5391
+ `Issued At: ${issuedAt}`
5392
+ ].join("\n");
5393
+ }
5394
+ function buildClaimLinkCancelAuthorizationMessage(claimToken, owner, issuedAt) {
5395
+ return [
5396
+ "RelAI Codes",
5397
+ "Authorize claim link cancellation",
5398
+ `Claim Token: ${claimToken}`,
5399
+ `Owner: ${owner.toLowerCase()}`,
5400
+ `Issued At: ${issuedAt}`
5401
+ ].join("\n");
5402
+ }
5403
+ function buildEvmClaimLinkAuthorizationMessage(params) {
5404
+ return [
5405
+ "RelAI EVM Claim Link",
5406
+ `Claim Token: ${params.claimToken}`,
5407
+ `Claimer: ${params.claimer.toLowerCase()}`,
5408
+ `Mode: ${params.mode}`,
5409
+ `Target Address: ${params.targetAddress ?? "-"}`,
5410
+ `Target Network: ${params.targetNetwork ?? "-"}`,
5411
+ `Issued At: ${params.issuedAt}`
5412
+ ].join("\n");
5413
+ }
5414
+ function buildSolanaClaimLinkAuthorizationMessage(params) {
5415
+ return [
5416
+ "RelAI Solana Claim Link",
5417
+ `Claim Token: ${params.claimToken}`,
5418
+ `Claimer: ${params.claimer}`,
5419
+ `Mode: ${params.mode}`,
5420
+ `Target Address: ${params.targetAddress ?? "-"}`,
5421
+ `Target Network: ${params.targetNetwork ?? "-"}`,
5422
+ `Issued At: ${params.issuedAt}`
5423
+ ].join("\n");
5424
+ }
5425
+ async function readJson(response) {
5426
+ return response.json().catch(() => ({}));
5427
+ }
5428
+ async function fetchWithPayload(url2, init) {
5429
+ const response = await fetch(url2, init);
5430
+ const payload = await readJson(response);
5431
+ return { response, payload };
5432
+ }
5433
+ function buildRequestError(response, payload) {
5434
+ return new Error(String(payload.error || payload.detail || payload.message || `Request failed (${response.status})`));
5435
+ }
5436
+ function isNotFoundResponse(response, payload) {
5437
+ return response.status === 404 || payload.errorCode === "not_found";
5438
+ }
5439
+ async function fetchStoredCodeWithFallback(facilitatorUrl, normalizedCode, options = {}) {
5440
+ const suffix = options.suffix ? `/${options.suffix.replace(/^\/+/, "")}` : "";
5441
+ const attempts = [
5442
+ { kind: "evm", url: `${facilitatorUrl}/payment-codes/${normalizedCode}${suffix}` },
5443
+ { kind: "solana", url: `${facilitatorUrl}/solana-payment-codes/${normalizedCode}${suffix}` }
5444
+ ];
5445
+ let lastError = null;
5446
+ for (const attempt of attempts) {
5447
+ const { response, payload } = await fetchWithPayload(attempt.url, options.init);
5448
+ if (response.ok) {
5449
+ return { kind: attempt.kind, payload };
5450
+ }
5451
+ if (!isNotFoundResponse(response, payload)) {
5452
+ throw buildRequestError(response, payload);
5453
+ }
5454
+ lastError = buildRequestError(response, payload);
5455
+ }
5456
+ throw lastError ?? new Error("Payment code not found");
5457
+ }
5458
+ async function fetchOrThrow(url2, init) {
5459
+ const { response, payload } = await fetchWithPayload(url2, init);
5460
+ if (!response.ok) {
5461
+ throw buildRequestError(response, payload);
5462
+ }
5463
+ return payload;
5464
+ }
5465
+ function sanitizeClaimLinkResponse(payload, facilitatorUrl, fallbackClaimToken) {
5466
+ const claimToken = typeof payload.claimToken === "string" ? payload.claimToken : fallbackClaimToken ?? null;
5467
+ const sanitized = { ...payload };
5468
+ delete sanitized.claimToken;
5469
+ delete sanitized.id;
5470
+ return {
5471
+ ...sanitized,
5472
+ claimUrl: buildClaimUrl2(facilitatorUrl, claimToken)
5473
+ };
5474
+ }
5475
+ async function createPaymentCode(config2, params) {
5476
+ const facilitatorUrl = config2.facilitatorUrl ?? DEFAULT_FACILITATOR4;
5477
+ const ttlSeconds = Math.max(60, Math.round(Number(params.ttlSeconds ?? 86400)));
5478
+ if ("wallet" in params) {
5479
+ const amount3 = BigInt(params.amount);
5480
+ if (amount3 <= 0n) throw new Error("amount must be positive");
5481
+ return generateSolanaPaymentCode(config2, params.wallet, {
5482
+ amount: amount3,
5483
+ network: params.network,
5484
+ claimLink: params.claimLink === true,
5485
+ description: params.description,
5486
+ ttlSeconds
5487
+ });
5488
+ }
5489
+ const network = params.network ?? "base-sepolia";
5490
+ const net = NETWORK_CONFIGS[network];
5491
+ if (!net) throw new Error(`Unsupported network: ${network}`);
5492
+ const amount2 = BigInt(params.amount);
5493
+ if (amount2 <= 0n) throw new Error("amount must be positive");
5494
+ const relayerConfig = await fetchOrThrow(`${facilitatorUrl}/payment-codes/relayer-address`);
5495
+ const escrowAddresses = relayerConfig.escrowAddresses ?? {};
5496
+ const escrowAddress = escrowAddresses[network];
5497
+ if (!escrowAddress) throw new Error(`EVM escrow is not configured for ${network}`);
5498
+ const from4 = await params.signer.getAddress();
5499
+ const now = Math.floor(Date.now() / 1e3);
5500
+ const validBefore = now + ttlSeconds;
5501
+ const authorizationValidBefore = String(Math.min(validBefore, now + AUTHORIZATION_WINDOW_SECONDS2));
5502
+ const authorizationNonce = randomBytes323();
5503
+ const usdcContract = params.usdcContract ?? net.usdc;
5504
+ const domain2 = {
5505
+ name: net.domainName,
5506
+ version: TRANSFER_WITH_AUTHORIZATION_DOMAIN_VERSION,
5507
+ chainId: net.chainId,
5508
+ verifyingContract: usdcContract
5509
+ };
5510
+ const authorization = {
5511
+ from: from4,
5512
+ to: escrowAddress,
5513
+ value: amount2.toString(),
5514
+ validAfter: "0",
5515
+ validBefore: authorizationValidBefore,
5516
+ nonce: authorizationNonce
5517
+ };
5518
+ const signature2 = await params.signer.signTypedData(domain2, EIP3009_TYPES3, authorization);
5519
+ const payload = await fetchOrThrow(`${facilitatorUrl}/payment-codes`, {
5520
+ method: "POST",
5521
+ headers: { "Content-Type": "application/json" },
5522
+ body: JSON.stringify({
5523
+ from: from4,
5524
+ value: amount2.toString(),
5525
+ validBefore,
5526
+ usdcContract,
5527
+ settlementNetwork: network,
5528
+ escrowMode: true,
5529
+ claimLink: params.claimLink === true,
5530
+ ...params.description ? { description: params.description } : {},
5531
+ ...params.payee ? { payee: params.payee } : {},
5532
+ signature: signature2,
5533
+ authorization
5534
+ })
5535
+ });
5536
+ return params.claimLink === true ? sanitizeClaimLinkResponse(payload, facilitatorUrl) : payload;
5537
+ }
5538
+ async function createPaymentCodesBatch(config2, params) {
5539
+ const facilitatorUrl = config2.facilitatorUrl ?? DEFAULT_FACILITATOR4;
5540
+ if (!Array.isArray(params.codes) || params.codes.length === 0) {
5541
+ throw new Error("codes must not be empty");
5542
+ }
5543
+ if ("wallet" in params) {
5544
+ const items = params.codes.map((item) => ({
5545
+ amount: item.amount,
5546
+ ttlSeconds: item.ttlSeconds,
5547
+ description: item.description
5548
+ }));
5549
+ return generateSolanaPaymentCodesBatch(config2, params.wallet, {
5550
+ network: params.network,
5551
+ items
5552
+ });
5553
+ }
5554
+ const network = params.network ?? "base-sepolia";
5555
+ const net = NETWORK_CONFIGS[network];
5556
+ if (!net) throw new Error(`Unsupported network: ${network}`);
5557
+ const relayerConfig = await fetchOrThrow(`${facilitatorUrl}/payment-codes/relayer-address`);
5558
+ const escrowAddresses = relayerConfig.escrowAddresses ?? {};
5559
+ const escrowAddress = escrowAddresses[network];
5560
+ if (!escrowAddress) throw new Error(`EVM escrow is not configured for ${network}`);
5561
+ const from4 = await params.signer.getAddress();
5562
+ const now = Math.floor(Date.now() / 1e3);
5563
+ const usdcContract = params.usdcContract ?? net.usdc;
5564
+ const normalizedCodes = params.codes.map((item) => {
5565
+ const amount2 = BigInt(item.amount);
5566
+ if (amount2 <= 0n) throw new Error("Each batch code amount must be positive");
5567
+ const ttlSeconds = Math.max(60, Math.round(Number(item.ttlSeconds ?? 86400)));
5568
+ return {
5569
+ value: amount2,
5570
+ validBefore: now + ttlSeconds,
5571
+ description: item.description?.trim() || void 0
5572
+ };
5573
+ });
5574
+ const totalAmount = normalizedCodes.reduce((sum, item) => sum + item.value, 0n);
5575
+ const authorizationValidBefore = String(now + AUTHORIZATION_WINDOW_SECONDS2);
5576
+ const authorizationNonce = randomBytes323();
5577
+ const domain2 = {
5578
+ name: net.domainName,
5579
+ version: TRANSFER_WITH_AUTHORIZATION_DOMAIN_VERSION,
5580
+ chainId: net.chainId,
5581
+ verifyingContract: usdcContract
5582
+ };
5583
+ const authorization = {
5584
+ from: from4,
5585
+ to: escrowAddress,
5586
+ value: totalAmount.toString(),
5587
+ validAfter: "0",
5588
+ validBefore: authorizationValidBefore,
5589
+ nonce: authorizationNonce
5590
+ };
5591
+ const signature2 = await params.signer.signTypedData(domain2, EIP3009_TYPES3, authorization);
5592
+ return fetchOrThrow(`${facilitatorUrl}/payment-codes/batch-funded`, {
5593
+ method: "POST",
5594
+ headers: { "Content-Type": "application/json" },
5595
+ body: JSON.stringify({
5596
+ from: from4,
5597
+ usdcContract,
5598
+ settlementNetwork: network,
5599
+ ...params.payee ? { payee: params.payee } : {},
5600
+ signature: signature2,
5601
+ authorization,
5602
+ codes: normalizedCodes.map((item) => ({
5603
+ value: item.value.toString(),
5604
+ validBefore: item.validBefore,
5605
+ ...item.description ? { description: item.description } : {}
5606
+ }))
5607
+ })
5608
+ });
5609
+ }
5610
+ async function listOwnerPaymentCodes(config2, params) {
5611
+ const facilitatorUrl = config2.facilitatorUrl ?? DEFAULT_FACILITATOR4;
5612
+ if (params.walletType === "solana") {
5613
+ if (!params.wallet.publicKey) throw new Error("Solana wallet not connected");
5614
+ const walletAddress2 = params.wallet.publicKey.toString();
5615
+ const challenge2 = await fetchOrThrow(`${facilitatorUrl}/payment-codes/owner/challenge`, {
5616
+ method: "POST",
5617
+ headers: { "Content-Type": "application/json" },
5618
+ body: JSON.stringify({ walletAddress: walletAddress2, walletType: "solana" })
5619
+ });
5620
+ const message2 = typeof challenge2.message === "string" ? challenge2.message : "";
5621
+ if (!message2) throw new Error("Failed to load owner challenge message");
5622
+ const signatureBytes = await params.wallet.signMessage(new TextEncoder().encode(message2));
5623
+ const session2 = await fetchOrThrow(`${facilitatorUrl}/payment-codes/owner/session`, {
5624
+ method: "POST",
5625
+ headers: { "Content-Type": "application/json" },
5626
+ body: JSON.stringify({ walletAddress: walletAddress2, walletType: "solana", signature: bs58.encode(signatureBytes) })
5627
+ });
5628
+ const accessToken2 = typeof session2.accessToken === "string" ? session2.accessToken : "";
5629
+ if (!accessToken2) throw new Error("Failed to create owner session");
5630
+ return fetchOrThrow(`${facilitatorUrl}/payment-codes/owner/codes`, {
5631
+ headers: { Authorization: `Bearer ${accessToken2}` }
5632
+ });
5633
+ }
5634
+ const walletAddress = await params.wallet.getAddress();
5635
+ const challenge = await fetchOrThrow(`${facilitatorUrl}/payment-codes/owner/challenge`, {
5636
+ method: "POST",
5637
+ headers: { "Content-Type": "application/json" },
5638
+ body: JSON.stringify({ walletAddress, walletType: "evm" })
5639
+ });
5640
+ const message = typeof challenge.message === "string" ? challenge.message : "";
5641
+ if (!message) throw new Error("Failed to load owner challenge message");
5642
+ const session = await fetchOrThrow(`${facilitatorUrl}/payment-codes/owner/session`, {
5643
+ method: "POST",
5644
+ headers: { "Content-Type": "application/json" },
5645
+ body: JSON.stringify({ walletAddress, walletType: "evm", signature: await params.wallet.signMessage(message) })
5646
+ });
5647
+ const accessToken = typeof session.accessToken === "string" ? session.accessToken : "";
5648
+ if (!accessToken) throw new Error("Failed to create owner session");
5649
+ return fetchOrThrow(`${facilitatorUrl}/payment-codes/owner/codes`, {
5650
+ headers: { Authorization: `Bearer ${accessToken}` }
5651
+ });
5652
+ }
5653
+ async function getPaymentCode2(config2, code) {
5654
+ const facilitatorUrl = config2.facilitatorUrl ?? DEFAULT_FACILITATOR4;
5655
+ const normalizedCode = code.trim().toUpperCase();
5656
+ const { payload } = await fetchStoredCodeWithFallback(facilitatorUrl, normalizedCode);
5657
+ return payload;
5658
+ }
5659
+ var getPaymentCodeDetails = getPaymentCode2;
5660
+ async function redeemStoredPaymentCode(config2, code, params) {
5661
+ const facilitatorUrl = config2.facilitatorUrl ?? DEFAULT_FACILITATOR4;
5662
+ const normalizedCode = code.trim().toUpperCase();
5663
+ const { payload } = await fetchStoredCodeWithFallback(facilitatorUrl, normalizedCode, {
5664
+ suffix: "redeem",
5665
+ init: {
5666
+ method: "POST",
5667
+ headers: { "Content-Type": "application/json" },
5668
+ body: JSON.stringify({
5669
+ payee: params.payee,
5670
+ ...params.evmNetwork ? { evmNetwork: params.evmNetwork } : {},
5671
+ ...params.solanaNetwork ? { solanaNetwork: params.solanaNetwork } : {}
5672
+ })
5673
+ }
5674
+ });
5675
+ return payload;
5676
+ }
5677
+ async function cancelStoredPaymentCode(config2, code, params = {}) {
5678
+ const facilitatorUrl = config2.facilitatorUrl ?? DEFAULT_FACILITATOR4;
5679
+ const normalizedCode = code.trim().toUpperCase();
5680
+ const statusInfo = await fetchStoredCodeWithFallback(facilitatorUrl, normalizedCode);
5681
+ if (statusInfo.kind === "solana") {
5682
+ if (!params.solanaWallet) {
5683
+ throw new Error("A Solana wallet is required to cancel this payment code");
5684
+ }
5685
+ return cancelSolanaPaymentCode(config2, normalizedCode, params.solanaWallet, {
5686
+ network: params.network === "solana" || params.network === "solana-devnet" ? params.network : void 0
5687
+ });
5688
+ }
5689
+ if (!params.wallet) {
5690
+ throw new Error("An EVM wallet is required to cancel this payment code");
5691
+ }
5692
+ const status = statusInfo.payload;
5693
+ const owner = await params.wallet.getAddress();
5694
+ const network = params.network ?? String(status.settlementNetwork || "base-sepolia");
5695
+ if (status.claimLink === true && typeof status.claimToken === "string" && status.escrowMode === true) {
5696
+ const issuedAt2 = Date.now();
5697
+ return fetchOrThrow(`${facilitatorUrl}/payment-codes/claim-links/evm/${status.claimToken}/cancel`, {
5698
+ method: "POST",
5699
+ headers: { "Content-Type": "application/json" },
5700
+ body: JSON.stringify({
5701
+ owner,
5702
+ issuedAt: issuedAt2,
5703
+ signature: await params.wallet.signMessage(buildClaimLinkCancelAuthorizationMessage(status.claimToken, owner, issuedAt2))
5704
+ })
5705
+ });
5706
+ }
5707
+ if (status.escrowMode === true) {
5708
+ if (!params.wallet.sendTransaction) {
5709
+ throw new Error("This EVM wallet does not support sendTransaction, which is required for escrow cancellation");
5710
+ }
5711
+ const relayerConfig = await fetchOrThrow(`${facilitatorUrl}/payment-codes/relayer-address`);
5712
+ const escrowAddresses = relayerConfig.escrowAddresses ?? {};
5713
+ const escrowAddress = escrowAddresses[network];
5714
+ if (!escrowAddress) throw new Error(`EVM escrow is not configured for ${network}`);
5715
+ const cancelInterface = new ethers3.Interface(EVM_ESCROW_ABI);
5716
+ const tx = await params.wallet.sendTransaction({
5717
+ to: escrowAddress,
5718
+ data: cancelInterface.encodeFunctionData("cancel", [codeToBytes8(normalizedCode)])
5719
+ });
5720
+ await tx.wait();
5721
+ return {
5722
+ success: true,
5723
+ code: normalizedCode,
5724
+ cancelTxHash: tx.hash,
5725
+ network
5726
+ };
5727
+ }
5728
+ const issuedAt = Date.now();
5729
+ return fetchOrThrow(`${facilitatorUrl}/payment-codes/${normalizedCode}/cancel`, {
5730
+ method: "POST",
5731
+ headers: { "Content-Type": "application/json" },
5732
+ body: JSON.stringify({
5733
+ owner,
5734
+ issuedAt,
5735
+ signature: await params.wallet.signMessage(buildCancelAuthorizationMessage(normalizedCode, owner, issuedAt))
5736
+ })
5737
+ });
5738
+ }
5739
+ async function claimPaymentLink(config2, claimUrlOrToken, params) {
5740
+ const facilitatorUrl = config2.facilitatorUrl ?? DEFAULT_FACILITATOR4;
5741
+ const claimToken = extractClaimToken(claimUrlOrToken);
5742
+ if (!claimToken) throw new Error("Claim URL or claim token is required");
5743
+ const issuedAt = Date.now();
5744
+ const mode = params.mode ?? "claim-usdc";
5745
+ if ("solanaWallet" in params && params.solanaWallet) {
5746
+ if (!params.solanaWallet.publicKey) throw new Error("Solana wallet not connected");
5747
+ const claimer2 = params.solanaWallet.publicKey.toString();
5748
+ const requestedPayee2 = params.payee?.trim() || claimer2;
5749
+ const targetAddress2 = mode === "claim-usdc" ? isEvmAddress(requestedPayee2) ? requestedPayee2.toLowerCase() : requestedPayee2 : null;
5750
+ const targetNetwork2 = mode === "claim-usdc" ? targetAddress2 == null ? null : isEvmAddress(targetAddress2) ? params.evmNetwork ?? null : params.solanaNetwork ?? null : null;
5751
+ const message2 = buildSolanaClaimLinkAuthorizationMessage({
5752
+ claimToken,
5753
+ claimer: claimer2,
5754
+ issuedAt,
5755
+ mode,
5756
+ targetAddress: targetAddress2,
5757
+ targetNetwork: targetNetwork2
5758
+ });
5759
+ const signatureBytes = await params.solanaWallet.signMessage(new TextEncoder().encode(message2));
5760
+ const payload2 = await fetchOrThrow(`${facilitatorUrl}/solana-payment-codes/claim-links/${claimToken}/claim`, {
5761
+ method: "POST",
5762
+ headers: { "Content-Type": "application/json" },
5763
+ body: JSON.stringify({
5764
+ claimer: claimer2,
5765
+ issuedAt,
5766
+ signature: bs58.encode(signatureBytes),
5767
+ mode,
5768
+ ...targetAddress2 ? { targetAddress: targetAddress2 } : {},
5769
+ ...targetNetwork2 ? { targetNetwork: targetNetwork2 } : {}
5770
+ })
5771
+ });
5772
+ return sanitizeClaimLinkResponse(payload2, facilitatorUrl, claimToken);
5773
+ }
5774
+ if (!("wallet" in params) || !params.wallet) {
5775
+ throw new Error("An EVM wallet or Solana wallet is required to claim this payment link");
5776
+ }
5777
+ const claimer = (await params.wallet.getAddress()).toLowerCase();
5778
+ const requestedPayee = params.payee?.trim() || claimer;
5779
+ const targetAddress = mode === "claim-usdc" ? isEvmAddress(requestedPayee) ? requestedPayee.toLowerCase() : requestedPayee : null;
5780
+ const targetNetwork = mode === "claim-usdc" ? targetAddress == null ? null : isEvmAddress(targetAddress) ? params.evmNetwork ?? null : params.solanaNetwork ?? null : null;
5781
+ const message = buildEvmClaimLinkAuthorizationMessage({
5782
+ claimToken,
5783
+ claimer,
5784
+ issuedAt,
5785
+ mode,
5786
+ targetAddress,
5787
+ targetNetwork
5788
+ });
5789
+ const payload = await fetchOrThrow(`${facilitatorUrl}/payment-codes/claim-links/evm/${claimToken}/claim`, {
5790
+ method: "POST",
5791
+ headers: { "Content-Type": "application/json" },
5792
+ body: JSON.stringify({
5793
+ claimer,
5794
+ issuedAt,
5795
+ signature: await params.wallet.signMessage(message),
5796
+ mode,
5797
+ ...targetAddress ? { targetAddress, payee: targetAddress } : {},
5798
+ ...targetNetwork ? { targetNetwork } : {},
5799
+ ...targetAddress && isEvmAddress(targetAddress) && targetNetwork ? { evmNetwork: targetNetwork } : {},
5800
+ ...targetAddress && !isEvmAddress(targetAddress) && targetNetwork ? { solanaNetwork: targetNetwork } : {}
5801
+ })
5802
+ });
5803
+ return sanitizeClaimLinkResponse(payload, facilitatorUrl, claimToken);
5804
+ }
5805
+ async function payPayRequestWithStoredCode(config2, requestCode, paymentCode, options = {}) {
5806
+ const facilitatorUrl = config2.facilitatorUrl ?? DEFAULT_FACILITATOR4;
5807
+ const normalizedRequestCode = requestCode.trim().toUpperCase();
5808
+ const normalizedPaymentCode = paymentCode.trim().toUpperCase();
5809
+ const codeStatusInfo = await fetchStoredCodeWithFallback(facilitatorUrl, normalizedPaymentCode);
5810
+ if (codeStatusInfo.kind === "solana") {
5811
+ return fetchOrThrow(`${facilitatorUrl}/solana-payment-codes/${normalizedPaymentCode}/pay-request`, {
5812
+ method: "POST",
5813
+ headers: { "Content-Type": "application/json" },
5814
+ body: JSON.stringify({
5815
+ requestCode: normalizedRequestCode,
5816
+ ...options.changeAddress ? { changeAddress: options.changeAddress } : {}
5817
+ })
5818
+ });
5819
+ }
5820
+ const requestInfo = await getPayRequest(config2, normalizedRequestCode);
5821
+ const codeStatus = codeStatusInfo.payload;
5822
+ const allowOverpayment = options.allowOverpayment ?? true;
5823
+ const returnChange = options.returnChange ?? "code";
5824
+ const codeValue = BigInt(String(codeStatus.value ?? 0));
5825
+ const requestAmount = BigInt(requestInfo.amount);
5826
+ if (codeValue < requestAmount) {
5827
+ throw new Error(
5828
+ `Payment code value (${Number(codeValue) / 1e6} USDC) is less than the request amount (${Number(requestAmount) / 1e6} USDC)`
5829
+ );
5830
+ }
5831
+ if (!allowOverpayment && codeValue > requestAmount) {
5832
+ throw new Error(
5833
+ `Payment code value (${Number(codeValue) / 1e6} USDC) exceeds the request amount (${Number(requestAmount) / 1e6} USDC)`
5834
+ );
5835
+ }
5836
+ const merchantAddress = String(requestInfo.to);
5837
+ const requestNetwork = String(requestInfo.network);
5838
+ const usePartial = codeValue > requestAmount;
5839
+ return fetchOrThrow(`${facilitatorUrl}/payment-codes/${normalizedPaymentCode}/redeem`, {
5840
+ method: "POST",
5841
+ headers: { "Content-Type": "application/json" },
5842
+ body: JSON.stringify({
5843
+ payee: merchantAddress,
5844
+ ...usePartial ? { invoiceAmount: requestInfo.amount.toString() } : {},
5845
+ ...usePartial ? { returnChangeAsCode: returnChange === "code" } : {},
5846
+ ...usePartial && options.changeAddress ? { changeAddress: options.changeAddress } : {},
5847
+ ...isEvmAddress(merchantAddress) ? { evmNetwork: requestNetwork } : { solanaNetwork: requestNetwork }
5848
+ })
5849
+ });
5850
+ }
5851
+
5148
5852
  // src/utils/payload-converter.ts
5149
5853
  var NETWORK_V1_TO_V2 = {
5150
5854
  "solana": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
@@ -18924,10 +19628,14 @@ export {
18924
19628
  USDC_SOLANA,
18925
19629
  cancelPaymentCode,
18926
19630
  cancelSolanaPaymentCode,
19631
+ cancelStoredPaymentCode,
19632
+ claimPaymentLink,
18927
19633
  convertPayloadToVersion,
18928
19634
  convertV1ToV2,
18929
19635
  convertV2ToV1,
18930
19636
  createPayRequest,
19637
+ createPaymentCode,
19638
+ createPaymentCodesBatch,
18931
19639
  createPrivateKeySigner,
18932
19640
  createX402Client,
18933
19641
  Relai as default,
@@ -18942,11 +19650,13 @@ export {
18942
19650
  generateSolanaPaymentCode,
18943
19651
  getPayRequest,
18944
19652
  getPaymentCode,
19653
+ getPaymentCodeDetails,
18945
19654
  getSolanaPaymentCode,
18946
19655
  isEvm,
18947
19656
  isEvmNetwork,
18948
19657
  isSolana,
18949
19658
  isSolanaNetwork,
19659
+ listOwnerPaymentCodes,
18950
19660
  networkV1ToV2,
18951
19661
  networkV2ToV1,
18952
19662
  normalizeNetwork,
@@ -18954,8 +19664,10 @@ export {
18954
19664
  payPayRequest,
18955
19665
  payPayRequestWithCode,
18956
19666
  payPayRequestWithSolana,
19667
+ payPayRequestWithStoredCode,
18957
19668
  redeemPaymentCode,
18958
19669
  redeemSolanaPaymentCode,
19670
+ redeemStoredPaymentCode,
18959
19671
  resolveToken,
18960
19672
  stripePayTo,
18961
19673
  submitRelayFeedback,