@moneymq/react 0.9.4 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -46751,46 +46751,31 @@ var SandboxContext = (0, import_react3.createContext)({
46751
46751
  sandboxAccounts: []
46752
46752
  });
46753
46753
  var DEFAULT_RPC_URL = "https://api.devnet.solana.com";
46754
- var SANDBOX_HASH_PREFIX = "SURFNETxSAFEHASH";
46755
46754
  function normalizeRpcUrl(url2) {
46756
46755
  return url2.replace("0.0.0.0", "localhost").replace("127.0.0.1", "localhost");
46757
46756
  }
46758
- async function getRpcUrl(apiUrl) {
46757
+ async function getFacilitatorConfig(apiUrl) {
46759
46758
  try {
46760
- console.log("[MoneyMQ] Fetching config from:", `${apiUrl}/config`);
46761
- const response = await fetch(`${apiUrl}/config`);
46759
+ const configUrl = `${apiUrl}/payment/v1/config?attrs=studio`;
46760
+ console.log("[MoneyMQ] Fetching facilitator config from:", configUrl);
46761
+ const response = await fetch(configUrl);
46762
+ if (!response.ok) {
46763
+ throw new Error(`Failed to fetch config: ${response.status}`);
46764
+ }
46762
46765
  const config2 = await response.json();
46763
- const rawRpcUrl = config2.x402?.validator?.rpcUrl || DEFAULT_RPC_URL;
46764
- console.log("[MoneyMQ] Raw RPC URL from config:", rawRpcUrl);
46766
+ const rawRpcUrl = config2.studio?.rpcUrl || DEFAULT_RPC_URL;
46765
46767
  const normalizedUrl = normalizeRpcUrl(rawRpcUrl);
46766
- console.log("[MoneyMQ] Normalized RPC URL:", normalizedUrl);
46767
- return normalizedUrl;
46768
- } catch (err2) {
46769
- console.error("[MoneyMQ] Error fetching config:", err2);
46770
- return DEFAULT_RPC_URL;
46771
- }
46772
- }
46773
- async function checkSandboxMode(rpcUrl) {
46774
- try {
46775
- console.log("[MoneyMQ] Checking sandbox mode with RPC:", rpcUrl);
46776
- const response = await fetch(rpcUrl, {
46777
- method: "POST",
46778
- headers: { "Content-Type": "application/json" },
46779
- body: JSON.stringify({
46780
- jsonrpc: "2.0",
46781
- id: 1,
46782
- method: "getLatestBlockhash",
46783
- params: [{ commitment: "finalized" }]
46784
- })
46785
- });
46786
- const data = await response.json();
46787
- const blockhash = data?.result?.value?.blockhash || "";
46788
- const isSandbox = blockhash.startsWith(SANDBOX_HASH_PREFIX);
46789
- console.log("[MoneyMQ] Blockhash:", blockhash, "| Sandbox:", isSandbox);
46790
- return isSandbox;
46768
+ console.log("[MoneyMQ] Facilitator config:", { isSandbox: config2.isSandbox, rpcUrl: normalizedUrl });
46769
+ return {
46770
+ isSandbox: config2.isSandbox,
46771
+ rpcUrl: normalizedUrl
46772
+ };
46791
46773
  } catch (err2) {
46792
- console.error("[MoneyMQ] Error checking sandbox mode:", err2);
46793
- return false;
46774
+ console.error("[MoneyMQ] Error fetching facilitator config:", err2);
46775
+ return {
46776
+ isSandbox: false,
46777
+ rpcUrl: DEFAULT_RPC_URL
46778
+ };
46794
46779
  }
46795
46780
  }
46796
46781
  async function fetchTokenBalance(rpcUrl, tokenAccountAddress) {
@@ -46816,8 +46801,8 @@ async function fetchTokenBalance(rpcUrl, tokenAccountAddress) {
46816
46801
  }
46817
46802
  async function fetchSandboxAccounts(apiUrl, rpcUrl) {
46818
46803
  try {
46819
- console.log("[MoneyMQ] Fetching sandbox accounts from:", `${apiUrl}/sandbox/accounts`);
46820
- const response = await fetch(`${apiUrl}/sandbox/accounts`);
46804
+ console.log("[MoneyMQ] Fetching sandbox accounts from:", `${apiUrl}/payment/v1/accounts`);
46805
+ const response = await fetch(`${apiUrl}/payment/v1/accounts`);
46821
46806
  if (!response.ok) {
46822
46807
  console.log("[MoneyMQ] Sandbox accounts fetch failed:", response.status);
46823
46808
  return [];
@@ -46859,19 +46844,14 @@ function useMoneyMQ() {
46859
46844
  function useSandbox() {
46860
46845
  return (0, import_react3.useContext)(SandboxContext);
46861
46846
  }
46862
- function MoneyMQProvider({
46863
- children,
46864
- client,
46865
- branding
46866
- }) {
46847
+ function MoneyMQProvider({ children, client, branding }) {
46867
46848
  const [rpcEndpoint, setRpcEndpoint] = (0, import_react3.useState)(null);
46868
46849
  const [isSandboxMode, setIsSandboxMode] = (0, import_react3.useState)(false);
46869
46850
  const [sandboxAccounts, setSandboxAccounts] = (0, import_react3.useState)([]);
46870
46851
  (0, import_react3.useEffect)(() => {
46871
46852
  async function initialize() {
46872
- const rpcUrl = await getRpcUrl(client.config.endpoint);
46853
+ const { isSandbox, rpcUrl } = await getFacilitatorConfig(client.config.endpoint);
46873
46854
  setRpcEndpoint(rpcUrl);
46874
- const isSandbox = await checkSandboxMode(rpcUrl);
46875
46855
  setIsSandboxMode(isSandbox);
46876
46856
  if (isSandbox) {
46877
46857
  const accounts = await fetchSandboxAccounts(client.config.endpoint, rpcUrl);
@@ -49553,31 +49533,38 @@ function waitForSettlementEvent(apiUrl, paymentIntentId, timeoutMs = 3e4) {
49553
49533
  stream.connect();
49554
49534
  });
49555
49535
  }
49556
- function waitForChannelEvent(apiUrl, channelId, eventType, timeoutMs = 3e4) {
49536
+ function waitForTransactionCompleted(apiUrl, transactionId, timeoutMs = 3e4) {
49557
49537
  return new Promise((resolve, reject) => {
49558
- console.log("[MoneyMQ] Waiting for channel event:", eventType, "on channel:", channelId);
49559
- const reader = new import_sdk.EventReader(apiUrl, channelId, { replay: 10 });
49538
+ console.log("[MoneyMQ] Waiting for transaction:completed event for tx:", transactionId);
49539
+ const stream = new import_sdk.EventStream(apiUrl, { last: 5 });
49560
49540
  let resolved = false;
49561
49541
  const cleanup = () => {
49562
49542
  if (!resolved) {
49563
- reader.disconnect();
49543
+ stream.disconnect();
49564
49544
  }
49565
49545
  };
49566
49546
  const timeout = setTimeout(() => {
49567
49547
  cleanup();
49568
- reject(new Error(`Channel event timeout waiting for ${eventType}`));
49548
+ reject(new Error("Transaction completed event timeout"));
49569
49549
  }, timeoutMs);
49570
- reader.on(eventType, (event) => {
49571
- console.log("[MoneyMQ] Channel event received:", eventType);
49572
- resolved = true;
49573
- clearTimeout(timeout);
49574
- reader.disconnect();
49575
- resolve(event);
49550
+ stream.on("payment", (event) => {
49551
+ console.log("[MoneyMQ] Received event while waiting for transaction:completed:", event.type);
49552
+ if ((0, import_sdk.isTransactionCompleted)(event)) {
49553
+ if (event.data.transaction_id === transactionId) {
49554
+ console.log("[MoneyMQ] Transaction completed event received for tx:", transactionId);
49555
+ resolved = true;
49556
+ clearTimeout(timeout);
49557
+ stream.disconnect();
49558
+ resolve(event);
49559
+ } else {
49560
+ console.log("[MoneyMQ] Transaction completed event for different tx:", event.data.transaction_id);
49561
+ }
49562
+ }
49576
49563
  });
49577
- reader.on("error", (error46) => {
49578
- console.error("[MoneyMQ] Channel reader error:", error46);
49564
+ stream.on("error", (error46) => {
49565
+ console.error("[MoneyMQ] Stream error while waiting for transaction:completed:", error46);
49579
49566
  });
49580
- reader.connect();
49567
+ stream.connect();
49581
49568
  });
49582
49569
  }
49583
49570
  function getLineItemSubtotal(item) {
@@ -49728,10 +49715,10 @@ function CheckoutModal({
49728
49715
  if (currentSelection?.type === "browser_extension" && publicKey) {
49729
49716
  const apiUrl = normalizeRpcUrl2(client.config.endpoint);
49730
49717
  try {
49731
- const configResponse = await fetch(`${apiUrl}/config`);
49718
+ const configResponse = await fetch(`${apiUrl}/payment/v1/config?attrs=studio`);
49732
49719
  const config2 = await configResponse.json();
49733
49720
  const rpcUrl = normalizeRpcUrl2(
49734
- config2.x402?.validator?.rpcUrl || "http://localhost:8899"
49721
+ config2.studio?.rpcUrl || "http://localhost:8899"
49735
49722
  );
49736
49723
  const response = await fetch(rpcUrl, {
49737
49724
  method: "POST",
@@ -49786,9 +49773,9 @@ function CheckoutModal({
49786
49773
  const apiUrl2 = normalizeRpcUrl2(client.config.endpoint);
49787
49774
  let rpcUrl = "http://localhost:8899";
49788
49775
  try {
49789
- const configResponse = await fetch(`${apiUrl2}/config`);
49776
+ const configResponse = await fetch(`${apiUrl2}/payment/v1/config?attrs=studio`);
49790
49777
  const config2 = await configResponse.json();
49791
- rpcUrl = normalizeRpcUrl2(config2.x402?.validator?.rpcUrl || rpcUrl);
49778
+ rpcUrl = normalizeRpcUrl2(config2.studio?.rpcUrl || rpcUrl);
49792
49779
  } catch {
49793
49780
  console.log("[MoneyMQ] Using default RPC URL");
49794
49781
  }
@@ -49808,17 +49795,9 @@ function CheckoutModal({
49808
49795
  if (!transactionId2) {
49809
49796
  throw new Error("No transaction ID received from settlement event");
49810
49797
  }
49811
- console.log("[MoneyMQ] Waiting for transaction:completed on channel:", transactionId2);
49812
- const completedEvent2 = await waitForChannelEvent(
49813
- apiUrl2,
49814
- transactionId2,
49815
- "transaction:completed",
49816
- 3e4
49817
- );
49818
- const receiptToken2 = completedEvent2.data?.receipt;
49819
- if (!receiptToken2) {
49820
- throw new Error("No receipt token in transaction:completed event");
49821
- }
49798
+ console.log("[MoneyMQ] Waiting for transaction:completed CloudEvent for tx:", transactionId2);
49799
+ const completedEvent2 = await waitForTransactionCompleted(apiUrl2, transactionId2, 3e4);
49800
+ const receiptToken2 = completedEvent2.data.receipt;
49822
49801
  console.log("[MoneyMQ] Receipt received, creating CheckoutReceipt");
49823
49802
  const receipt2 = new import_sdk.CheckoutReceipt(receiptToken2);
49824
49803
  setIsSending(false);
@@ -49844,17 +49823,9 @@ function CheckoutModal({
49844
49823
  if (!transactionId) {
49845
49824
  throw new Error("No transaction ID received from settlement event");
49846
49825
  }
49847
- console.log("[MoneyMQ] Waiting for transaction:completed on channel:", transactionId);
49848
- const completedEvent = await waitForChannelEvent(
49849
- apiUrl,
49850
- transactionId,
49851
- "transaction:completed",
49852
- 3e4
49853
- );
49854
- const receiptToken = completedEvent.data?.receipt;
49855
- if (!receiptToken) {
49856
- throw new Error("No receipt token in transaction:completed event");
49857
- }
49826
+ console.log("[MoneyMQ] Waiting for transaction:completed CloudEvent for tx:", transactionId);
49827
+ const completedEvent = await waitForTransactionCompleted(apiUrl, transactionId, 3e4);
49828
+ const receiptToken = completedEvent.data.receipt;
49858
49829
  console.log("[MoneyMQ] Receipt received, creating CheckoutReceipt");
49859
49830
  const receipt = new import_sdk.CheckoutReceipt(receiptToken);
49860
49831
  setIsSending(false);
@@ -49879,9 +49850,10 @@ function CheckoutModal({
49879
49850
  ]);
49880
49851
  const canPay = (connected && publicKey || selectedPaymentMethod?.type === "sandbox_account") && recipient && !isSending;
49881
49852
  const dotLottieRef = (0, import_react5.useRef)(null);
49853
+ const processingLottieRef = (0, import_react5.useRef)(null);
49882
49854
  (0, import_react5.useEffect)(() => {
49883
49855
  if (!dotLottieRef.current) return;
49884
- if (canPay) {
49856
+ if (canPay && !isSending) {
49885
49857
  dotLottieRef.current.setFrame(0);
49886
49858
  dotLottieRef.current.play();
49887
49859
  const interval = setInterval(() => {
@@ -49894,7 +49866,15 @@ function CheckoutModal({
49894
49866
  } else {
49895
49867
  dotLottieRef.current.stop();
49896
49868
  }
49897
- }, [canPay]);
49869
+ }, [canPay, isSending]);
49870
+ (0, import_react5.useEffect)(() => {
49871
+ if (!processingLottieRef.current) return;
49872
+ if (isSending) {
49873
+ processingLottieRef.current.setSpeed(2);
49874
+ processingLottieRef.current.setLoop(true);
49875
+ processingLottieRef.current.play();
49876
+ }
49877
+ }, [isSending]);
49898
49878
  if (typeof document === "undefined") return null;
49899
49879
  if (!shouldRender) return null;
49900
49880
  const WalletIcon = () => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
@@ -50756,11 +50736,11 @@ function CheckoutModal({
50756
50736
  }
50757
50737
  )
50758
50738
  ] }),
50759
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
50739
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
50760
50740
  "button",
50761
50741
  {
50762
50742
  onClick: handlePay,
50763
- disabled: !canPay,
50743
+ disabled: !canPay || isSending,
50764
50744
  style: {
50765
50745
  width: "100%",
50766
50746
  padding: "0.5rem 1rem",
@@ -50768,63 +50748,97 @@ function CheckoutModal({
50768
50748
  border: "none",
50769
50749
  fontSize: "1.0625rem",
50770
50750
  fontWeight: 600,
50771
- cursor: canPay ? "pointer" : "not-allowed",
50772
- backgroundColor: canPay ? "#000" : "#48484a",
50773
- color: canPay ? "#fff" : "#8e8e93",
50751
+ cursor: canPay && !isSending ? "pointer" : "not-allowed",
50752
+ backgroundColor: canPay || isSending ? "#000" : "#48484a",
50753
+ color: canPay || isSending ? "#fff" : "#8e8e93",
50774
50754
  display: "flex",
50775
50755
  alignItems: "center",
50776
50756
  justifyContent: "center",
50777
50757
  gap: "0.25rem",
50778
- transition: "opacity 150ms"
50758
+ transition: "background-color 150ms, color 150ms",
50759
+ position: "relative",
50760
+ overflow: "hidden"
50779
50761
  },
50780
- children: isSending ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
50762
+ children: [
50781
50763
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
50782
50764
  "div",
50783
50765
  {
50784
50766
  style: {
50785
- width: "1.25rem",
50786
- height: "1.25rem",
50787
- border: "2px solid currentColor",
50788
- borderTopColor: "transparent",
50789
- borderRadius: "50%",
50790
- animation: "spin 1s linear infinite"
50791
- }
50767
+ position: "absolute",
50768
+ inset: 0,
50769
+ display: "flex",
50770
+ alignItems: "center",
50771
+ justifyContent: "center",
50772
+ opacity: isSending ? 1 : 0,
50773
+ transform: isSending ? "scale(1)" : "scale(0.8)",
50774
+ transition: "opacity 200ms ease-out, transform 200ms ease-out",
50775
+ pointerEvents: "none"
50776
+ },
50777
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
50778
+ l9,
50779
+ {
50780
+ dotLottieRefCallback: (dotLottie) => {
50781
+ processingLottieRef.current = dotLottie;
50782
+ },
50783
+ data: JSON.stringify(logo_animation_default),
50784
+ loop: false,
50785
+ autoplay: false,
50786
+ style: {
50787
+ width: 48,
50788
+ height: 48
50789
+ }
50790
+ }
50791
+ )
50792
50792
  }
50793
50793
  ),
50794
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Processing..." })
50795
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
50796
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
50797
- l9,
50794
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
50795
+ "div",
50798
50796
  {
50799
- dotLottieRefCallback: (dotLottie) => {
50800
- dotLottieRef.current = dotLottie;
50801
- },
50802
- data: JSON.stringify(logo_animation_default),
50803
- loop: false,
50804
- autoplay: false,
50805
50797
  style: {
50806
- width: 48,
50807
- height: 48,
50808
- marginTop: "-8px",
50809
- marginBottom: "-8px",
50810
- marginLeft: "-8px",
50811
- marginRight: "4px",
50812
- opacity: canPay ? 1 : 0.55,
50813
- transition: "opacity 150ms"
50814
- }
50798
+ display: "flex",
50799
+ alignItems: "center",
50800
+ justifyContent: "center",
50801
+ gap: "0.25rem",
50802
+ opacity: isSending ? 0 : 1,
50803
+ transform: isSending ? "scale(0.95)" : "scale(1)",
50804
+ transition: "opacity 200ms ease-out, transform 200ms ease-out"
50805
+ },
50806
+ children: [
50807
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
50808
+ l9,
50809
+ {
50810
+ dotLottieRefCallback: (dotLottie) => {
50811
+ dotLottieRef.current = dotLottie;
50812
+ },
50813
+ data: JSON.stringify(logo_animation_default),
50814
+ loop: false,
50815
+ autoplay: false,
50816
+ style: {
50817
+ width: 48,
50818
+ height: 48,
50819
+ marginTop: "-8px",
50820
+ marginBottom: "-8px",
50821
+ marginLeft: "-8px",
50822
+ marginRight: "4px",
50823
+ opacity: canPay ? 1 : 0.55,
50824
+ transition: "opacity 150ms"
50825
+ }
50826
+ }
50827
+ ),
50828
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
50829
+ "Pay",
50830
+ " ",
50831
+ amount.toLocaleString(void 0, {
50832
+ minimumFractionDigits: 2,
50833
+ maximumFractionDigits: 2
50834
+ }),
50835
+ " ",
50836
+ currency
50837
+ ] })
50838
+ ]
50815
50839
  }
50816
- ),
50817
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
50818
- "Pay",
50819
- " ",
50820
- amount.toLocaleString(void 0, {
50821
- minimumFractionDigits: 2,
50822
- maximumFractionDigits: 2
50823
- }),
50824
- " ",
50825
- currency
50826
- ] })
50827
- ] })
50840
+ )
50841
+ ]
50828
50842
  }
50829
50843
  )
50830
50844
  ]
@@ -50910,16 +50924,17 @@ var CheckoutButton = (0, import_react6.forwardRef)(
50910
50924
  setError(null);
50911
50925
  try {
50912
50926
  if (!basket || basket.length === 0) {
50913
- throw new Error("Basket is empty");
50927
+ setIsLoading(true);
50928
+ return;
50914
50929
  }
50915
50930
  const apiUrl = client.config.endpoint;
50916
- const configResponse = await fetch(`${apiUrl}/config`);
50931
+ const configResponse = await fetch(`${apiUrl}/payment/v1/config`);
50917
50932
  if (!configResponse.ok) {
50918
50933
  throw new Error(`Failed to fetch config: ${configResponse.status}`);
50919
50934
  }
50920
50935
  const config2 = await configResponse.json();
50921
- if (config2.x402?.payoutAccount?.address) {
50922
- setRecipient(config2.x402.payoutAccount.address);
50936
+ if (config2.x402?.solana?.payout?.recipientAddress) {
50937
+ setRecipient(config2.x402.solana.payout.recipientAddress);
50923
50938
  }
50924
50939
  } catch (err2) {
50925
50940
  console.error("[CheckoutButton] Error fetching payment details:", err2);