@relai-fi/x402 0.6.10 → 0.6.11-rc.1

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/README.md CHANGED
@@ -1751,6 +1751,8 @@ import {
1751
1751
  getPayRequest,
1752
1752
  payPayRequest,
1753
1753
  payPayRequestWithCode,
1754
+ payPayRequestWithStoredCode,
1755
+ type PaymentRequestObject,
1754
1756
  } from '@relai-fi/x402';
1755
1757
 
1756
1758
  const config = { facilitatorUrl: 'https://relai.fi/facilitator' };
@@ -1784,6 +1786,16 @@ console.log('Explorer:', result.explorerUrl);
1784
1786
  if (result.changeCode) {
1785
1787
  console.log(`Change $${Number(result.change) / 1e6} USDC → code: ${result.changeCode}`);
1786
1788
  }
1789
+
1790
+ // ── Agent / vault flow: reuse a fetched request object directly ─────────────
1791
+ const fetchedRequest: PaymentRequestObject = await getPayRequest(config, 'MW78SGTW');
1792
+ const storedCodeResult = await payPayRequestWithStoredCode(
1793
+ config,
1794
+ fetchedRequest,
1795
+ 'MYVAULT78',
1796
+ { returnChange: 'code' },
1797
+ );
1798
+ console.log('Stored code payment success:', storedCodeResult.success);
1787
1799
  ```
1788
1800
 
1789
1801
  ### `payPayRequestWithCode` options
@@ -1793,6 +1805,13 @@ if (result.changeCode) {
1793
1805
  | `returnChange` | `'code' \| 'wallet'` | `'code'` | How to return surplus when code value > invoice |
1794
1806
  | `allowOverpayment` | `boolean` | `true` | If `false`, throws when code value ≠ invoice amount |
1795
1807
 
1808
+ `payPayRequestWithStoredCode()` accepts either:
1809
+
1810
+ - a payment request code string, or
1811
+ - a fetched `PaymentRequestObject` from `getPayRequest()`
1812
+
1813
+ Passing the object lets agents skip the extra request lookup when they already have the decoded request in memory. For stored Solana codes, the object must include a valid `code` field because the Solana facilitator endpoint still resolves the merchant request by `requestCode`.
1814
+
1796
1815
  **`returnChange` behaviour:**
1797
1816
 
1798
1817
  | Value | Mechanism | Requires buyer wallet? |
package/dist/index.cjs CHANGED
@@ -4548,6 +4548,15 @@ function buildClaimUrl(facilitatorUrl, claimToken) {
4548
4548
  const origin = new URL(facilitatorUrl).origin;
4549
4549
  return new URL(`/claim/${claimToken}`, origin).toString();
4550
4550
  }
4551
+ function resolveSolanaRelayerConfig(relayerInfo, network) {
4552
+ const networkInfo = relayerInfo?.networks?.[network] ?? null;
4553
+ const relayerAddr = typeof networkInfo?.address === "string" && networkInfo.address.trim() ? networkInfo.address.trim() : typeof relayerInfo?.address === "string" ? relayerInfo.address.trim() : "";
4554
+ const programId = typeof relayerInfo?.programId === "string" ? relayerInfo.programId.trim() : "";
4555
+ const usdcMint = typeof networkInfo?.usdc === "string" && networkInfo.usdc.trim() ? networkInfo.usdc.trim() : network === "solana-devnet" ? "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU" : "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
4556
+ if (!relayerAddr) throw new Error(`Missing relayer address for ${network}`);
4557
+ if (!programId) throw new Error("Missing Solana payment-code programId");
4558
+ return { relayerAddr, programId, usdcMint };
4559
+ }
4551
4560
  async function anchorDisc(name) {
4552
4561
  const preimage = new TextEncoder().encode(`global:${name}`);
4553
4562
  if (typeof globalThis !== "undefined" && globalThis.crypto?.subtle) {
@@ -4589,9 +4598,7 @@ async function generateSolanaPaymentCode(config2, wallet, params) {
4589
4598
  if (!infoRes.ok) throw new Error("Failed to fetch Solana relayer info");
4590
4599
  const relayerInfo = await infoRes.json();
4591
4600
  const network = params.network ?? relayerInfo.defaultNetwork ?? "solana";
4592
- const relayerAddr = relayerInfo.address;
4593
- const programId = relayerInfo.programId;
4594
- const usdcMint = relayerInfo.networks?.[network]?.usdc ?? (network === "solana-devnet" ? "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU" : "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
4601
+ const { relayerAddr, programId, usdcMint } = resolveSolanaRelayerConfig(relayerInfo, network);
4595
4602
  const code = generateCode(network, claimLink);
4596
4603
  const codeBytes = new TextEncoder().encode(code);
4597
4604
  const {
@@ -4695,9 +4702,7 @@ async function generateSolanaPaymentCodesBatch(config2, wallet, params) {
4695
4702
  if (!infoRes.ok) throw new Error("Failed to fetch Solana relayer info");
4696
4703
  const relayerInfo = await infoRes.json();
4697
4704
  const network = params.network ?? relayerInfo.defaultNetwork ?? "solana";
4698
- const relayerAddr = relayerInfo.address;
4699
- const programId = relayerInfo.programId;
4700
- const usdcMint = relayerInfo.networks?.[network]?.usdc ?? (network === "solana-devnet" ? "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU" : "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
4705
+ const { relayerAddr, programId, usdcMint } = resolveSolanaRelayerConfig(relayerInfo, network);
4701
4706
  const {
4702
4707
  Connection: Connection2,
4703
4708
  PublicKey: PublicKey2,
@@ -4829,9 +4834,7 @@ async function cancelSolanaPaymentCode(config2, code, wallet, options = {}) {
4829
4834
  if (!infoRes.ok) throw new Error("Failed to fetch Solana relayer info");
4830
4835
  const relayerInfo = await infoRes.json();
4831
4836
  const network = options.network ?? relayerInfo.defaultNetwork ?? "solana";
4832
- const relayerAddr = relayerInfo.address;
4833
- const programId = relayerInfo.programId;
4834
- const usdcMint = relayerInfo.networks?.[network]?.usdc ?? (network === "solana-devnet" ? "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU" : "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
4837
+ const { relayerAddr, programId, usdcMint } = resolveSolanaRelayerConfig(relayerInfo, network);
4835
4838
  const {
4836
4839
  Connection: Connection2,
4837
4840
  PublicKey: PublicKey2,
@@ -5418,6 +5421,9 @@ var EIP3009_TYPES3 = {
5418
5421
  { name: "nonce", type: "bytes32" }
5419
5422
  ]
5420
5423
  };
5424
+ function isPaymentRequestObject(value) {
5425
+ return typeof value !== "string";
5426
+ }
5421
5427
  function isEvmAddress(value) {
5422
5428
  return /^0x[0-9a-fA-F]{40}$/i.test(value);
5423
5429
  }
@@ -5876,12 +5882,16 @@ async function claimPaymentLink(config2, claimUrlOrToken, params) {
5876
5882
  });
5877
5883
  return sanitizeClaimLinkResponse(payload, facilitatorUrl, claimToken);
5878
5884
  }
5879
- async function payPayRequestWithStoredCode(config2, requestCode, paymentCode, options = {}) {
5885
+ async function payPayRequestWithStoredCode(config2, request, paymentCode, options = {}) {
5880
5886
  const facilitatorUrl = config2.facilitatorUrl ?? DEFAULT_FACILITATOR4;
5881
- const normalizedRequestCode = requestCode.trim().toUpperCase();
5882
5887
  const normalizedPaymentCode = paymentCode.trim().toUpperCase();
5888
+ const requestInfo = isPaymentRequestObject(request) ? request : await getPayRequest(config2, request.trim().toUpperCase());
5889
+ const normalizedRequestCode = isPaymentRequestObject(request) ? requestInfo.code.trim().toUpperCase() : request.trim().toUpperCase();
5883
5890
  const codeStatusInfo = await fetchStoredCodeWithFallback(facilitatorUrl, normalizedPaymentCode);
5884
5891
  if (codeStatusInfo.kind === "solana") {
5892
+ if (!normalizedRequestCode) {
5893
+ throw new Error("A payment request object with a valid code is required when paying a request with a stored Solana code");
5894
+ }
5885
5895
  return fetchOrThrow(`${facilitatorUrl}/solana-payment-codes/${normalizedPaymentCode}/pay-request`, {
5886
5896
  method: "POST",
5887
5897
  headers: { "Content-Type": "application/json" },
@@ -5891,7 +5901,6 @@ async function payPayRequestWithStoredCode(config2, requestCode, paymentCode, op
5891
5901
  })
5892
5902
  });
5893
5903
  }
5894
- const requestInfo = await getPayRequest(config2, normalizedRequestCode);
5895
5904
  const codeStatus = codeStatusInfo.payload;
5896
5905
  const allowOverpayment = options.allowOverpayment ?? true;
5897
5906
  const returnChange = options.returnChange ?? "code";