@dexterai/x402 1.6.1 → 1.6.2

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.
@@ -424,6 +424,7 @@ function x402Middleware(config) {
424
424
  }
425
425
 
426
426
  // src/server/browser-support.ts
427
+ var USDC_ICON_SVG = `<svg width="18" height="18" viewBox="0 0 2000 2000" xmlns="http://www.w3.org/2000/svg"><path d="M1000 2000c554.17 0 1000-445.83 1000-1000S1554.17 0 1000 0 0 445.83 0 1000s445.83 1000 1000 1000z" fill="#2775ca"/><path d="M1275 1158.33c0-145.83-87.5-195.83-262.5-216.66-125-16.67-150-50-150-108.34s41.67-95.83 125-95.83c75 0 116.67 25 137.5 87.5 4.17 12.5 16.67 20.83 29.17 20.83h66.66c16.67 0 29.17-12.5 29.17-29.16v-4.17c-16.67-91.67-91.67-162.5-187.5-170.83v-100c0-16.67-12.5-29.17-33.33-33.34h-62.5c-16.67 0-29.17 12.5-33.34 33.34v95.83c-125 16.67-204.16 100-204.16 204.17 0 137.5 83.33 191.66 258.33 212.5 116.67 20.83 154.17 45.83 154.17 112.5s-58.34 112.5-137.5 112.5c-108.34 0-145.84-45.84-158.34-108.34-4.16-16.66-16.66-25-29.16-25h-70.84c-16.66 0-29.16 12.5-29.16 29.17v4.17c16.66 104.16 83.33 179.16 220.83 200v100c0 16.66 12.5 29.16 33.33 33.33h62.5c16.67 0 29.17-12.5 33.34-33.33v-100c125-20.84 208.33-108.34 208.33-220.84z" fill="#fff"/><path d="M787.5 1595.83c-325-116.66-491.67-479.16-370.83-800 62.5-175 200-308.33 370.83-370.83 16.67-8.33 25-20.83 25-41.67V325c0-16.67-8.33-29.17-25-33.33-4.17 0-12.5 0-16.67 4.16-395.83 125-612.5 545.84-487.5 941.67 75 233.33 254.17 412.5 487.5 487.5 16.67 8.33 33.34 0 37.5-16.67 4.17-4.16 4.17-8.33 4.17-16.66v-58.34c0-12.5-12.5-29.16-25-37.5zM1229.17 295.83c-16.67-8.33-33.34 0-37.5 16.67-4.17 4.17-4.17 8.33-4.17 16.67v58.33c0 16.67 12.5 33.33 25 41.67 325 116.66 491.67 479.16 370.83 800-62.5 175-200 308.33-370.83 370.83-16.67 8.33-25 20.83-25 41.67V1700c0 16.67 8.33 29.17 25 33.33 4.17 0 12.5 0 16.67-4.16 395.83-125 612.5-545.84 487.5-941.67-75-237.5-258.34-416.67-487.5-491.67z" fill="#fff"/></svg>`;
427
428
  var DEXTER_CREST_SVG = `<svg width="36" height="36" viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg"><g><path fill="#F2681A" d="m324.93,313.11c-115.5,0-231,0-350,0l350,0z"/><path fill="#FDFAF5" d="m230.43,50.62c1.1.85 2.19 1.7 3.32 2.57 6.02 4.8 11.77 9.88 17.46 15.07.92.84.92.84 1.86 1.69 1.82 1.69 3.59 3.42 5.35 5.16.61.56 1.22 1.13 1.84 1.71 5.66 5.76 6.18 10.43 6.13 18.3.02 1.16.04 2.32.06 3.52.06 3.83.06 7.65.07 11.48.02 2.68.05 5.35.08 8.03.05 5.6.09 11.21.1 16.81.02 7.15.09 14.31.17 21.46.06 5.53.1 11.05.13 16.58.02 2.64.04 5.27.07 7.91.18 17.58.12 32.82-11.24 47.32-7.35 7.27-16.54 12.06-25.42 17.22-1.97 1.16-3.94 2.33-5.91 3.49-7.16 4.24-14.34 8.44-21.53 12.62-4.8 2.79-9.59 5.6-14.38 8.42-1.25.73-2.5 1.47-3.79 2.23-2.32 1.36-4.64 2.73-6.96 4.1-27.47 16.09-27.47 16.09-42.16 12.93-8.06-2.28-14.94-5.82-22.16-10.02-1.17-.67-2.34-1.34-3.54-2.04-24.55-14.25-43.58-27.03-51.9-55.58-1.07-4.58-1.54-8.92-1.52-13.61.28-9.5.28-9.5-3.3-17.97-1.81-1.49-3.68-2.92-5.59-4.28-9.19-7.06-12.7-20.03-14.18-31.06-.54-5.77-.55-11.56-.6-17.35-.03-1.32-.07-2.63-.1-3.99-.01-1.26-.02-2.53-.03-3.83-.02-1.15-.03-2.29-.05-3.47.72-4.02 1.94-5.36 5.21-7.74 2.89-.53 2.89-.53 6.07-.46 1.71.02 1.71.02 3.46.05 1.19.04 2.37.08 3.59.12 1.2.02 2.41.04 3.65.06 2.97.05 5.93.13 8.9.23.14-1.35.29-2.7.43-4.08.63-5 1.78-9.74 3.14-14.58.22-.79.43-1.59.66-2.4.53-1.92 1.06-3.84 1.6-5.76-1.55-.45-1.55-.45-3.13-.9-9.52-3.52-17.1-10.95-21.37-20.1-3.81-9.26-3.87-20.34-.29-29.68 6.49-13.99 16.36-23.23 30.66-29.01 49.81-17.69 115.79 8.35 155.13 38.85z"/><path fill="#F2671A" d="m142.93,22.62c.86.19 1.73.39 2.62.59 36.12 8.21 68.79 24.98 95.38 50.75 1.02.98 2.03 1.97 3.08 2.98 10.84 10.66 10.84 10.66 11.05 14.62-2.06 3.55-5.44 4.18-9.17 5.3-.79.25-1.59.49-2.41.75-28.13 8.43-60.95 6.37-87.13-7.16-.86-.49-1.71-.97-2.6-1.48-7.37-4.05-12.59-3.36-20.59-1.54-22.76 4-48.47 1.53-68.69-9.74-4.88-3.88-8.23-8.29-10.21-14.22-.93-10.38-.67-18.44 5.83-26.83 19.57-23.38 55.99-20.36 82.83-14z"/><path fill="#F16619" d="m44.93,129.12c27.36-.03 54.72-.05 82.08-.06 12.7-.01 25.41-.01 38.11-.03 11.07-.01 22.14-.02 33.2-.02 5.86 0 11.73-.01 17.59-.01 5.51-.01 11.03-.01 16.54-.01 2.03 0 4.06 0 6.09-.01 2.76-.01 5.52 0 8.28 0 .81 0 1.63-.01 2.47-.01 5.51.02 5.51.02 6.81 1.32.22 3.43.22 3.43 0 7-2.75 2.75-3.42 2.66-7.15 2.82-1.41.07-1.41.07-2.85.14-1.47.05-1.47.05-2.98.11-1.49.07-1.49.07-3 .14-2.45.11-4.9.21-7.35.3-.2 1.3-.4 2.59-.6 3.93-2.57 16.08-5.93 29.89-18.89 40.86-10.35 7.28-21.87 8.49-34.17 7.71-13.11-2.33-22.52-9.19-30.33-19.83-4.49-7.64-4.8-17.05-5.83-25.67-4.24.39-8.47.77-12.83 1.17-.28 1.84-.28 1.84-.56 3.71-2.32 14.39-5.63 23.35-16.95 33.11-2.32 1.67-2.32 1.67-4.65 1.67 4 4.67 9.06 6.59 14.87 8.24 3.79 1.09 3.79 1.09 6.12 3.43-.65 5.31-.65 5.31-2.33 7-8.42-.27-15.13-2.29-22.17-7-1.09-1.21-2.17-2.43-3.25-3.65-2.72-2.81-4.45-3.84-8.36-4.16-1.67-.02-3.34-.02-5.01.01-1.77-.04-3.54-.09-5.3-.15-1.27-.04-1.27-.04-2.56-.08-9.26-.54-17.6-4.56-24.51-10.64-9.58-11.11-11.03-22.56-10.72-36.82.02-1.4.03-2.8.05-4.24.04-3.42.1-6.85.17-10.27z"/><path fill="#F26117" d="m172.68,203.08c7.27.09 13.23 1.97 18.87 6.65 2.88 3.07 3.86 5.12 4.25 9.32-.12 1.01-.24 2.02-.36 3.06-2.55.95-2.55.95-5.83 1.17-3.28-2.84-3.28-2.84-5.83-5.83-.36.58-.71 1.16-1.08 1.75-7.6 11.29-20.06 17.74-33.05 21.09-20.36 3.1-36.81-1.66-53.37-13.73-2.33-2.11-2.33-2.11-4.67-5.61.42-3.45.99-4.49 3.5-7 4.07.37 5.95 2.13 8.75 4.96 9.81 8.93 22.53 11.87 35.51 11.69 11.74-1.05 22.38-5.85 31.57-13.15 2.06-2.45 2.06-2.45 3.5-4.67-1.66.07-1.66.07-3.35.15-3.65-.15-3.65-.15-5.98-2.48.75-6.18 1.46-7.19 7.58-7.36z"/></g></svg>`;
428
429
  var DEXTER_STYLES = `
429
430
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Orbitron:wght@500;700&display=swap');
@@ -433,7 +434,8 @@ body{font-family:'Inter',system-ui,-apple-system,sans-serif;background:#0a0a0a;c
433
434
  .crest{margin:0 auto .75rem}
434
435
  h1{font-family:'Orbitron',sans-serif;font-size:1.15rem;font-weight:700;color:#f1f5f9;letter-spacing:.04em;margin-bottom:.35rem}
435
436
  .desc{color:#94a3b8;font-size:.9rem;margin-bottom:1.25rem;line-height:1.5}
436
- .price{font-family:'Orbitron',sans-serif;font-size:1.6rem;font-weight:700;color:#F26B1A;margin:.75rem 0 .25rem}
437
+ .price{font-family:'Orbitron',sans-serif;font-size:1.6rem;font-weight:700;color:#F26B1A;margin:.75rem 0 .25rem;display:inline-flex;align-items:center;gap:.35rem}
438
+ .price svg{width:1.3em;height:1.3em;flex-shrink:0}
437
439
  .chain{color:#525252;font-size:.75rem;margin-bottom:1.25rem;letter-spacing:.03em}
438
440
  .endpoint{background:rgba(242,107,26,.06);border:1px solid rgba(242,107,26,.12);border-radius:6px;padding:.5rem .75rem;margin-bottom:1.25rem}
439
441
  .endpoint code{font-family:'SF Mono',Monaco,Consolas,monospace;font-size:.8rem;color:#F26B1A}
@@ -628,13 +630,15 @@ if (btn) {
628
630
  setBtnState('Verifying...', true, true);
629
631
  setStatus('Payment submitted, verifying...');
630
632
 
633
+ // Use the original request body if available
634
+ const originalBody = dataEl.dataset.body ? atob(dataEl.dataset.body) : '{}';
631
635
  const response = await fetch(requestUrl, {
632
636
  method: requestMethod,
633
637
  headers: {
634
638
  'Content-Type': 'application/json',
635
639
  'PAYMENT-SIGNATURE': paymentHeader,
636
640
  },
637
- body: requestMethod !== 'GET' ? '{}' : undefined,
641
+ body: requestMethod !== 'GET' ? originalBody : undefined,
638
642
  });
639
643
 
640
644
  if (response.ok) {
@@ -652,14 +656,14 @@ if (btn) {
652
656
  }
653
657
  } catch (err) {
654
658
  console.error('[x402] Payment error:', err);
655
- setBtnState('Pay $' + document.getElementById('price-value').textContent, false, false);
659
+ setBtnState('Pay ' + document.getElementById('price-value').textContent, false, false);
656
660
  setStatus(err.message || 'Payment failed', 'error');
657
661
  }
658
662
  });
659
663
  }
660
664
  </script>
661
665
  `;
662
- function generatePaywallHtml(paymentRequiredHeader, requestUrl, method, config, rpcUrl) {
666
+ function generatePaywallHtml(paymentRequiredHeader, requestUrl, method, config, rpcUrl, requestBody) {
663
667
  let price = "?";
664
668
  let description = "This resource requires payment";
665
669
  let network = "";
@@ -684,7 +688,7 @@ function generatePaywallHtml(paymentRequiredHeader, requestUrl, method, config,
684
688
  <head>
685
689
  <meta charset="utf-8">
686
690
  <meta name="viewport" content="width=device-width,initial-scale=1">
687
- <title>${config.title} \u2014 $${price} USDC</title>
691
+ <title>${config.title} \u2014 ${price} USDC</title>
688
692
  <style>${DEXTER_STYLES}${PAY_BUTTON_STYLES}</style>
689
693
  </head>
690
694
  <body>
@@ -692,12 +696,12 @@ function generatePaywallHtml(paymentRequiredHeader, requestUrl, method, config,
692
696
  <div class="crest">${DEXTER_CREST_SVG}</div>
693
697
  <h1>${config.title}</h1>
694
698
  <p class="desc">${description}</p>
695
- <div class="price">$<span id="price-value">${price}</span> USDC</div>
699
+ <div class="price">${USDC_ICON_SVG}<span id="price-value">${price}</span></div>
696
700
  <div class="chain">${chainName}${chainName ? " network" : ""}</div>
697
701
  ${endpointSection}
698
702
 
699
703
  <div id="pay-section" class="pay-section" style="display:none">
700
- <button id="pay-btn" class="pay-btn">Pay $${price}</button>
704
+ <button id="pay-btn" class="pay-btn">Pay ${price}</button>
701
705
  <div id="pay-status" class="pay-status"></div>
702
706
  <div class="pay-alt">or use <a href="${config.sdkUrl}">x402 SDK</a> for programmatic access</div>
703
707
  </div>
@@ -712,7 +716,7 @@ function generatePaywallHtml(paymentRequiredHeader, requestUrl, method, config,
712
716
  </div>
713
717
 
714
718
  <div class="footer">
715
- <a href="https://x402.org">x402</a>
719
+ <a href="https://docs.dexter.cash/docs/sdk/">x402</a>
716
720
  <span class="sep"></span>
717
721
  <a href="https://dexter.cash">Dexter</a>
718
722
  </div>
@@ -723,6 +727,7 @@ function generatePaywallHtml(paymentRequiredHeader, requestUrl, method, config,
723
727
  data-method="${method}"
724
728
  data-url="${requestUrl}"
725
729
  data-rpc="${rpcUrl}"
730
+ data-body="${requestBody ? Buffer.from(requestBody).toString("base64") : ""}"
726
731
  ></div>
727
732
  ${PAY_SCRIPT}
728
733
  </body>
@@ -731,8 +736,8 @@ ${PAY_SCRIPT}
731
736
  function x402BrowserSupport(config = {}) {
732
737
  const resolvedConfig = {
733
738
  title: config.title ?? "Payment Required",
734
- branding: config.branding ?? 'Powered by <a href="https://x402.org">x402</a>',
735
- sdkUrl: config.sdkUrl ?? "https://x402.org",
739
+ branding: config.branding ?? 'Powered by <a href="https://docs.dexter.cash/docs/sdk/">Dexter x402</a>',
740
+ sdkUrl: config.sdkUrl ?? "https://docs.dexter.cash/docs/sdk/",
736
741
  showEndpoint: config.showEndpoint ?? true
737
742
  };
738
743
  const rpcUrl = config.rpcUrl ?? "https://api.dexter.cash/api/solana/rpc";
@@ -742,12 +747,20 @@ function x402BrowserSupport(config = {}) {
742
747
  if (res.statusCode === 402 && req.accepts("html") && !req.headers["payment-signature"]) {
743
748
  const paymentRequired = res.getHeader("PAYMENT-REQUIRED") || res.getHeader("payment-required");
744
749
  if (paymentRequired && typeof paymentRequired === "string") {
750
+ let bodyStr;
751
+ if (req.body && typeof req.body === "object" && Object.keys(req.body).length > 0) {
752
+ try {
753
+ bodyStr = JSON.stringify(req.body);
754
+ } catch {
755
+ }
756
+ }
745
757
  const html = generatePaywallHtml(
746
758
  paymentRequired,
747
759
  req.originalUrl,
748
760
  req.method,
749
761
  resolvedConfig,
750
- rpcUrl
762
+ rpcUrl,
763
+ bodyStr
751
764
  );
752
765
  res.status(402).type("html").send(html);
753
766
  return res;