@b3dotfun/sdk 0.0.62-alpha.1 → 0.0.62-alpha.3

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.
Files changed (88) hide show
  1. package/dist/cjs/anyspend/react/components/AnySpend.js +61 -23
  2. package/dist/cjs/anyspend/react/components/AnySpendCustom.js +3 -0
  3. package/dist/cjs/anyspend/react/components/AnySpendStakeB3.js +5 -4
  4. package/dist/cjs/anyspend/react/components/AnyspendDepositHype.js +4 -4
  5. package/dist/cjs/anyspend/react/components/common/CryptoPaySection.js +4 -6
  6. package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.js +9 -17
  7. package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.d.ts +6 -1
  8. package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.js +11 -1
  9. package/dist/cjs/anyspend/react/components/common/OrderDetails.js +56 -145
  10. package/dist/cjs/anyspend/react/components/common/OrderTokenAmount.d.ts +2 -1
  11. package/dist/cjs/anyspend/react/components/common/OrderTokenAmount.js +39 -15
  12. package/dist/cjs/anyspend/react/components/common/PaySection.js +1 -1
  13. package/dist/cjs/anyspend/react/components/common/TokenBalance.js +1 -1
  14. package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.js +12 -11
  15. package/dist/cjs/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.d.ts +26 -0
  16. package/dist/cjs/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.js +56 -0
  17. package/dist/cjs/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.d.ts +10 -0
  18. package/dist/cjs/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.js +73 -0
  19. package/dist/cjs/anyspend/react/hooks/useConnectedWalletDisplay.d.ts +14 -0
  20. package/dist/cjs/anyspend/react/hooks/useConnectedWalletDisplay.js +57 -0
  21. package/dist/cjs/anyspend/react/hooks/usePhantomTransfer.d.ts +36 -0
  22. package/dist/cjs/anyspend/react/hooks/usePhantomTransfer.js +211 -0
  23. package/dist/cjs/global-account/react/hooks/index.d.ts +2 -1
  24. package/dist/cjs/global-account/react/hooks/index.js +5 -3
  25. package/dist/cjs/global-account/react/hooks/useSimBalance.d.ts +1 -1
  26. package/dist/cjs/global-account/react/hooks/useSimBalance.js +6 -5
  27. package/dist/cjs/global-account/react/hooks/useTokenBalanceDirect.d.ts +12 -0
  28. package/dist/cjs/global-account/react/hooks/useTokenBalanceDirect.js +62 -0
  29. package/dist/cjs/global-account/react/hooks/useTokenFromUrl.js +4 -3
  30. package/dist/esm/anyspend/react/components/AnySpend.js +62 -24
  31. package/dist/esm/anyspend/react/components/AnySpendCustom.js +3 -0
  32. package/dist/esm/anyspend/react/components/AnySpendStakeB3.js +7 -6
  33. package/dist/esm/anyspend/react/components/AnyspendDepositHype.js +4 -4
  34. package/dist/esm/anyspend/react/components/common/CryptoPaySection.js +5 -7
  35. package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.js +9 -17
  36. package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.d.ts +6 -1
  37. package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.js +11 -1
  38. package/dist/esm/anyspend/react/components/common/OrderDetails.js +57 -146
  39. package/dist/esm/anyspend/react/components/common/OrderTokenAmount.d.ts +2 -1
  40. package/dist/esm/anyspend/react/components/common/OrderTokenAmount.js +40 -16
  41. package/dist/esm/anyspend/react/components/common/PaySection.js +1 -1
  42. package/dist/esm/anyspend/react/components/common/TokenBalance.js +2 -2
  43. package/dist/esm/anyspend/react/hooks/useAnyspendFlow.js +12 -11
  44. package/dist/esm/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.d.ts +26 -0
  45. package/dist/esm/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.js +53 -0
  46. package/dist/esm/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.d.ts +10 -0
  47. package/dist/esm/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.js +70 -0
  48. package/dist/esm/anyspend/react/hooks/useConnectedWalletDisplay.d.ts +14 -0
  49. package/dist/esm/anyspend/react/hooks/useConnectedWalletDisplay.js +54 -0
  50. package/dist/esm/anyspend/react/hooks/usePhantomTransfer.d.ts +36 -0
  51. package/dist/esm/anyspend/react/hooks/usePhantomTransfer.js +208 -0
  52. package/dist/esm/global-account/react/hooks/index.d.ts +2 -1
  53. package/dist/esm/global-account/react/hooks/index.js +2 -1
  54. package/dist/esm/global-account/react/hooks/useSimBalance.d.ts +1 -1
  55. package/dist/esm/global-account/react/hooks/useSimBalance.js +6 -5
  56. package/dist/esm/global-account/react/hooks/useTokenBalanceDirect.d.ts +12 -0
  57. package/dist/esm/global-account/react/hooks/useTokenBalanceDirect.js +59 -0
  58. package/dist/esm/global-account/react/hooks/useTokenFromUrl.js +4 -3
  59. package/dist/types/anyspend/react/components/common/CryptoReceiveSection.d.ts +6 -1
  60. package/dist/types/anyspend/react/components/common/OrderTokenAmount.d.ts +2 -1
  61. package/dist/types/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.d.ts +26 -0
  62. package/dist/types/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.d.ts +10 -0
  63. package/dist/types/anyspend/react/hooks/useConnectedWalletDisplay.d.ts +14 -0
  64. package/dist/types/anyspend/react/hooks/usePhantomTransfer.d.ts +36 -0
  65. package/dist/types/global-account/react/hooks/index.d.ts +2 -1
  66. package/dist/types/global-account/react/hooks/useSimBalance.d.ts +1 -1
  67. package/dist/types/global-account/react/hooks/useTokenBalanceDirect.d.ts +12 -0
  68. package/package.json +1 -1
  69. package/src/anyspend/react/components/AnySpend.tsx +73 -22
  70. package/src/anyspend/react/components/AnySpendCustom.tsx +4 -0
  71. package/src/anyspend/react/components/AnySpendStakeB3.tsx +8 -11
  72. package/src/anyspend/react/components/AnyspendDepositHype.tsx +7 -3
  73. package/src/anyspend/react/components/common/CryptoPaySection.tsx +5 -7
  74. package/src/anyspend/react/components/common/CryptoPaymentMethod.tsx +9 -18
  75. package/src/anyspend/react/components/common/CryptoReceiveSection.tsx +22 -0
  76. package/src/anyspend/react/components/common/OrderDetails.tsx +66 -188
  77. package/src/anyspend/react/components/common/OrderTokenAmount.tsx +48 -17
  78. package/src/anyspend/react/components/common/PaySection.tsx +1 -0
  79. package/src/anyspend/react/components/common/TokenBalance.tsx +2 -2
  80. package/src/anyspend/react/hooks/useAnyspendFlow.ts +13 -10
  81. package/src/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.ts +72 -0
  82. package/src/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.ts +80 -0
  83. package/src/anyspend/react/hooks/useConnectedWalletDisplay.ts +69 -0
  84. package/src/anyspend/react/hooks/usePhantomTransfer.ts +301 -0
  85. package/src/global-account/react/hooks/index.ts +2 -1
  86. package/src/global-account/react/hooks/useSimBalance.ts +6 -5
  87. package/src/global-account/react/hooks/useTokenBalanceDirect.tsx +84 -0
  88. package/src/global-account/react/hooks/useTokenFromUrl.tsx +6 -5
@@ -17,6 +17,7 @@ import {
17
17
  useProfile,
18
18
  useRouter,
19
19
  useSearchParamsSSR,
20
+ useTokenBalanceDirect,
20
21
  useTokenData,
21
22
  useTokenFromUrl,
22
23
  } from "@b3dotfun/sdk/global-account/react";
@@ -30,17 +31,19 @@ import { toast } from "sonner";
30
31
  import { parseUnits } from "viem";
31
32
  import { base, mainnet } from "viem/chains";
32
33
  import { components } from "../../types/api";
34
+ import { useAutoSelectCryptoPaymentMethod } from "../hooks/useAutoSelectCryptoPaymentMethod";
35
+ import { useAutoSetActiveWalletFromWagmi } from "../hooks/useAutoSetActiveWalletFromWagmi";
33
36
  import { AnySpendFingerprintWrapper, getFingerprintConfig } from "./AnySpendFingerprintWrapper";
34
37
  import { CryptoPaymentMethod, CryptoPaymentMethodType } from "./common/CryptoPaymentMethod";
35
38
  import { CryptoPaySection } from "./common/CryptoPaySection";
36
39
  import { CryptoReceiveSection } from "./common/CryptoReceiveSection";
40
+ import { FeeDetailPanel } from "./common/FeeDetailPanel";
37
41
  import { FiatPaymentMethod, FiatPaymentMethodComponent } from "./common/FiatPaymentMethod";
38
42
  import { OrderDetails, OrderDetailsLoadingView } from "./common/OrderDetails";
39
43
  import { OrderHistory } from "./common/OrderHistory";
40
44
  import { PanelOnramp } from "./common/PanelOnramp";
41
45
  import { PanelOnrampPayment } from "./common/PanelOnrampPayment";
42
46
  import { PointsDetailPanel } from "./common/PointsDetailPanel";
43
- import { FeeDetailPanel } from "./common/FeeDetailPanel";
44
47
  import { RecipientSelection } from "./common/RecipientSelection";
45
48
  import { TabSection } from "./common/TabSection";
46
49
 
@@ -437,14 +440,38 @@ function AnySpendInner({
437
440
  // State for recipient selection
438
441
  const [recipientAddress, setRecipientAddress] = useState<string | undefined>();
439
442
 
440
- const { address: globalAddress, wallet: globalWallet } = useAccountWallet();
443
+ const { address: globalAddress, wallet: globalWallet, connectedEOAWallet } = useAccountWallet();
441
444
  const recipientProfile = useProfile({ address: recipientAddress, fresh: true });
442
445
  const recipientName = recipientProfile.data?.name;
443
446
 
444
- // Set default recipient address when wallet changes
445
- useEffect(() => {
446
- setRecipientAddress(recipientAddressFromProps || globalAddress);
447
- }, [recipientAddressFromProps, globalAddress]);
447
+ // Auto-set active wallet from wagmi
448
+ useAutoSetActiveWalletFromWagmi();
449
+
450
+ // Check token balance for crypto payments
451
+ const { rawBalance, isLoading: isBalanceLoading } = useTokenBalanceDirect({
452
+ token: selectedSrcToken,
453
+ address: connectedEOAWallet?.getAccount()?.address,
454
+ });
455
+
456
+ // Check if user has enough balanceuseAutoSetActiveWalletFromWagmi
457
+ const hasEnoughBalance = useMemo(() => {
458
+ if (!rawBalance || isBalanceLoading || activeTab !== "crypto") return false;
459
+ try {
460
+ const requiredAmount = parseUnits(srcAmount.replace(/,/g, ""), selectedSrcToken.decimals);
461
+ return rawBalance >= requiredAmount;
462
+ } catch {
463
+ return false;
464
+ }
465
+ }, [rawBalance, srcAmount, selectedSrcToken.decimals, isBalanceLoading, activeTab]);
466
+
467
+ // Auto-select crypto payment method based on available wallets and balance
468
+ useAutoSelectCryptoPaymentMethod({
469
+ paymentType: activeTab,
470
+ selectedCryptoPaymentMethod,
471
+ setSelectedCryptoPaymentMethod,
472
+ hasEnoughBalance,
473
+ isBalanceLoading,
474
+ });
448
475
 
449
476
  // Get geo-based onramp options for fiat payments
450
477
  const { geoData, coinbaseAvailablePaymentMethods, stripeWeb2Support } = useGeoOnrampOptions(srcAmountOnRamp);
@@ -624,17 +651,34 @@ function AnySpendInner({
624
651
  if (isSameChainSameToken)
625
652
  return { text: "Select a different token or chain", disable: true, error: false, loading: false };
626
653
  if (isLoadingAnyspendQuote) return { text: "Loading quote...", disable: true, error: false, loading: true };
627
- if (!recipientAddress) return { text: "Select recipient", disable: false, error: false, loading: false };
628
654
  if (isCreatingOrder || isCreatingOnrampOrder)
629
655
  return { text: "Creating order...", disable: true, error: false, loading: true };
630
656
  if (!anyspendQuote || !anyspendQuote.success)
631
657
  return { text: "No quote found", disable: true, error: false, loading: false };
632
658
 
659
+ if (activeTab === "fiat") {
660
+ // For fiat: check recipient first, then payment method
661
+ if (!recipientAddress) return { text: "Select recipient", disable: false, error: false, loading: false };
662
+
663
+ // If no fiat payment method selected, show "Select payment method"
664
+ if (selectedFiatPaymentMethod === FiatPaymentMethod.NONE) {
665
+ return { text: "Select payment method", disable: false, error: false, loading: false };
666
+ }
667
+ // If payment method is selected, show "Buy"
668
+ return { text: "Buy", disable: false, error: false, loading: false };
669
+ }
670
+
633
671
  if (activeTab === "crypto") {
672
+ // For crypto: check payment method first, then recipient
673
+
634
674
  // If no payment method selected, show "Choose payment method"
635
675
  if (selectedCryptoPaymentMethod === CryptoPaymentMethodType.NONE) {
636
676
  return { text: "Choose payment method", disable: false, error: false, loading: false };
637
677
  }
678
+
679
+ // Check recipient after payment method
680
+ if (!recipientAddress) return { text: "Select recipient", disable: false, error: false, loading: false };
681
+
638
682
  // If payment method selected, show appropriate action
639
683
  if (
640
684
  selectedCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET ||
@@ -647,15 +691,6 @@ function AnySpendInner({
647
691
  }
648
692
  }
649
693
 
650
- if (activeTab === "fiat") {
651
- // If no fiat payment method selected, show "Select payment method"
652
- if (selectedFiatPaymentMethod === FiatPaymentMethod.NONE) {
653
- return { text: "Select payment method", disable: false, error: false, loading: false };
654
- }
655
- // If payment method is selected, show "Buy"
656
- return { text: "Buy", disable: false, error: false, loading: false };
657
- }
658
-
659
694
  return { text: "Buy", disable: false, error: false, loading: false };
660
695
  }, [
661
696
  activeInputAmountInWei,
@@ -674,16 +709,18 @@ function AnySpendInner({
674
709
  const onMainButtonClick = async () => {
675
710
  if (btnInfo.disable) return;
676
711
 
677
- if (!recipientAddress) {
678
- navigateToPanel(PanelView.RECIPIENT_SELECTION, "forward");
679
- return;
680
- }
681
-
682
712
  try {
683
713
  invariant(anyspendQuote, "Relay price is not found");
684
- invariant(recipientAddress, "Recipient address is not found");
685
714
 
686
715
  if (activeTab === "fiat") {
716
+ // For fiat: check recipient first
717
+ if (!recipientAddress) {
718
+ navigateToPanel(PanelView.RECIPIENT_SELECTION, "forward");
719
+ return;
720
+ }
721
+
722
+ invariant(recipientAddress, "Recipient address is not found");
723
+
687
724
  // If no fiat payment method selected, show payment method selection
688
725
  if (selectedFiatPaymentMethod === FiatPaymentMethod.NONE) {
689
726
  navigateToPanel(PanelView.FIAT_PAYMENT_METHOD, "forward");
@@ -695,6 +732,8 @@ function AnySpendInner({
695
732
  }
696
733
 
697
734
  if (activeTab === "crypto") {
735
+ // For crypto: check payment method first, then recipient
736
+
698
737
  // If no payment method selected, show payment method selection
699
738
  if (selectedCryptoPaymentMethod === CryptoPaymentMethodType.NONE) {
700
739
  console.log("No payment method selected, showing selection panel");
@@ -702,6 +741,14 @@ function AnySpendInner({
702
741
  return;
703
742
  }
704
743
 
744
+ // Check recipient after payment method
745
+ if (!recipientAddress) {
746
+ navigateToPanel(PanelView.RECIPIENT_SELECTION, "forward");
747
+ return;
748
+ }
749
+
750
+ invariant(recipientAddress, "Recipient address is not found");
751
+
705
752
  // If payment method is selected, create order with payment method info
706
753
  if (
707
754
  selectedCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET ||
@@ -1057,6 +1104,9 @@ function AnySpendInner({
1057
1104
  selectedRecipientAddress={recipientAddress}
1058
1105
  recipientName={recipientName || undefined}
1059
1106
  onSelectRecipient={() => navigateToPanel(PanelView.RECIPIENT_SELECTION, "forward")}
1107
+ setRecipientAddress={setRecipientAddress}
1108
+ recipientAddressFromProps={recipientAddressFromProps}
1109
+ globalAddress={globalAddress}
1060
1110
  dstAmount={dstAmount}
1061
1111
  dstToken={selectedDstToken}
1062
1112
  selectedDstChainId={selectedDstChainId}
@@ -1070,6 +1120,7 @@ function AnySpendInner({
1070
1120
  anyspendQuote={anyspendQuote}
1071
1121
  onShowPointsDetail={() => navigateToPanel(PanelView.POINTS_DETAIL, "forward")}
1072
1122
  onShowFeeDetail={() => navigateToPanel(PanelView.FEE_DETAIL, "forward")}
1123
+ selectedCryptoPaymentMethod={selectedCryptoPaymentMethod}
1073
1124
  />
1074
1125
  )}
1075
1126
  </div>
@@ -44,6 +44,7 @@ import React, { useCallback, useEffect, useMemo, useState } from "react";
44
44
  import { toast } from "sonner";
45
45
  import { base } from "viem/chains";
46
46
  import { useFeatureFlags } from "../contexts/FeatureFlagsContext";
47
+ import { useAutoSetActiveWalletFromWagmi } from "../hooks/useAutoSetActiveWalletFromWagmi";
47
48
  import { AnySpendFingerprintWrapper, getFingerprintConfig } from "./AnySpendFingerprintWrapper";
48
49
  import { CryptoPaymentMethod, CryptoPaymentMethodType } from "./common/CryptoPaymentMethod";
49
50
  import { FeeBreakDown } from "./common/FeeBreakDown";
@@ -241,6 +242,9 @@ function AnySpendCustomInner({
241
242
  const searchParams = useSearchParamsSSR();
242
243
  const router = useRouter();
243
244
 
245
+ // Auto-set active wallet from wagmi
246
+ useAutoSetActiveWalletFromWagmi();
247
+
244
248
  const [activePanel, setActivePanel] = useState<PanelView>(
245
249
  loadOrder ? PanelView.ORDER_DETAILS : PanelView.CONFIRM_ORDER,
246
250
  );
@@ -1,4 +1,4 @@
1
- import { ABI_ERC20_STAKING, B3_TOKEN } from "@b3dotfun/sdk/anyspend";
1
+ import { ABI_ERC20_STAKING, B3_TOKEN, eqci } from "@b3dotfun/sdk/anyspend";
2
2
  import {
3
3
  Button,
4
4
  GlareCardRounded,
@@ -7,7 +7,7 @@ import {
7
7
  TextLoop,
8
8
  useHasMounted,
9
9
  useModalStore,
10
- useTokenBalance,
10
+ useSimBalance,
11
11
  useUnifiedChainSwitchAndExecute,
12
12
  } from "@b3dotfun/sdk/global-account/react";
13
13
  import { PUBLIC_BASE_RPC_URL } from "@b3dotfun/sdk/shared/constants";
@@ -58,19 +58,16 @@ export function AnySpendStakeB3({
58
58
  const hasMounted = useHasMounted();
59
59
  const { setB3ModalOpen } = useModalStore();
60
60
 
61
- // Fetch B3 token balance
62
- const {
63
- formattedBalance: b3Balance,
64
- isLoading: isBalanceLoading,
65
- rawBalance: b3RawBalance,
66
- } = useTokenBalance({
67
- token: B3_TOKEN,
68
- });
69
-
70
61
  // Wagmi hooks for direct staking
71
62
  const { address } = useAccount();
72
63
  const { switchChainAndExecute, isSwitchingOrExecuting } = useUnifiedChainSwitchAndExecute();
73
64
 
65
+ // Fetch B3 token balance
66
+ const { data: simBalance, isLoading: isBalanceLoading } = useSimBalance(address, [base.id]);
67
+ const b3RawBalanceStr = simBalance?.balances.find(b => eqci(b.address, B3_TOKEN.address))?.amount || "0";
68
+ const b3RawBalance = BigInt(b3RawBalanceStr);
69
+ const b3Balance = formatTokenAmount(b3RawBalance, B3_TOKEN.decimals);
70
+
74
71
  // State for direct staking flow
75
72
  const [isStaking, setIsStaking] = useState(false);
76
73
  const [stakingTxHash, setStakingTxHash] = useState<string>("");
@@ -6,6 +6,7 @@ import invariant from "invariant";
6
6
  import { motion } from "motion/react";
7
7
  import { useEffect, useMemo, useRef } from "react";
8
8
  import { toast } from "sonner";
9
+ import { useActiveWallet, useSetActiveWallet } from "thirdweb/react";
9
10
  import { base } from "viem/chains";
10
11
  import { PanelView, useAnyspendFlow } from "../hooks/useAnyspendFlow";
11
12
  import { AnySpendFingerprintWrapper, getFingerprintConfig } from "./AnySpendFingerprintWrapper";
@@ -17,11 +18,10 @@ import { FiatPaymentMethod, FiatPaymentMethodComponent } from "./common/FiatPaym
17
18
  import { OrderDetails } from "./common/OrderDetails";
18
19
  import { PointsDetailPanel } from "./common/PointsDetailPanel";
19
20
  import { RecipientSelection } from "./common/RecipientSelection";
20
- import { useActiveWallet, useSetActiveWallet } from "thirdweb/react";
21
21
 
22
22
  import { ArrowDown, Loader2 } from "lucide-react";
23
- import { PanelOnramp } from "./common/PanelOnramp";
24
23
  import { useGlobalWalletState } from "../../utils";
24
+ import { PanelOnramp } from "./common/PanelOnramp";
25
25
 
26
26
  const SLIPPAGE_PERCENT = 3;
27
27
 
@@ -286,9 +286,12 @@ function AnySpendDepositHypeInner({
286
286
  <CryptoReceiveSection
287
287
  isDepositMode={false}
288
288
  isBuyMode={true}
289
- selectedRecipientAddress={recipientAddress}
289
+ selectedRecipientAddress={selectedRecipientAddress}
290
290
  recipientName={recipientName || undefined}
291
291
  onSelectRecipient={() => setActivePanel(PanelView.RECIPIENT_SELECTION)}
292
+ setRecipientAddress={setSelectedRecipientAddress}
293
+ recipientAddressFromProps={recipientAddress}
294
+ globalAddress={globalAddress}
292
295
  dstAmount={dstAmount}
293
296
  dstToken={B3_TOKEN}
294
297
  dstTokenSymbol={HYPE_TOKEN_DETAILS.SYMBOL}
@@ -304,6 +307,7 @@ function AnySpendDepositHypeInner({
304
307
  anyspendQuote={anyspendQuote}
305
308
  onShowPointsDetail={() => setActivePanel(PanelView.POINTS_DETAIL)}
306
309
  onShowFeeDetail={() => setActivePanel(PanelView.FEE_DETAIL)}
310
+ selectedCryptoPaymentMethod={selectedCryptoPaymentMethod}
307
311
  />
308
312
  )}
309
313
  </div>
@@ -1,4 +1,4 @@
1
- import { useAccountWallet, useProfile, useTokenData } from "@b3dotfun/sdk/global-account/react";
1
+ import { useProfile, useTokenData } from "@b3dotfun/sdk/global-account/react";
2
2
  import { formatUsername } from "@b3dotfun/sdk/shared/utils";
3
3
  import { shortenAddress } from "@b3dotfun/sdk/shared/utils/formatAddress";
4
4
  import { formatDisplayNumber } from "@b3dotfun/sdk/shared/utils/number";
@@ -6,6 +6,7 @@ import { ChevronRight, Info } from "lucide-react";
6
6
  import { motion } from "motion/react";
7
7
  import { useEffect, useRef } from "react";
8
8
  import { components } from "../../../types/api";
9
+ import { useConnectedWalletDisplay } from "../../hooks/useConnectedWalletDisplay";
9
10
  import { CryptoPaymentMethodType } from "./CryptoPaymentMethod";
10
11
  import { OrderTokenAmount } from "./OrderTokenAmount";
11
12
  import { TokenBalance } from "./TokenBalance";
@@ -46,14 +47,10 @@ export function CryptoPaySection({
46
47
  onTokenSelect,
47
48
  onShowFeeDetail,
48
49
  }: CryptoPaySectionProps) {
49
- const { connectedSmartWallet, connectedEOAWallet } = useAccountWallet();
50
50
  const { data: srcTokenMetadata } = useTokenData(selectedSrcToken?.chainId, selectedSrcToken?.address);
51
51
 
52
- // Determine which address to use based on payment method
53
- const walletAddress =
54
- selectedCryptoPaymentMethod === CryptoPaymentMethodType.GLOBAL_WALLET
55
- ? connectedSmartWallet?.getAccount()?.address
56
- : connectedEOAWallet?.getAccount()?.address;
52
+ // Use custom hook to determine wallet address based on payment method
53
+ const { walletAddress } = useConnectedWalletDisplay(selectedCryptoPaymentMethod);
57
54
 
58
55
  const { data: profileData } = useProfile({ address: walletAddress });
59
56
  const connectedName = profileData?.displayName;
@@ -137,6 +134,7 @@ export function CryptoPaySection({
137
134
  </div>
138
135
  <OrderTokenAmount
139
136
  address={walletAddress}
137
+ walletAddress={walletAddress}
140
138
  context="from"
141
139
  inputValue={srcAmount}
142
140
  onChangeInput={value => {
@@ -13,6 +13,7 @@ import { toast } from "sonner";
13
13
  import { useActiveWallet, useSetActiveWallet, useWalletInfo } from "thirdweb/react";
14
14
  import { WalletId, createWallet } from "thirdweb/wallets";
15
15
  import { useAccount, useConnect, useDisconnect, useWalletClient } from "wagmi";
16
+ import { useConnectedWalletDisplay } from "../../hooks/useConnectedWalletDisplay";
16
17
 
17
18
  export enum CryptoPaymentMethodType {
18
19
  NONE = "none",
@@ -47,7 +48,7 @@ export function CryptoPaymentMethod({
47
48
  connectedEOAWallet: connectedEOAWallet,
48
49
  connectedSmartWallet: connectedSmartWallet,
49
50
  } = useAccountWallet();
50
- const { connector, address, isConnected: wagmiWalletIsConnected } = useAccount();
51
+ const { connector, address } = useAccount();
51
52
  const { connect, connectors, isPending } = useConnect();
52
53
  const { disconnect } = useDisconnect();
53
54
  const { data: walletClient } = useWalletClient();
@@ -61,20 +62,8 @@ export function CryptoPaymentMethod({
61
62
  const isConnected = !!connectedEOAWallet;
62
63
  const globalAddress = connectedSmartWallet?.getAccount()?.address;
63
64
 
64
- // Helper function to check if two addresses are the same
65
- const isSameAddress = (addr1?: string, addr2?: string): boolean => {
66
- if (!addr1 || !addr2) return false;
67
- return addr1.toLowerCase() === addr2.toLowerCase();
68
- };
69
-
70
- // Check if connectedEOAWallet and wagmi wallet represent the same wallet
71
- const connectedEOAAddress = connectedEOAWallet?.getAccount()?.address;
72
- const wagmiAddress = address;
73
- const isWalletDuplicated = isSameAddress(connectedEOAAddress, wagmiAddress);
74
-
75
- // Determine which wallet to show (prefer connectedEOAWallet if both exist and are the same)
76
- const shouldShowConnectedEOA = !!connectedEOAWallet;
77
- const shouldShowWagmiWallet = wagmiWalletIsConnected && (!isWalletDuplicated || !connectedEOAWallet);
65
+ // Use custom hook to determine wallet display logic
66
+ const { shouldShowConnectedEOA, shouldShowWagmiWallet } = useConnectedWalletDisplay(selectedPaymentMethod);
78
67
 
79
68
  // Map wagmi connector names to thirdweb wallet IDs
80
69
  const getThirdwebWalletId = (connectorName: string): WalletId | null => {
@@ -237,11 +226,13 @@ export function CryptoPaymentMethod({
237
226
  setSelectedPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
238
227
  onSelectPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
239
228
  setGlobalAccountWallet(activeWallet);
240
- setActiveWallet(connectedEOAWallet);
229
+ if (connectedEOAWallet) {
230
+ setActiveWallet(connectedEOAWallet);
231
+ }
241
232
  toast.success(`Selected ${eoaWalletInfo?.name || connector?.name || "wallet"}`);
242
233
  }}
243
234
  className={cn(
244
- "crypto-payment-method-connect-wallet w-full rounded-xl border p-4 text-left transition-all hover:shadow-md",
235
+ "crypto-payment-method-connect-wallet eoa-wallet w-full rounded-xl border p-4 text-left transition-all hover:shadow-md",
245
236
  selectedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET
246
237
  ? "connected-wallet border-as-brand bg-as-brand/5"
247
238
  : "border-as-border-secondary bg-as-surface-primary hover:border-as-secondary/80",
@@ -300,7 +291,7 @@ export function CryptoPaymentMethod({
300
291
  toast.success(`Selected ${connector?.name || "wallet"}`);
301
292
  }}
302
293
  className={cn(
303
- "crypto-payment-method-connect-wallet w-full rounded-xl border p-4 text-left transition-all hover:shadow-md",
294
+ "crypto-payment-method-connect-wallet wagmi-wallet w-full rounded-xl border p-4 text-left transition-all hover:shadow-md",
304
295
  selectedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET
305
296
  ? "connected-wallet border-as-brand bg-as-brand/5"
306
297
  : "border-as-border-secondary bg-as-surface-primary hover:border-as-secondary/80",
@@ -4,8 +4,11 @@ import { shortenAddress } from "@b3dotfun/sdk/shared/utils/formatAddress";
4
4
  import { formatDisplayNumber } from "@b3dotfun/sdk/shared/utils/number";
5
5
  import { ChevronRight, Info } from "lucide-react";
6
6
  import { motion } from "motion/react";
7
+ import { useEffect } from "react";
7
8
  import { components } from "../../../types/api";
8
9
  import { useFeatureFlags } from "../../contexts/FeatureFlagsContext";
10
+ import { useConnectedWalletDisplay } from "../../hooks/useConnectedWalletDisplay";
11
+ import { CryptoPaymentMethodType } from "./CryptoPaymentMethod";
9
12
  import { OrderTokenAmount } from "./OrderTokenAmount";
10
13
  import { PointsBadge } from "./PointsBadge";
11
14
 
@@ -16,6 +19,9 @@ interface CryptoReceiveSectionProps {
16
19
  selectedRecipientAddress?: string;
17
20
  recipientName?: string;
18
21
  onSelectRecipient: () => void;
22
+ setRecipientAddress?: (address: string | undefined) => void;
23
+ recipientAddressFromProps?: string;
24
+ globalAddress?: string;
19
25
  // Token data
20
26
  dstAmount: string;
21
27
  dstToken: components["schemas"]["Token"];
@@ -34,6 +40,8 @@ interface CryptoReceiveSectionProps {
34
40
  onShowPointsDetail?: () => void;
35
41
  // Fee detail navigation
36
42
  onShowFeeDetail?: () => void;
43
+ // Payment method for wallet tracking
44
+ selectedCryptoPaymentMethod?: CryptoPaymentMethodType;
37
45
  }
38
46
 
39
47
  export function CryptoReceiveSection({
@@ -42,6 +50,9 @@ export function CryptoReceiveSection({
42
50
  selectedRecipientAddress,
43
51
  recipientName,
44
52
  onSelectRecipient,
53
+ setRecipientAddress,
54
+ recipientAddressFromProps,
55
+ globalAddress,
45
56
  dstAmount,
46
57
  dstToken,
47
58
  selectedDstChainId,
@@ -54,9 +65,20 @@ export function CryptoReceiveSection({
54
65
  dstTokenLogoURI,
55
66
  onShowPointsDetail,
56
67
  onShowFeeDetail,
68
+ selectedCryptoPaymentMethod,
57
69
  }: CryptoReceiveSectionProps) {
58
70
  const featureFlags = useFeatureFlags();
59
71
 
72
+ // Get wallet address based on selected payment method
73
+ const { walletAddress } = useConnectedWalletDisplay(selectedCryptoPaymentMethod);
74
+
75
+ // Set default recipient address when wallet changes
76
+ useEffect(() => {
77
+ if (setRecipientAddress) {
78
+ setRecipientAddress(recipientAddressFromProps || walletAddress || globalAddress);
79
+ }
80
+ }, [recipientAddressFromProps, walletAddress, globalAddress, setRecipientAddress]);
81
+
60
82
  return (
61
83
  <motion.div
62
84
  initial={{ opacity: 0, y: 20, filter: "blur(10px)" }}