@b3dotfun/sdk 0.0.43 → 0.0.44-alpha.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.
@@ -52,11 +52,27 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
52
52
  const lastUrlUpdate = useRef(null);
53
53
  // Track if onSuccess has been called for the current order
54
54
  const onSuccessCalled = useRef(false);
55
+ // Track animation direction for TransitionPanel
56
+ const animationDirection = useRef(null);
57
+ // Track previous panel for proper back navigation
58
+ const previousPanel = useRef(PanelView.MAIN);
55
59
  const [activeTab, setActiveTab] = useState(defaultActiveTab);
56
60
  const [orderId, setOrderId] = useState(loadOrder);
57
61
  const { orderAndTransactions: oat, getOrderAndTransactionsError } = useAnyspendOrderAndTransactions(orderId);
58
62
  !!getOrderAndTransactionsError && console.log("getOrderAndTransactionsError", getOrderAndTransactionsError);
59
63
  const [activePanel, setActivePanel] = useState(loadOrder ? PanelView.ORDER_DETAILS : PanelView.MAIN);
64
+ // Helper functions to navigate with animation direction
65
+ const navigateToPanel = useCallback((panel, direction = "forward") => {
66
+ previousPanel.current = activePanel;
67
+ animationDirection.current = direction;
68
+ setActivePanel(panel);
69
+ }, [activePanel]);
70
+ const navigateBack = useCallback(() => {
71
+ animationDirection.current = "back";
72
+ // Navigate back to previous panel or default to MAIN
73
+ const targetPanel = previousPanel.current !== activePanel ? previousPanel.current : PanelView.MAIN;
74
+ setActivePanel(targetPanel);
75
+ }, [activePanel]);
60
76
  const [customRecipients, setCustomRecipients] = useState([]);
61
77
  // Add state for selected payment method
62
78
  const [selectedCryptoPaymentMethod, setSelectedCryptoPaymentMethod] = useState(CryptoPaymentMethodType.NONE);
@@ -405,7 +421,7 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
405
421
  const orderId = data.data.id;
406
422
  setOrderId(orderId);
407
423
  // setNewRecipientAddress("");
408
- setActivePanel(PanelView.ORDER_DETAILS);
424
+ navigateToPanel(PanelView.ORDER_DETAILS, "forward");
409
425
  // Debug: Check payment method before setting URL
410
426
  console.log("Creating order - selectedCryptoPaymentMethod:", selectedCryptoPaymentMethod);
411
427
  // Add orderId and payment method to URL for persistence
@@ -431,7 +447,7 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
431
447
  onSuccess: data => {
432
448
  const orderId = data.data.id;
433
449
  setOrderId(orderId);
434
- setActivePanel(PanelView.ORDER_DETAILS);
450
+ navigateToPanel(PanelView.ORDER_DETAILS, "forward");
435
451
  // Add orderId and payment method to URL for persistence
436
452
  const params = new URLSearchParams(searchParams.toString());
437
453
  params.set("orderId", orderId);
@@ -494,7 +510,7 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
494
510
  if (btnInfo.disable)
495
511
  return;
496
512
  if (!recipientAddress) {
497
- setActivePanel(PanelView.RECIPIENT_SELECTION);
513
+ navigateToPanel(PanelView.RECIPIENT_SELECTION, "forward");
498
514
  return;
499
515
  }
500
516
  try {
@@ -503,7 +519,7 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
503
519
  if (activeTab === "fiat") {
504
520
  // If no fiat payment method selected, show payment method selection
505
521
  if (selectedFiatPaymentMethod === FiatPaymentMethod.NONE) {
506
- setActivePanel(PanelView.FIAT_PAYMENT_METHOD);
522
+ navigateToPanel(PanelView.FIAT_PAYMENT_METHOD, "forward");
507
523
  return;
508
524
  }
509
525
  // If payment method is selected, create order directly
@@ -514,7 +530,7 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
514
530
  // If no payment method selected, show payment method selection
515
531
  if (selectedCryptoPaymentMethod === CryptoPaymentMethodType.NONE) {
516
532
  console.log("No payment method selected, showing selection panel");
517
- setActivePanel(PanelView.CRYPTO_PAYMENT_METHOD);
533
+ navigateToPanel(PanelView.CRYPTO_PAYMENT_METHOD, "forward");
518
534
  return;
519
535
  }
520
536
  // If payment method is selected, create order with payment method info
@@ -534,7 +550,7 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
534
550
  };
535
551
  const onClickHistory = () => {
536
552
  setOrderId(undefined);
537
- setActivePanel(PanelView.HISTORY);
553
+ navigateToPanel(PanelView.HISTORY, "forward");
538
554
  // Remove orderId and paymentMethod from URL when going back to history
539
555
  const params = new URLSearchParams(searchParams.toString());
540
556
  params.delete("orderId");
@@ -647,8 +663,8 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
647
663
  }
648
664
  }, [searchParams, loadOrder]);
649
665
  const onSelectOrder = (selectedOrderId) => {
650
- setActivePanel(PanelView.MAIN);
651
666
  setOrderId(selectedOrderId);
667
+ navigateToPanel(PanelView.ORDER_DETAILS, "forward");
652
668
  // Update URL with the new orderId and preserve existing parameters
653
669
  const params = new URLSearchParams(searchParams.toString());
654
670
  params.set("orderId", selectedOrderId);
@@ -668,13 +684,49 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
668
684
  useEffect(() => {
669
685
  window.scrollTo({ top: 0, behavior: "smooth" });
670
686
  }, [activePanel]);
671
- const historyView = (_jsx("div", { className: "mx-auto flex w-[560px] max-w-full flex-col items-center", children: _jsx(OrderHistory, { mode: mode, onBack: () => setActivePanel(PanelView.MAIN), onSelectOrder: onSelectOrder }) }));
687
+ // Handle browser back button for recipient selection and payment method views
688
+ useEffect(() => {
689
+ // Push a new history state when navigating to specific panels
690
+ if (activePanel === PanelView.RECIPIENT_SELECTION) {
691
+ window.history.pushState({ panel: "recipient-selection" }, "");
692
+ }
693
+ else if (activePanel === PanelView.CRYPTO_PAYMENT_METHOD) {
694
+ window.history.pushState({ panel: "crypto-payment-method" }, "");
695
+ }
696
+ else if (activePanel === PanelView.FIAT_PAYMENT_METHOD) {
697
+ window.history.pushState({ panel: "fiat-payment-method" }, "");
698
+ }
699
+ // Listen for popstate event (browser back button)
700
+ const handlePopState = (event) => {
701
+ if (activePanel === PanelView.RECIPIENT_SELECTION ||
702
+ activePanel === PanelView.CRYPTO_PAYMENT_METHOD ||
703
+ activePanel === PanelView.FIAT_PAYMENT_METHOD) {
704
+ // User pressed back while on these panels
705
+ event.preventDefault();
706
+ navigateBack();
707
+ }
708
+ };
709
+ window.addEventListener("popstate", handlePopState);
710
+ return () => {
711
+ window.removeEventListener("popstate", handlePopState);
712
+ };
713
+ }, [activePanel, navigateBack]);
714
+ const historyView = (_jsx("div", { className: "mx-auto flex w-[560px] max-w-full flex-col items-center", children: _jsx(OrderHistory, { mode: mode, onBack: navigateBack, onSelectOrder: onSelectOrder }) }));
672
715
  const orderDetailsView = (_jsx("div", { className: "mx-auto w-[460px] max-w-full", children: _jsx("div", { className: "relative flex flex-col gap-4", children: oat && (_jsx(OrderDetails, { mode: mode, order: oat.data.order, depositTxs: oat.data.depositTxs, relayTxs: oat.data.relayTxs, executeTx: oat.data.executeTx, refundTxs: oat.data.refundTxs, selectedCryptoPaymentMethod: selectedCryptoPaymentMethod, onPaymentMethodChange: setSelectedCryptoPaymentMethod, onBack: () => {
673
716
  setOrderId(undefined);
674
- setActivePanel(PanelView.MAIN);
717
+ navigateBack();
675
718
  setSelectedCryptoPaymentMethod(CryptoPaymentMethodType.NONE); // Reset payment method when going back
676
719
  } })) }) }));
677
- const mainView = (_jsxs("div", { className: "mx-auto flex w-[460px] max-w-full flex-col items-center gap-2", children: [isBuyMode && (_jsxs("div", { className: "mb-4 flex flex-col items-center gap-3 text-center", children: [selectedDstToken.metadata?.logoURI && (_jsx("div", { className: "relative", children: _jsx("img", { src: selectedDstToken.metadata.logoURI, alt: selectedDstToken.symbol, className: "border-as-stroke h-12 w-12 rounded-full border-2 shadow-md" }) })), _jsx("div", { children: _jsxs("h1", { className: "text-as-primary text-xl font-bold", children: ["Buy ", selectedDstToken.symbol] }) })] })), _jsx(TabSection, { activeTab: activeTab, setActiveTab: setActiveTab, setSelectedCryptoPaymentMethod: setSelectedCryptoPaymentMethod, setSelectedFiatPaymentMethod: setSelectedFiatPaymentMethod }), _jsxs("div", { className: "relative flex w-full max-w-[calc(100vw-32px)] flex-col gap-2", children: [activeTab === "crypto" ? (_jsx(CryptoPaySection, { selectedSrcChainId: selectedSrcChainId, setSelectedSrcChainId: setSelectedSrcChainId, selectedSrcToken: selectedSrcToken, setSelectedSrcToken: setSelectedSrcToken, srcAmount: srcAmount, setSrcAmount: setSrcAmount, setIsSrcInputDirty: setIsSrcInputDirty, selectedCryptoPaymentMethod: selectedCryptoPaymentMethod, onSelectCryptoPaymentMethod: () => setActivePanel(PanelView.CRYPTO_PAYMENT_METHOD), anyspendQuote: anyspendQuote, onTokenSelect: onTokenSelect })) : (_jsx(motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0, ease: "easeInOut" }, children: _jsx(PanelOnramp, { srcAmountOnRamp: srcAmountOnRamp, setSrcAmountOnRamp: setSrcAmountOnRamp, selectedPaymentMethod: selectedFiatPaymentMethod, setActivePanel: setActivePanel, _recipientAddress: recipientAddress, destinationToken: selectedDstToken, destinationChainId: selectedDstChainId, destinationAmount: dstAmount, onDestinationTokenChange: setSelectedDstToken, onDestinationChainChange: setSelectedDstChainId, fiatPaymentMethodIndex: PanelView.FIAT_PAYMENT_METHOD, recipientSelectionPanelIndex: PanelView.RECIPIENT_SELECTION, hideDstToken: isBuyMode, anyspendQuote: anyspendQuote, onShowPointsDetail: () => setActivePanel(PanelView.POINTS_DETAIL), customUsdInputValues: customUsdInputValues }) })), _jsx(Button, { variant: "ghost", className: cn("border-as-stroke bg-as-surface-primary absolute left-1/2 top-1/2 z-10 h-10 w-10 -translate-x-1/2 -translate-y-1/2 rounded-xl border-2 sm:h-8 sm:w-8 sm:rounded-xl", isBuyMode && "top-[calc(50%+56px)] cursor-default", activeTab === "fiat" && "hidden"), onClick: () => {
720
+ const mainView = (_jsxs("div", { className: "mx-auto flex w-[460px] max-w-full flex-col items-center gap-2", children: [isBuyMode && (_jsxs("div", { className: "mb-4 flex flex-col items-center gap-3 text-center", children: [selectedDstToken.metadata?.logoURI && (_jsx("div", { className: "relative", children: _jsx("img", { src: selectedDstToken.metadata.logoURI, alt: selectedDstToken.symbol, className: "border-as-stroke h-12 w-12 rounded-full border-2 shadow-md" }) })), _jsx("div", { children: _jsxs("h1", { className: "text-as-primary text-xl font-bold", children: ["Buy ", selectedDstToken.symbol] }) })] })), _jsx(TabSection, { activeTab: activeTab, setActiveTab: setActiveTab, setSelectedCryptoPaymentMethod: setSelectedCryptoPaymentMethod, setSelectedFiatPaymentMethod: setSelectedFiatPaymentMethod }), _jsxs("div", { className: "relative flex w-full max-w-[calc(100vw-32px)] flex-col gap-2", children: [activeTab === "crypto" ? (_jsx(CryptoPaySection, { selectedSrcChainId: selectedSrcChainId, setSelectedSrcChainId: setSelectedSrcChainId, selectedSrcToken: selectedSrcToken, setSelectedSrcToken: setSelectedSrcToken, srcAmount: srcAmount, setSrcAmount: setSrcAmount, setIsSrcInputDirty: setIsSrcInputDirty, selectedCryptoPaymentMethod: selectedCryptoPaymentMethod, onSelectCryptoPaymentMethod: () => navigateToPanel(PanelView.CRYPTO_PAYMENT_METHOD, "forward"), anyspendQuote: anyspendQuote, onTokenSelect: onTokenSelect })) : (_jsx(motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0, ease: "easeInOut" }, children: _jsx(PanelOnramp, { srcAmountOnRamp: srcAmountOnRamp, setSrcAmountOnRamp: setSrcAmountOnRamp, selectedPaymentMethod: selectedFiatPaymentMethod, setActivePanel: (panelIndex) => {
721
+ // Map panel index to navigation with direction
722
+ const panelsWithForwardNav = [PanelView.FIAT_PAYMENT_METHOD, PanelView.RECIPIENT_SELECTION];
723
+ if (panelsWithForwardNav.includes(panelIndex)) {
724
+ navigateToPanel(panelIndex, "forward");
725
+ }
726
+ else {
727
+ setActivePanel(panelIndex);
728
+ }
729
+ }, _recipientAddress: recipientAddress, destinationToken: selectedDstToken, destinationChainId: selectedDstChainId, destinationAmount: dstAmount, onDestinationTokenChange: setSelectedDstToken, onDestinationChainChange: setSelectedDstChainId, fiatPaymentMethodIndex: PanelView.FIAT_PAYMENT_METHOD, recipientSelectionPanelIndex: PanelView.RECIPIENT_SELECTION, hideDstToken: isBuyMode, anyspendQuote: anyspendQuote, onShowPointsDetail: () => navigateToPanel(PanelView.POINTS_DETAIL, "forward"), customUsdInputValues: customUsdInputValues }) })), _jsx(Button, { variant: "ghost", className: cn("border-as-stroke bg-as-surface-primary absolute left-1/2 top-1/2 z-10 h-10 w-10 -translate-x-1/2 -translate-y-1/2 rounded-xl border-2 sm:h-8 sm:w-8 sm:rounded-xl", isBuyMode && "top-[calc(50%+56px)] cursor-default", activeTab === "fiat" && "hidden"), onClick: () => {
678
730
  if (activeTab === "fiat" || isBuyMode) {
679
731
  return;
680
732
  }
@@ -693,13 +745,13 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
693
745
  const tempDstAmount = dstAmount;
694
746
  setSrcAmount(tempDstAmount);
695
747
  setDstAmount(tempSrcAmount);
696
- }, children: _jsx("div", { className: "relative flex items-center justify-center transition-opacity", children: _jsx(ArrowDown, { className: "text-as-primary/50 h-5 w-5" }) }) }), activeTab === "crypto" && (_jsx(CryptoReceiveSection, { isDepositMode: false, isBuyMode: isBuyMode, selectedRecipientAddress: recipientAddress, recipientName: recipientName || undefined, onSelectRecipient: () => setActivePanel(PanelView.RECIPIENT_SELECTION), dstAmount: dstAmount, dstToken: selectedDstToken, selectedDstChainId: selectedDstChainId, setSelectedDstChainId: setSelectedDstChainId, setSelectedDstToken: setSelectedDstToken, onChangeDstAmount: value => {
748
+ }, children: _jsx("div", { className: "relative flex items-center justify-center transition-opacity", children: _jsx(ArrowDown, { className: "text-as-primary/50 h-5 w-5" }) }) }), activeTab === "crypto" && (_jsx(CryptoReceiveSection, { isDepositMode: false, isBuyMode: isBuyMode, selectedRecipientAddress: recipientAddress, recipientName: recipientName || undefined, onSelectRecipient: () => navigateToPanel(PanelView.RECIPIENT_SELECTION, "forward"), dstAmount: dstAmount, dstToken: selectedDstToken, selectedDstChainId: selectedDstChainId, setSelectedDstChainId: setSelectedDstChainId, setSelectedDstToken: setSelectedDstToken, onChangeDstAmount: value => {
697
749
  setIsSrcInputDirty(false);
698
750
  setDstAmount(value);
699
- }, anyspendQuote: anyspendQuote, onShowPointsDetail: () => setActivePanel(PanelView.POINTS_DETAIL) }))] }), _jsx(ErrorSection, { error: getAnyspendQuoteError }), _jsxs(motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0.2, ease: "easeInOut" }, className: cn("mt-4 flex w-full max-w-[460px] flex-col gap-2", getAnyspendQuoteError && "mt-0"), children: [_jsx(ShinyButton, { accentColor: "hsl(var(--as-brand))", disabled: btnInfo.disable, onClick: onMainButtonClick, className: cn("as-main-button relative w-full", btnInfo.error ? "!bg-as-red" : btnInfo.disable ? "!bg-as-on-surface-2" : "!bg-as-brand"), textClassName: cn(btnInfo.error ? "text-white" : btnInfo.disable ? "text-as-secondary" : "text-white"), children: btnInfo.text }), !hideTransactionHistoryButton && (globalAddress || recipientAddress) ? (_jsxs(Button, { variant: "link", onClick: onClickHistory, className: "text-as-primary/50 hover:text-as-primary flex items-center gap-1 transition-colors", children: [_jsx(HistoryIcon, { className: "h-4 w-4" }), " ", _jsx("span", { className: "pr-4", children: "Transaction History" })] })) : null] })] }));
751
+ }, anyspendQuote: anyspendQuote, onShowPointsDetail: () => navigateToPanel(PanelView.POINTS_DETAIL, "forward") }))] }), _jsx(ErrorSection, { error: getAnyspendQuoteError }), _jsxs(motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0.2, ease: "easeInOut" }, className: cn("mt-4 flex w-full max-w-[460px] flex-col gap-2", getAnyspendQuoteError && "mt-0"), children: [_jsx(ShinyButton, { accentColor: "hsl(var(--as-brand))", disabled: btnInfo.disable, onClick: onMainButtonClick, className: cn("as-main-button relative w-full", btnInfo.error ? "!bg-as-red" : btnInfo.disable ? "!bg-as-on-surface-2" : "!bg-as-brand"), textClassName: cn(btnInfo.error ? "text-white" : btnInfo.disable ? "text-as-secondary" : "text-white"), children: btnInfo.text }), !hideTransactionHistoryButton && (globalAddress || recipientAddress) ? (_jsxs(Button, { variant: "link", onClick: onClickHistory, className: "text-as-primary/50 hover:text-as-primary flex items-center gap-1 transition-colors", children: [_jsx(HistoryIcon, { className: "h-4 w-4" }), " ", _jsx("span", { className: "pr-4", children: "Transaction History" })] })) : null] })] }));
700
752
  const onrampPaymentView = (_jsx(PanelOnrampPayment, { srcAmountOnRamp: srcAmountOnRamp, recipientName: recipientName || undefined, recipientAddress: recipientAddress, isBuyMode: isBuyMode, destinationTokenChainId: destinationTokenChainId, destinationTokenAddress: destinationTokenAddress, selectedDstChainId: selectedDstChainId, selectedDstToken: selectedDstToken, orderType: "swap", anyspendQuote: anyspendQuote, globalAddress: globalAddress, onOrderCreated: orderId => {
701
753
  setOrderId(orderId);
702
- setActivePanel(PanelView.ORDER_DETAILS);
754
+ navigateToPanel(PanelView.ORDER_DETAILS, "forward");
703
755
  // Add orderId and payment method to URL for persistence
704
756
  const params = new URLSearchParams(searchParams.toString()); // Preserve existing params
705
757
  params.set("orderId", orderId);
@@ -711,20 +763,20 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
711
763
  params.set("paymentMethod", selectedCryptoPaymentMethod);
712
764
  }
713
765
  router.push(`${window.location.pathname}?${params.toString()}`);
714
- }, onBack: () => setActivePanel(PanelView.MAIN), recipientEnsName: globalWallet?.ensName, recipientImageUrl: globalWallet?.meta?.icon }));
715
- const recipientSelectionView = (_jsx(RecipientSelection, { initialValue: recipientAddress || "", onBack: () => setActivePanel(PanelView.MAIN), onConfirm: address => {
766
+ }, onBack: navigateBack, recipientEnsName: globalWallet?.ensName, recipientImageUrl: globalWallet?.meta?.icon }));
767
+ const recipientSelectionView = (_jsx(RecipientSelection, { initialValue: recipientAddress || "", onBack: navigateBack, onConfirm: address => {
716
768
  setRecipientAddress(address);
717
- setActivePanel(PanelView.MAIN);
769
+ navigateBack();
718
770
  } }));
719
- const cryptoPaymentMethodView = (_jsx(CryptoPaymentMethod, { globalAddress: globalAddress, globalWallet: globalWallet, selectedPaymentMethod: selectedCryptoPaymentMethod, setSelectedPaymentMethod: setSelectedCryptoPaymentMethod, isCreatingOrder: isCreatingOrder, onBack: () => setActivePanel(PanelView.MAIN), onSelectPaymentMethod: (method) => {
771
+ const cryptoPaymentMethodView = (_jsx(CryptoPaymentMethod, { globalAddress: globalAddress, globalWallet: globalWallet, selectedPaymentMethod: selectedCryptoPaymentMethod, setSelectedPaymentMethod: setSelectedCryptoPaymentMethod, isCreatingOrder: isCreatingOrder, onBack: navigateBack, onSelectPaymentMethod: (method) => {
720
772
  setSelectedCryptoPaymentMethod(method);
721
- setActivePanel(PanelView.MAIN);
773
+ navigateBack();
722
774
  } }));
723
- const fiatPaymentMethodView = (_jsx(FiatPaymentMethodComponent, { selectedPaymentMethod: selectedFiatPaymentMethod, setSelectedPaymentMethod: setSelectedFiatPaymentMethod, onBack: () => setActivePanel(PanelView.MAIN), onSelectPaymentMethod: (method) => {
775
+ const fiatPaymentMethodView = (_jsx(FiatPaymentMethodComponent, { selectedPaymentMethod: selectedFiatPaymentMethod, setSelectedPaymentMethod: setSelectedFiatPaymentMethod, onBack: navigateBack, onSelectPaymentMethod: (method) => {
724
776
  setSelectedFiatPaymentMethod(method);
725
- setActivePanel(PanelView.MAIN); // Go back to main panel to show updated pricing
777
+ navigateBack(); // Go back to main panel to show updated pricing
726
778
  }, srcAmountOnRamp: srcAmountOnRamp }));
727
- const pointsDetailView = (_jsx(PointsDetailPanel, { pointsAmount: anyspendQuote?.data?.pointsAmount || 0, onBack: () => setActivePanel(PanelView.MAIN) }));
779
+ const pointsDetailView = (_jsx(PointsDetailPanel, { pointsAmount: anyspendQuote?.data?.pointsAmount || 0, onBack: navigateBack }));
728
780
  // Add tabs to the main component when no order is loaded
729
781
  return (_jsx(StyleRoot, { children: _jsx("div", { className: cn("anyspend-container font-inter mx-auto w-full max-w-[460px]", mode === "page" &&
730
782
  "bg-as-surface-primary border-as-border-secondary overflow-hidden rounded-2xl border shadow-xl"), children: _jsx(TransitionPanel, { activeIndex: orderId
@@ -735,10 +787,16 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
735
787
  ? PanelView.MAIN
736
788
  : activePanel, className: cn("rounded-2xl", {
737
789
  "mt-0": mode === "modal",
738
- }), variants: {
739
- enter: { x: 300, opacity: 0 },
790
+ }), custom: animationDirection.current, variants: {
791
+ enter: direction => ({
792
+ x: direction === "back" ? -300 : 300,
793
+ opacity: 0,
794
+ }),
740
795
  center: { x: 0, opacity: 1 },
741
- exit: { x: -300, opacity: 0 },
796
+ exit: direction => ({
797
+ x: direction === "back" ? 300 : -300,
798
+ opacity: 0,
799
+ }),
742
800
  }, transition: { type: "spring", stiffness: 300, damping: 30 }, children: [
743
801
  _jsx("div", { className: cn(mode === "page" && "p-6"), children: mainView }, "main-view"),
744
802
  _jsx("div", { className: cn(mode === "page" && "p-6"), children: historyView }, "history-view"),
@@ -481,7 +481,7 @@ export const OrderDetails = memo(function OrderDetails({ mode = "modal", order,
481
481
  ? "Funding Tournament"
482
482
  : "Processing Transaction", chainId: order.srcChain, tx: null, isProcessing: true, delay: 0.5 })) : (_jsx(TransactionDetails, { title: order.onrampMetadata?.vendor === "stripe-web2"
483
483
  ? `Waiting for payment`
484
- : `Waiting for deposit ${formattedDepositDeficit} ${srcToken.symbol}`, chainId: order.srcChain, tx: null, isProcessing: true, delay: 0.5 }))] }) })] }) }), !depositEnoughAmount && order.status !== "expired" && (_jsx(InsufficientDepositPayment, { order: order, srcToken: srcToken, depositDeficit: depositDeficit, phantomWalletAddress: phantomWalletAddress, txLoading: txLoading, isSwitchingOrExecuting: isSwitchingOrExecuting, onPayment: handlePayment }))] }));
484
+ : `Waiting for deposit ${formattedDepositDeficit} ${srcToken.symbol}`, chainId: order.srcChain, tx: null, isProcessing: true, delay: 0.5 }))] }) })] }) }), depositTxs?.length > 0 && !depositEnoughAmount && order.status === "scanning_deposit_transaction" && (_jsx(InsufficientDepositPayment, { order: order, srcToken: srcToken, depositDeficit: depositDeficit, phantomWalletAddress: phantomWalletAddress, txLoading: txLoading, isSwitchingOrExecuting: isSwitchingOrExecuting, onPayment: handlePayment }))] }));
485
485
  }
486
486
  return (_jsxs(_Fragment, { children: [_jsx(OrderStatus, { order: order, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod }), statusDisplay === "processing" && (_jsx(_Fragment, { children: order.onrampMetadata ? (_jsx(PaymentVendorUI, { order: order, dstTokenSymbol: dstToken.symbol })) : effectiveCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET ||
487
487
  effectiveCryptoPaymentMethod === CryptoPaymentMethodType.GLOBAL_WALLET ? (_jsx(ConnectWalletPayment, { order: order, onPayment: handlePayment, onCancel: handleBack, txLoading: txLoading, isSwitchingOrExecuting: isSwitchingOrExecuting, phantomWalletAddress: phantomWalletAddress, tournament: tournament, nft: nft, cryptoPaymentMethod: effectiveCryptoPaymentMethod, onPaymentMethodChange: onPaymentMethodChange })) : effectiveCryptoPaymentMethod === CryptoPaymentMethodType.TRANSFER_CRYPTO ? (
@@ -12,6 +12,7 @@ export declare function useAnyspendOrderHistory(creatorAddress: string | undefin
12
12
  errorDetails: string | null;
13
13
  createdAt: number;
14
14
  expiredAt: number;
15
+ filledAt: number | null;
15
16
  creatorAddress: string | null;
16
17
  partnerId: string | null;
17
18
  onrampMetadata: import("../..").components["schemas"]["OnrampMetadata"] | null;
@@ -34,6 +35,7 @@ export declare function useAnyspendOrderHistory(creatorAddress: string | undefin
34
35
  errorDetails: string | null;
35
36
  createdAt: number;
36
37
  expiredAt: number;
38
+ filledAt: number | null;
37
39
  creatorAddress: string | null;
38
40
  partnerId: string | null;
39
41
  onrampMetadata: import("../..").components["schemas"]["OnrampMetadata"] | null;
@@ -56,6 +58,7 @@ export declare function useAnyspendOrderHistory(creatorAddress: string | undefin
56
58
  errorDetails: string | null;
57
59
  createdAt: number;
58
60
  expiredAt: number;
61
+ filledAt: number | null;
59
62
  creatorAddress: string | null;
60
63
  partnerId: string | null;
61
64
  onrampMetadata: import("../..").components["schemas"]["OnrampMetadata"] | null;
@@ -78,6 +81,7 @@ export declare function useAnyspendOrderHistory(creatorAddress: string | undefin
78
81
  errorDetails: string | null;
79
82
  createdAt: number;
80
83
  expiredAt: number;
84
+ filledAt: number | null;
81
85
  creatorAddress: string | null;
82
86
  partnerId: string | null;
83
87
  onrampMetadata: import("../..").components["schemas"]["OnrampMetadata"] | null;
@@ -100,6 +104,7 @@ export declare function useAnyspendOrderHistory(creatorAddress: string | undefin
100
104
  errorDetails: string | null;
101
105
  createdAt: number;
102
106
  expiredAt: number;
107
+ filledAt: number | null;
103
108
  creatorAddress: string | null;
104
109
  partnerId: string | null;
105
110
  onrampMetadata: import("../..").components["schemas"]["OnrampMetadata"] | null;
@@ -122,6 +127,7 @@ export declare function useAnyspendOrderHistory(creatorAddress: string | undefin
122
127
  errorDetails: string | null;
123
128
  createdAt: number;
124
129
  expiredAt: number;
130
+ filledAt: number | null;
125
131
  creatorAddress: string | null;
126
132
  partnerId: string | null;
127
133
  onrampMetadata: import("../..").components["schemas"]["OnrampMetadata"] | null;
@@ -147,6 +153,7 @@ export declare function useAnyspendOrderHistory(creatorAddress: string | undefin
147
153
  errorDetails: string | null;
148
154
  createdAt: number;
149
155
  expiredAt: number;
156
+ filledAt: number | null;
150
157
  creatorAddress: string | null;
151
158
  partnerId: string | null;
152
159
  onrampMetadata: import("../..").components["schemas"]["OnrampMetadata"] | null;
@@ -169,6 +176,7 @@ export declare function useAnyspendOrderHistory(creatorAddress: string | undefin
169
176
  errorDetails: string | null;
170
177
  createdAt: number;
171
178
  expiredAt: number;
179
+ filledAt: number | null;
172
180
  creatorAddress: string | null;
173
181
  partnerId: string | null;
174
182
  onrampMetadata: import("../..").components["schemas"]["OnrampMetadata"] | null;
@@ -191,6 +199,7 @@ export declare function useAnyspendOrderHistory(creatorAddress: string | undefin
191
199
  errorDetails: string | null;
192
200
  createdAt: number;
193
201
  expiredAt: number;
202
+ filledAt: number | null;
194
203
  creatorAddress: string | null;
195
204
  partnerId: string | null;
196
205
  onrampMetadata: import("../..").components["schemas"]["OnrampMetadata"] | null;
@@ -213,6 +222,7 @@ export declare function useAnyspendOrderHistory(creatorAddress: string | undefin
213
222
  errorDetails: string | null;
214
223
  createdAt: number;
215
224
  expiredAt: number;
225
+ filledAt: number | null;
216
226
  creatorAddress: string | null;
217
227
  partnerId: string | null;
218
228
  onrampMetadata: import("../..").components["schemas"]["OnrampMetadata"] | null;
@@ -235,6 +245,7 @@ export declare function useAnyspendOrderHistory(creatorAddress: string | undefin
235
245
  errorDetails: string | null;
236
246
  createdAt: number;
237
247
  expiredAt: number;
248
+ filledAt: number | null;
238
249
  creatorAddress: string | null;
239
250
  partnerId: string | null;
240
251
  onrampMetadata: import("../..").components["schemas"]["OnrampMetadata"] | null;
@@ -257,6 +268,7 @@ export declare function useAnyspendOrderHistory(creatorAddress: string | undefin
257
268
  errorDetails: string | null;
258
269
  createdAt: number;
259
270
  expiredAt: number;
271
+ filledAt: number | null;
260
272
  creatorAddress: string | null;
261
273
  partnerId: string | null;
262
274
  onrampMetadata: import("../..").components["schemas"]["OnrampMetadata"] | null;
@@ -1117,11 +1117,6 @@ export interface components {
1117
1117
  * @example 990000
1118
1118
  */
1119
1119
  actualDstAmount: string | null;
1120
- /**
1121
- * @description Amount in after fee
1122
- * @example 990000
1123
- */
1124
- amountInAfterFee: string | null;
1125
1120
  };
1126
1121
  /** @description HypeDuel-specific payload */
1127
1122
  HypeDuelPayload: {
@@ -1135,11 +1130,6 @@ export interface components {
1135
1130
  * @example 990000
1136
1131
  */
1137
1132
  actualDstAmount: string | null;
1138
- /**
1139
- * @description Amount in after fee
1140
- * @example 990000
1141
- */
1142
- amountInAfterFee: string | null;
1143
1133
  };
1144
1134
  /** @description Custom execution payload */
1145
1135
  CustomPayload: {
@@ -1307,6 +1297,8 @@ export interface components {
1307
1297
  * @example 1752506694679
1308
1298
  */
1309
1299
  expiredAt: number;
1300
+ /** @description Timestamp when the order was filled/executed */
1301
+ filledAt: number | null;
1310
1302
  /**
1311
1303
  * @description Optional creator address
1312
1304
  * @example 0xb34facb90a200251318e8841c05102366f2158cf
@@ -20,7 +20,7 @@ export declare function useCurrencyConversion(): {
20
20
  /** Base currency used for conversion (typically B3) */
21
21
  baseCurrency: import("../stores/currencyStore").SupportedCurrency;
22
22
  /** Current exchange rate from base to selected currency (undefined while loading) */
23
- exchangeRate: number;
23
+ exchangeRate: number | undefined;
24
24
  /** Format a value with currency conversion and proper symbol/decimal handling */
25
25
  formatCurrencyValue: (value: number, options?: {
26
26
  decimals?: number;
@@ -1,6 +1,23 @@
1
- import { useExchangeRate } from "../../../global-account/react/index.js";
1
+ import { useQuery } from "@tanstack/react-query";
2
2
  import { formatDisplayNumber } from "../../../shared/utils/number.js";
3
3
  import { CURRENCY_SYMBOLS, useCurrencyStore } from "../stores/currencyStore.js";
4
+ const COINBASE_API_URL = "https://api.coinbase.com/v2/exchange-rates";
5
+ const REFETCH_INTERVAL_MS = 30000;
6
+ /**
7
+ * Fetches all exchange rates for a given base currency from Coinbase API.
8
+ */
9
+ async function fetchAllExchangeRates(baseCurrency) {
10
+ const response = await fetch(`${COINBASE_API_URL}?currency=${baseCurrency}`);
11
+ if (!response.ok) {
12
+ throw new Error(`Failed to fetch exchange rates for ${baseCurrency}: ${response.status}`);
13
+ }
14
+ const data = await response.json();
15
+ const rates = {};
16
+ for (const [currency, rate] of Object.entries(data.data.rates)) {
17
+ rates[currency] = parseFloat(rate);
18
+ }
19
+ return rates;
20
+ }
4
21
  /**
5
22
  * Hook for currency conversion and formatting with real-time exchange rates.
6
23
  *
@@ -20,16 +37,18 @@ import { CURRENCY_SYMBOLS, useCurrencyStore } from "../stores/currencyStore.js";
20
37
  export function useCurrencyConversion() {
21
38
  const selectedCurrency = useCurrencyStore(state => state.selectedCurrency);
22
39
  const baseCurrency = useCurrencyStore(state => state.baseCurrency);
23
- // Get exchange rate for the selected currency
24
- const { rate: exchangeRate } = useExchangeRate({
25
- baseCurrency,
26
- quoteCurrency: selectedCurrency === baseCurrency ? "USD" : selectedCurrency,
27
- });
28
- // Always fetch USD rate for tooltip purposes
29
- const { rate: usdRate } = useExchangeRate({
30
- baseCurrency,
31
- quoteCurrency: "USD",
40
+ // Fetch all exchange rates for the base currency
41
+ const { data: exchangeRates } = useQuery({
42
+ queryKey: ["exchangeRates", baseCurrency],
43
+ queryFn: () => fetchAllExchangeRates(baseCurrency),
44
+ refetchInterval: REFETCH_INTERVAL_MS,
45
+ staleTime: REFETCH_INTERVAL_MS / 2,
46
+ retry: 3,
47
+ retryDelay: attemptIndex => Math.min(1000 * 2 ** attemptIndex, REFETCH_INTERVAL_MS),
32
48
  });
49
+ // Extract specific rates from the full rates object
50
+ const exchangeRate = exchangeRates?.[selectedCurrency];
51
+ const usdRate = exchangeRates?.["USD"];
33
52
  /**
34
53
  * Formats a numeric value as a currency string with proper conversion and formatting.
35
54
  *
@@ -75,8 +94,7 @@ export function useCurrencyConversion() {
75
94
  });
76
95
  return `${formatted} ${baseCurrency}`;
77
96
  }
78
- // If no exchange rate available, show base currency to prevent showing
79
- // incorrect values with wrong currency symbols during rate fetching
97
+ // If showing base currency, no conversion needed
80
98
  if (selectedCurrency === baseCurrency || !exchangeRate) {
81
99
  const formatted = formatDisplayNumber(value, {
82
100
  significantDigits: baseCurrency === "B3" ? 6 : 8,
@@ -12,6 +12,7 @@ export declare function useAnyspendOrderHistory(creatorAddress: string | undefin
12
12
  errorDetails: string | null;
13
13
  createdAt: number;
14
14
  expiredAt: number;
15
+ filledAt: number | null;
15
16
  creatorAddress: string | null;
16
17
  partnerId: string | null;
17
18
  onrampMetadata: import("../..").components["schemas"]["OnrampMetadata"] | null;
@@ -34,6 +35,7 @@ export declare function useAnyspendOrderHistory(creatorAddress: string | undefin
34
35
  errorDetails: string | null;
35
36
  createdAt: number;
36
37
  expiredAt: number;
38
+ filledAt: number | null;
37
39
  creatorAddress: string | null;
38
40
  partnerId: string | null;
39
41
  onrampMetadata: import("../..").components["schemas"]["OnrampMetadata"] | null;
@@ -56,6 +58,7 @@ export declare function useAnyspendOrderHistory(creatorAddress: string | undefin
56
58
  errorDetails: string | null;
57
59
  createdAt: number;
58
60
  expiredAt: number;
61
+ filledAt: number | null;
59
62
  creatorAddress: string | null;
60
63
  partnerId: string | null;
61
64
  onrampMetadata: import("../..").components["schemas"]["OnrampMetadata"] | null;
@@ -78,6 +81,7 @@ export declare function useAnyspendOrderHistory(creatorAddress: string | undefin
78
81
  errorDetails: string | null;
79
82
  createdAt: number;
80
83
  expiredAt: number;
84
+ filledAt: number | null;
81
85
  creatorAddress: string | null;
82
86
  partnerId: string | null;
83
87
  onrampMetadata: import("../..").components["schemas"]["OnrampMetadata"] | null;
@@ -100,6 +104,7 @@ export declare function useAnyspendOrderHistory(creatorAddress: string | undefin
100
104
  errorDetails: string | null;
101
105
  createdAt: number;
102
106
  expiredAt: number;
107
+ filledAt: number | null;
103
108
  creatorAddress: string | null;
104
109
  partnerId: string | null;
105
110
  onrampMetadata: import("../..").components["schemas"]["OnrampMetadata"] | null;
@@ -122,6 +127,7 @@ export declare function useAnyspendOrderHistory(creatorAddress: string | undefin
122
127
  errorDetails: string | null;
123
128
  createdAt: number;
124
129
  expiredAt: number;
130
+ filledAt: number | null;
125
131
  creatorAddress: string | null;
126
132
  partnerId: string | null;
127
133
  onrampMetadata: import("../..").components["schemas"]["OnrampMetadata"] | null;
@@ -147,6 +153,7 @@ export declare function useAnyspendOrderHistory(creatorAddress: string | undefin
147
153
  errorDetails: string | null;
148
154
  createdAt: number;
149
155
  expiredAt: number;
156
+ filledAt: number | null;
150
157
  creatorAddress: string | null;
151
158
  partnerId: string | null;
152
159
  onrampMetadata: import("../..").components["schemas"]["OnrampMetadata"] | null;
@@ -169,6 +176,7 @@ export declare function useAnyspendOrderHistory(creatorAddress: string | undefin
169
176
  errorDetails: string | null;
170
177
  createdAt: number;
171
178
  expiredAt: number;
179
+ filledAt: number | null;
172
180
  creatorAddress: string | null;
173
181
  partnerId: string | null;
174
182
  onrampMetadata: import("../..").components["schemas"]["OnrampMetadata"] | null;
@@ -191,6 +199,7 @@ export declare function useAnyspendOrderHistory(creatorAddress: string | undefin
191
199
  errorDetails: string | null;
192
200
  createdAt: number;
193
201
  expiredAt: number;
202
+ filledAt: number | null;
194
203
  creatorAddress: string | null;
195
204
  partnerId: string | null;
196
205
  onrampMetadata: import("../..").components["schemas"]["OnrampMetadata"] | null;
@@ -213,6 +222,7 @@ export declare function useAnyspendOrderHistory(creatorAddress: string | undefin
213
222
  errorDetails: string | null;
214
223
  createdAt: number;
215
224
  expiredAt: number;
225
+ filledAt: number | null;
216
226
  creatorAddress: string | null;
217
227
  partnerId: string | null;
218
228
  onrampMetadata: import("../..").components["schemas"]["OnrampMetadata"] | null;
@@ -235,6 +245,7 @@ export declare function useAnyspendOrderHistory(creatorAddress: string | undefin
235
245
  errorDetails: string | null;
236
246
  createdAt: number;
237
247
  expiredAt: number;
248
+ filledAt: number | null;
238
249
  creatorAddress: string | null;
239
250
  partnerId: string | null;
240
251
  onrampMetadata: import("../..").components["schemas"]["OnrampMetadata"] | null;
@@ -257,6 +268,7 @@ export declare function useAnyspendOrderHistory(creatorAddress: string | undefin
257
268
  errorDetails: string | null;
258
269
  createdAt: number;
259
270
  expiredAt: number;
271
+ filledAt: number | null;
260
272
  creatorAddress: string | null;
261
273
  partnerId: string | null;
262
274
  onrampMetadata: import("../..").components["schemas"]["OnrampMetadata"] | null;
@@ -1117,11 +1117,6 @@ export interface components {
1117
1117
  * @example 990000
1118
1118
  */
1119
1119
  actualDstAmount: string | null;
1120
- /**
1121
- * @description Amount in after fee
1122
- * @example 990000
1123
- */
1124
- amountInAfterFee: string | null;
1125
1120
  };
1126
1121
  /** @description HypeDuel-specific payload */
1127
1122
  HypeDuelPayload: {
@@ -1135,11 +1130,6 @@ export interface components {
1135
1130
  * @example 990000
1136
1131
  */
1137
1132
  actualDstAmount: string | null;
1138
- /**
1139
- * @description Amount in after fee
1140
- * @example 990000
1141
- */
1142
- amountInAfterFee: string | null;
1143
1133
  };
1144
1134
  /** @description Custom execution payload */
1145
1135
  CustomPayload: {
@@ -1307,6 +1297,8 @@ export interface components {
1307
1297
  * @example 1752506694679
1308
1298
  */
1309
1299
  expiredAt: number;
1300
+ /** @description Timestamp when the order was filled/executed */
1301
+ filledAt: number | null;
1310
1302
  /**
1311
1303
  * @description Optional creator address
1312
1304
  * @example 0xb34facb90a200251318e8841c05102366f2158cf
@@ -20,7 +20,7 @@ export declare function useCurrencyConversion(): {
20
20
  /** Base currency used for conversion (typically B3) */
21
21
  baseCurrency: import("../stores/currencyStore").SupportedCurrency;
22
22
  /** Current exchange rate from base to selected currency (undefined while loading) */
23
- exchangeRate: number;
23
+ exchangeRate: number | undefined;
24
24
  /** Format a value with currency conversion and proper symbol/decimal handling */
25
25
  formatCurrencyValue: (value: number, options?: {
26
26
  decimals?: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@b3dotfun/sdk",
3
- "version": "0.0.43",
3
+ "version": "0.0.44-alpha.0",
4
4
  "source": "src/index.ts",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "react-native": "./dist/cjs/index.native.js",