@b3dotfun/sdk 0.0.66 → 0.0.67-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/cjs/anyspend/react/components/AnySpend.js +38 -26
  2. package/dist/cjs/anyspend/react/components/AnySpendCustom.js +10 -6
  3. package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.js +1 -1
  4. package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.js +0 -7
  5. package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.d.ts +2 -7
  6. package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.js +3 -13
  7. package/dist/cjs/anyspend/react/hooks/index.d.ts +1 -0
  8. package/dist/cjs/anyspend/react/hooks/index.js +1 -0
  9. package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.d.ts +1 -1
  10. package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.js +12 -12
  11. package/dist/cjs/anyspend/react/hooks/useConnectedWalletDisplay.js +2 -1
  12. package/dist/cjs/anyspend/react/hooks/useRecipientAddressState.d.ts +52 -0
  13. package/dist/cjs/anyspend/react/hooks/useRecipientAddressState.js +52 -0
  14. package/dist/cjs/global-account/react/hooks/useAuthentication.js +5 -0
  15. package/dist/esm/anyspend/react/components/AnySpend.js +38 -26
  16. package/dist/esm/anyspend/react/components/AnySpendCustom.js +10 -6
  17. package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.js +1 -1
  18. package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.js +1 -8
  19. package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.d.ts +2 -7
  20. package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.js +3 -13
  21. package/dist/esm/anyspend/react/hooks/index.d.ts +1 -0
  22. package/dist/esm/anyspend/react/hooks/index.js +1 -0
  23. package/dist/esm/anyspend/react/hooks/useAnyspendFlow.d.ts +1 -1
  24. package/dist/esm/anyspend/react/hooks/useAnyspendFlow.js +12 -12
  25. package/dist/esm/anyspend/react/hooks/useConnectedWalletDisplay.js +2 -1
  26. package/dist/esm/anyspend/react/hooks/useRecipientAddressState.d.ts +52 -0
  27. package/dist/esm/anyspend/react/hooks/useRecipientAddressState.js +49 -0
  28. package/dist/esm/global-account/react/hooks/useAuthentication.js +5 -0
  29. package/dist/types/anyspend/react/components/common/CryptoReceiveSection.d.ts +2 -7
  30. package/dist/types/anyspend/react/hooks/index.d.ts +1 -0
  31. package/dist/types/anyspend/react/hooks/useAnyspendFlow.d.ts +1 -1
  32. package/dist/types/anyspend/react/hooks/useRecipientAddressState.d.ts +52 -0
  33. package/package.json +1 -1
  34. package/src/anyspend/react/components/AnySpend.tsx +43 -31
  35. package/src/anyspend/react/components/AnySpendCustom.tsx +10 -7
  36. package/src/anyspend/react/components/AnySpendCustomExactIn.tsx +1 -1
  37. package/src/anyspend/react/components/common/CryptoPaymentMethod.tsx +1 -8
  38. package/src/anyspend/react/components/common/CryptoReceiveSection.tsx +5 -27
  39. package/src/anyspend/react/hooks/index.ts +1 -0
  40. package/src/anyspend/react/hooks/useAnyspendFlow.ts +13 -12
  41. package/src/anyspend/react/hooks/useConnectedWalletDisplay.ts +4 -1
  42. package/src/anyspend/react/hooks/useRecipientAddressState.ts +78 -0
  43. package/src/global-account/react/hooks/useAuthentication.ts +5 -0
@@ -21,7 +21,9 @@ const viem_1 = require("viem");
21
21
  const chains_1 = require("viem/chains");
22
22
  const useAutoSelectCryptoPaymentMethod_1 = require("../hooks/useAutoSelectCryptoPaymentMethod");
23
23
  const useAutoSetActiveWalletFromWagmi_1 = require("../hooks/useAutoSetActiveWalletFromWagmi");
24
+ const useConnectedWalletDisplay_1 = require("../hooks/useConnectedWalletDisplay");
24
25
  const useCryptoPaymentMethodState_1 = require("../hooks/useCryptoPaymentMethodState");
26
+ const useRecipientAddressState_1 = require("../hooks/useRecipientAddressState");
25
27
  const AnySpendFingerprintWrapper_1 = require("./AnySpendFingerprintWrapper");
26
28
  const CryptoPaymentMethod_1 = require("./common/CryptoPaymentMethod");
27
29
  const CryptoPaySection_1 = require("./common/CryptoPaySection");
@@ -311,13 +313,22 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
311
313
  // : isAddress(newRecipientAddress) || (resolvedAddress && isAddress(resolvedAddress)),
312
314
  // [selectedDstChainId, newRecipientAddress, resolvedAddress]
313
315
  // );
314
- // State for recipient selection
315
- const [recipientAddress, setRecipientAddress] = (0, react_4.useState)();
316
316
  const { address: globalAddress, wallet: globalWallet, connectedEOAWallet } = (0, react_2.useAccountWallet)();
317
- const recipientProfile = (0, react_2.useProfile)({ address: recipientAddress, fresh: true });
318
- const recipientName = recipientProfile.data?.name;
319
317
  // Auto-set active wallet from wagmi
320
318
  (0, useAutoSetActiveWalletFromWagmi_1.useAutoSetActiveWalletFromWagmi)();
319
+ // Get wallet address based on selected payment method
320
+ const { walletAddress } = (0, useConnectedWalletDisplay_1.useConnectedWalletDisplay)(effectiveCryptoPaymentMethod);
321
+ // Recipient address state with dual-state system (auto + explicit user selection)
322
+ // The hook automatically manages priority: props > user selection > wallet/global
323
+ const { setSelectedRecipientAddress, effectiveRecipientAddress,
324
+ // resetRecipientAddress, // Not used yet, but available for future use
325
+ } = (0, useRecipientAddressState_1.useRecipientAddressState)({
326
+ recipientAddressFromProps,
327
+ walletAddress,
328
+ globalAddress,
329
+ });
330
+ const recipientProfile = (0, react_2.useProfile)({ address: effectiveRecipientAddress, fresh: true });
331
+ const recipientName = recipientProfile.data?.name;
321
332
  // Check token balance for crypto payments
322
333
  const { rawBalance, isLoading: isBalanceLoading } = (0, react_2.useTokenBalanceDirect)({
323
334
  token: selectedSrcToken,
@@ -375,7 +386,7 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
375
386
  type: "swap",
376
387
  tradeType: isSrcInputDirty ? "EXACT_INPUT" : "EXACT_OUTPUT",
377
388
  amount: activeInputAmountInWei,
378
- recipientAddress,
389
+ recipientAddress: effectiveRecipientAddress,
379
390
  }
380
391
  : {
381
392
  srcChain: chains_1.base.id,
@@ -385,7 +396,7 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
385
396
  type: "swap",
386
397
  tradeType: "EXACT_INPUT",
387
398
  amount: srcAmountOnrampInWei,
388
- recipientAddress,
399
+ recipientAddress: effectiveRecipientAddress,
389
400
  onrampVendor: getOnrampVendor(selectedFiatPaymentMethod),
390
401
  });
391
402
  // Load custom recipients from local storage on mount
@@ -401,8 +412,8 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
401
412
  // Add custom recipients based on local storage
402
413
  setCustomRecipients(parsedRecipients);
403
414
  // If no wallet is connected and no recipient is selected, select the first recipient
404
- if (!globalAddress && !recipientAddress && parsedRecipients.length > 0) {
405
- setRecipientAddress(parsedRecipients[0].address);
415
+ if (!globalAddress && !effectiveRecipientAddress && parsedRecipients.length > 0) {
416
+ setSelectedRecipientAddress(parsedRecipients[0].address);
406
417
  }
407
418
  }
408
419
  }
@@ -410,7 +421,7 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
410
421
  console.error("Error loading recipients from local storage:", err);
411
422
  }
412
423
  // Only run this effect once on mount
413
- }, [globalAddress, recipientAddress, customRecipients.length]);
424
+ }, [globalAddress, effectiveRecipientAddress, customRecipients.length, setSelectedRecipientAddress]);
414
425
  // Update dependent amount when relay price changes
415
426
  (0, react_4.useEffect)(() => {
416
427
  if (anyspendQuote?.data &&
@@ -513,7 +524,7 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
513
524
  return { text: "No quote found", disable: true, error: false, loading: false };
514
525
  if (activeTab === "fiat") {
515
526
  // For fiat: check recipient first, then payment method
516
- if (!recipientAddress)
527
+ if (!effectiveRecipientAddress)
517
528
  return { text: "Select recipient", disable: false, error: false, loading: false };
518
529
  // If no fiat payment method selected, show "Select payment method"
519
530
  if (selectedFiatPaymentMethod === FiatPaymentMethod_1.FiatPaymentMethod.NONE) {
@@ -529,7 +540,7 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
529
540
  return { text: "Choose payment method", disable: false, error: false, loading: false };
530
541
  }
531
542
  // Check recipient after payment method
532
- if (!recipientAddress)
543
+ if (!effectiveRecipientAddress)
533
544
  return { text: "Select recipient", disable: false, error: false, loading: false };
534
545
  // If payment method selected, show appropriate action
535
546
  if (effectiveCryptoPaymentMethod === CryptoPaymentMethod_1.CryptoPaymentMethodType.CONNECT_WALLET ||
@@ -545,7 +556,7 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
545
556
  activeInputAmountInWei,
546
557
  isSameChainSameToken,
547
558
  isLoadingAnyspendQuote,
548
- recipientAddress,
559
+ effectiveRecipientAddress,
549
560
  isCreatingOrder,
550
561
  isCreatingOnrampOrder,
551
562
  anyspendQuote,
@@ -561,11 +572,11 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
561
572
  (0, invariant_1.default)(anyspendQuote, "Relay price is not found");
562
573
  if (activeTab === "fiat") {
563
574
  // For fiat: check recipient first
564
- if (!recipientAddress) {
575
+ if (!effectiveRecipientAddress) {
565
576
  navigateToPanel(PanelView.RECIPIENT_SELECTION, "forward");
566
577
  return;
567
578
  }
568
- (0, invariant_1.default)(recipientAddress, "Recipient address is not found");
579
+ (0, invariant_1.default)(effectiveRecipientAddress, "Recipient address is not found");
569
580
  // If no fiat payment method selected, show payment method selection
570
581
  if (selectedFiatPaymentMethod === FiatPaymentMethod_1.FiatPaymentMethod.NONE) {
571
582
  navigateToPanel(PanelView.FIAT_PAYMENT_METHOD, "forward");
@@ -584,11 +595,11 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
584
595
  return;
585
596
  }
586
597
  // Check recipient after payment method
587
- if (!recipientAddress) {
598
+ if (!effectiveRecipientAddress) {
588
599
  navigateToPanel(PanelView.RECIPIENT_SELECTION, "forward");
589
600
  return;
590
601
  }
591
- (0, invariant_1.default)(recipientAddress, "Recipient address is not found");
602
+ (0, invariant_1.default)(effectiveRecipientAddress, "Recipient address is not found");
592
603
  // If payment method is selected, create order with payment method info
593
604
  if (effectiveCryptoPaymentMethod === CryptoPaymentMethod_1.CryptoPaymentMethodType.CONNECT_WALLET ||
594
605
  effectiveCryptoPaymentMethod === CryptoPaymentMethod_1.CryptoPaymentMethodType.GLOBAL_WALLET ||
@@ -617,13 +628,13 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
617
628
  const handleCryptoSwap = async (method) => {
618
629
  try {
619
630
  (0, invariant_1.default)(anyspendQuote, "Relay price is not found");
620
- (0, invariant_1.default)(recipientAddress, "Recipient address is not found");
631
+ (0, invariant_1.default)(effectiveRecipientAddress, "Recipient address is not found");
621
632
  // Debug: Check payment method values
622
633
  console.log("handleCryptoSwap - method parameter:", method);
623
634
  console.log("handleCryptoSwap - selectedCryptoPaymentMethod state:", selectedCryptoPaymentMethod);
624
635
  const srcAmountBigInt = (0, viem_1.parseUnits)(srcAmount.replace(/,/g, ""), selectedSrcToken.decimals);
625
636
  createOrder({
626
- recipientAddress,
637
+ recipientAddress: effectiveRecipientAddress,
627
638
  orderType: "swap",
628
639
  srcChain: selectedSrcChainId,
629
640
  dstChain: isBuyMode ? destinationTokenChainId : selectedDstChainId,
@@ -645,7 +656,7 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
645
656
  const handleFiatOrder = async (paymentMethod) => {
646
657
  try {
647
658
  (0, invariant_1.default)(anyspendQuote, "Relay price is not found");
648
- (0, invariant_1.default)(recipientAddress, "Recipient address is not found");
659
+ (0, invariant_1.default)(effectiveRecipientAddress, "Recipient address is not found");
649
660
  if (!srcAmountOnRamp || parseFloat(srcAmountOnRamp) <= 0) {
650
661
  sonner_1.toast.error("Please enter a valid amount");
651
662
  return;
@@ -685,7 +696,7 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
685
696
  return selectedDstToken;
686
697
  };
687
698
  createOnrampOrder({
688
- recipientAddress,
699
+ recipientAddress: effectiveRecipientAddress,
689
700
  orderType: "swap",
690
701
  dstChain: getDstToken().chainId,
691
702
  dstToken: getDstToken(),
@@ -791,7 +802,7 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
791
802
  else {
792
803
  setActivePanel(panelIndex);
793
804
  }
794
- }, _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"), onShowFeeDetail: () => navigateToPanel(PanelView.FEE_DETAIL, "forward"), customUsdInputValues: customUsdInputValues }) })), (0, jsx_runtime_1.jsx)(react_2.Button, { variant: "ghost", className: (0, cn_1.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: () => {
805
+ }, _recipientAddress: effectiveRecipientAddress, 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"), onShowFeeDetail: () => navigateToPanel(PanelView.FEE_DETAIL, "forward"), customUsdInputValues: customUsdInputValues }) })), (0, jsx_runtime_1.jsx)(react_2.Button, { variant: "ghost", className: (0, cn_1.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: () => {
795
806
  if (activeTab === "fiat" || isBuyMode) {
796
807
  return;
797
808
  }
@@ -810,11 +821,11 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
810
821
  const tempDstAmount = dstAmount;
811
822
  setSrcAmount(tempDstAmount);
812
823
  setDstAmount(tempSrcAmount);
813
- }, children: (0, jsx_runtime_1.jsx)("div", { className: "relative flex items-center justify-center transition-opacity", children: (0, jsx_runtime_1.jsx)(lucide_react_1.ArrowDown, { className: "text-as-primary/50 h-5 w-5" }) }) }), activeTab === "crypto" && ((0, jsx_runtime_1.jsx)(CryptoReceiveSection_1.CryptoReceiveSection, { isDepositMode: false, isBuyMode: isBuyMode, selectedRecipientAddress: recipientAddress, recipientName: recipientName || undefined, onSelectRecipient: () => navigateToPanel(PanelView.RECIPIENT_SELECTION, "forward"), setRecipientAddress: setRecipientAddress, recipientAddressFromProps: recipientAddressFromProps, globalAddress: globalAddress, dstAmount: dstAmount, dstToken: selectedDstToken, selectedDstChainId: selectedDstChainId, setSelectedDstChainId: setSelectedDstChainId, setSelectedDstToken: setSelectedDstToken, isSrcInputDirty: isSrcInputDirty, onChangeDstAmount: value => {
824
+ }, children: (0, jsx_runtime_1.jsx)("div", { className: "relative flex items-center justify-center transition-opacity", children: (0, jsx_runtime_1.jsx)(lucide_react_1.ArrowDown, { className: "text-as-primary/50 h-5 w-5" }) }) }), activeTab === "crypto" && ((0, jsx_runtime_1.jsx)(CryptoReceiveSection_1.CryptoReceiveSection, { isDepositMode: false, isBuyMode: isBuyMode, effectiveRecipientAddress: effectiveRecipientAddress, recipientName: recipientName || undefined, onSelectRecipient: () => navigateToPanel(PanelView.RECIPIENT_SELECTION, "forward"), dstAmount: dstAmount, dstToken: selectedDstToken, selectedDstChainId: selectedDstChainId, setSelectedDstChainId: setSelectedDstChainId, setSelectedDstToken: setSelectedDstToken, isSrcInputDirty: isSrcInputDirty, onChangeDstAmount: value => {
814
825
  setIsSrcInputDirty(false);
815
826
  setDstAmount(value);
816
- }, anyspendQuote: anyspendQuote, onShowPointsDetail: () => navigateToPanel(PanelView.POINTS_DETAIL, "forward"), onShowFeeDetail: () => navigateToPanel(PanelView.FEE_DETAIL, "forward"), selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod }))] }), (0, jsx_runtime_1.jsxs)(react_3.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: (0, cn_1.cn)("mt-4 flex w-full max-w-[460px] flex-col gap-2"), children: [(0, jsx_runtime_1.jsx)(react_2.ShinyButton, { accentColor: "hsl(var(--as-brand))", disabled: btnInfo.disable, onClick: onMainButtonClick, className: (0, cn_1.cn)("as-main-button relative w-full", btnInfo.error ? "!bg-as-red" : btnInfo.disable ? "!bg-as-on-surface-2" : "!bg-as-brand"), textClassName: (0, cn_1.cn)(btnInfo.error ? "text-white" : btnInfo.disable ? "text-as-secondary" : "text-white"), children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-center gap-2", children: [btnInfo.loading && (0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "h-4 w-4 animate-spin" }), btnInfo.text] }) }), !hideTransactionHistoryButton && (globalAddress || recipientAddress) ? ((0, jsx_runtime_1.jsxs)(react_2.Button, { variant: "link", onClick: onClickHistory, className: "text-as-primary/50 hover:text-as-primary flex items-center gap-1 transition-colors", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.HistoryIcon, { className: "h-4 w-4" }), " ", (0, jsx_runtime_1.jsx)("span", { className: "pr-4", children: "Transaction History" })] })) : null] })] }));
817
- const onrampPaymentView = ((0, jsx_runtime_1.jsx)(PanelOnrampPayment_1.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 => {
827
+ }, anyspendQuote: anyspendQuote, onShowPointsDetail: () => navigateToPanel(PanelView.POINTS_DETAIL, "forward"), onShowFeeDetail: () => navigateToPanel(PanelView.FEE_DETAIL, "forward") }))] }), (0, jsx_runtime_1.jsxs)(react_3.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: (0, cn_1.cn)("mt-4 flex w-full max-w-[460px] flex-col gap-2"), children: [(0, jsx_runtime_1.jsx)(react_2.ShinyButton, { accentColor: "hsl(var(--as-brand))", disabled: btnInfo.disable, onClick: onMainButtonClick, className: (0, cn_1.cn)("as-main-button relative w-full", btnInfo.error ? "!bg-as-red" : btnInfo.disable ? "!bg-as-on-surface-2" : "!bg-as-brand"), textClassName: (0, cn_1.cn)(btnInfo.error ? "text-white" : btnInfo.disable ? "text-as-secondary" : "text-white"), children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-center gap-2", children: [btnInfo.loading && (0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "h-4 w-4 animate-spin" }), btnInfo.text] }) }), !hideTransactionHistoryButton && (globalAddress || effectiveRecipientAddress) ? ((0, jsx_runtime_1.jsxs)(react_2.Button, { variant: "link", onClick: onClickHistory, className: "text-as-primary/50 hover:text-as-primary flex items-center gap-1 transition-colors", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.HistoryIcon, { className: "h-4 w-4" }), " ", (0, jsx_runtime_1.jsx)("span", { className: "pr-4", children: "Transaction History" })] })) : null] })] }));
828
+ const onrampPaymentView = ((0, jsx_runtime_1.jsx)(PanelOnrampPayment_1.PanelOnrampPayment, { srcAmountOnRamp: srcAmountOnRamp, recipientName: recipientName || undefined, recipientAddress: effectiveRecipientAddress, isBuyMode: isBuyMode, destinationTokenChainId: destinationTokenChainId, destinationTokenAddress: destinationTokenAddress, selectedDstChainId: selectedDstChainId, selectedDstToken: selectedDstToken, orderType: "swap", anyspendQuote: anyspendQuote, globalAddress: globalAddress, onOrderCreated: orderId => {
818
829
  setOrderId(orderId);
819
830
  navigateToPanel(PanelView.ORDER_DETAILS, "forward");
820
831
  // Add orderId and payment method to URL for persistence
@@ -829,8 +840,9 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
829
840
  }
830
841
  router.push(`${window.location.pathname}?${params.toString()}`);
831
842
  }, onBack: navigateBack, recipientEnsName: globalWallet?.ensName, recipientImageUrl: globalWallet?.meta?.icon }));
832
- const recipientSelectionView = ((0, jsx_runtime_1.jsx)(RecipientSelection_1.RecipientSelection, { initialValue: recipientAddress || "", onBack: navigateBack, onConfirm: address => {
833
- setRecipientAddress(address);
843
+ const recipientSelectionView = ((0, jsx_runtime_1.jsx)(RecipientSelection_1.RecipientSelection, { initialValue: effectiveRecipientAddress || "", onBack: navigateBack, onConfirm: address => {
844
+ // User manually selected a recipient
845
+ setSelectedRecipientAddress(address);
834
846
  navigateBack();
835
847
  } }));
836
848
  const cryptoPaymentMethodView = ((0, jsx_runtime_1.jsx)(CryptoPaymentMethod_1.CryptoPaymentMethod, { globalAddress: globalAddress, globalWallet: globalWallet, selectedPaymentMethod: effectiveCryptoPaymentMethod, setSelectedPaymentMethod: method => {
@@ -55,6 +55,7 @@ const chains_1 = require("viem/chains");
55
55
  const FeatureFlagsContext_1 = require("../contexts/FeatureFlagsContext");
56
56
  const useAutoSetActiveWalletFromWagmi_1 = require("../hooks/useAutoSetActiveWalletFromWagmi");
57
57
  const useCryptoPaymentMethodState_1 = require("../hooks/useCryptoPaymentMethodState");
58
+ const useRecipientAddressState_1 = require("../hooks/useRecipientAddressState");
58
59
  const AnySpendFingerprintWrapper_1 = require("./AnySpendFingerprintWrapper");
59
60
  const CryptoPaymentMethod_1 = require("./common/CryptoPaymentMethod");
60
61
  const FeeBreakDown_1 = require("./common/FeeBreakDown");
@@ -161,10 +162,12 @@ function AnySpendCustomInner({ loadOrder, mode = "modal", activeTab: activeTabPr
161
162
  const [selectedFiatPaymentMethod, setSelectedFiatPaymentMethod] = (0, react_4.useState)(FiatPaymentMethod_1.FiatPaymentMethod.NONE);
162
163
  // Get current user's wallet
163
164
  const currentWallet = (0, react_2.useAccountWallet)();
164
- // Add state for custom recipient
165
- const [customRecipientAddress, setCustomRecipientAddress] = (0, react_4.useState)(recipientAddressProps);
166
- // Update recipient logic to use custom recipient
167
- const recipientAddress = customRecipientAddress || currentWallet.address;
165
+ // Recipient address state with dual-state system (auto + explicit user selection)
166
+ // The hook automatically manages priority: props > user selection > global address
167
+ const { setSelectedRecipientAddress, effectiveRecipientAddress: recipientAddress } = (0, useRecipientAddressState_1.useRecipientAddressState)({
168
+ recipientAddressFromProps: recipientAddressProps,
169
+ globalAddress: currentWallet.address,
170
+ });
168
171
  const [orderId, setOrderId] = (0, react_4.useState)(loadOrder);
169
172
  // Track if onSuccess has been called for the current order
170
173
  const onSuccessCalled = react_4.default.useRef(false);
@@ -558,8 +561,9 @@ function AnySpendCustomInner({ loadOrder, mode = "modal", activeTab: activeTabPr
558
561
  }
559
562
  }, className: "relative w-full", children: isCreatingOrder ? ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "size-4 animate-spin" }), (0, jsx_runtime_1.jsx)("span", { children: "Creating order..." })] })) : isLoadingAnyspendQuote ? ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "size-4 animate-spin" }), (0, jsx_runtime_1.jsx)("span", { children: "Loading quote..." })] })) : !recipientAddress ? ("Select recipient") : selectedFiatPaymentMethod === FiatPaymentMethod_1.FiatPaymentMethod.NONE ? ("Select payment method") : anyspendQuote ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { children: "Buy" }), (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronRightCircle, { className: "absolute right-0 top-1/2 size-6 -translate-y-1/2 opacity-70" })] })) : ("No quote found") }) }) })] }) })] })] }));
560
563
  // Recipient selection view
561
- const recipientSelectionView = ((0, jsx_runtime_1.jsx)("div", { className: (0, utils_1.cn)("bg-as-surface-primary mx-auto w-[460px] max-w-full rounded-xl p-4"), children: (0, jsx_runtime_1.jsx)(RecipientSelection_1.RecipientSelection, { initialValue: customRecipientAddress || "", title: "Add recipient address or ENS", description: "Send tokens to another address", onBack: () => setActivePanel(PanelView.CONFIRM_ORDER), onConfirm: address => {
562
- setCustomRecipientAddress(address);
564
+ const recipientSelectionView = ((0, jsx_runtime_1.jsx)("div", { className: (0, utils_1.cn)("bg-as-surface-primary mx-auto w-[460px] max-w-full rounded-xl p-4"), children: (0, jsx_runtime_1.jsx)(RecipientSelection_1.RecipientSelection, { initialValue: recipientAddress || "", title: "Add recipient address or ENS", description: "Send tokens to another address", onBack: () => setActivePanel(PanelView.CONFIRM_ORDER), onConfirm: address => {
565
+ // User manually selected a recipient
566
+ setSelectedRecipientAddress(address);
563
567
  setActivePanel(PanelView.CONFIRM_ORDER);
564
568
  } }) }));
565
569
  // Crypto payment method view
@@ -174,7 +174,7 @@ function AnySpendCustomExactInInner({ loadOrder, mode = "modal", recipientAddres
174
174
  }
175
175
  };
176
176
  const headerContent = header ? (header({ anyspendPrice: anyspendQuote, isLoadingAnyspendPrice: isLoadingAnyspendQuote })) : ((0, jsx_runtime_1.jsx)("div", { className: "mb-4 flex flex-col items-center gap-3 text-center", children: (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-as-primary text-xl font-bold", children: actionLabel }), (0, jsx_runtime_1.jsx)("p", { className: "text-as-secondary text-sm", children: "Pay from any token to execute a custom exact-in transaction." })] }) }));
177
- const mainView = ((0, jsx_runtime_1.jsxs)("div", { className: "mx-auto flex w-[460px] max-w-full flex-col items-center gap-2", children: [headerContent, (0, jsx_runtime_1.jsx)("div", { className: "relative flex w-full max-w-[calc(100vw-32px)] flex-col gap-2", children: (0, jsx_runtime_1.jsxs)("div", { className: "relative flex w-full max-w-[calc(100vw-32px)] flex-col gap-2", children: [paymentType === "crypto" ? ((0, jsx_runtime_1.jsx)(CryptoPaySection_1.CryptoPaySection, { selectedSrcChainId: selectedSrcChainId, setSelectedSrcChainId: setSelectedSrcChainId, selectedSrcToken: selectedSrcToken, setSelectedSrcToken: setSelectedSrcToken, srcAmount: srcAmount, setSrcAmount: setSrcAmount, isSrcInputDirty: isSrcInputDirty, setIsSrcInputDirty: setIsSrcInputDirty, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod, onSelectCryptoPaymentMethod: () => setActivePanel(useAnyspendFlow_1.PanelView.CRYPTO_PAYMENT_METHOD), anyspendQuote: anyspendQuote, onTokenSelect: onTokenSelect })) : ((0, jsx_runtime_1.jsx)(react_2.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: (0, jsx_runtime_1.jsx)(PanelOnramp_1.PanelOnramp, { srcAmountOnRamp: srcAmount, setSrcAmountOnRamp: setSrcAmount, selectedPaymentMethod: selectedFiatPaymentMethod, setActivePanel: setActivePanel, _recipientAddress: selectedRecipientOrDefault, destinationToken: selectedDstToken, destinationChainId: selectedDstChainId, dstTokenSymbol: DESTINATION_TOKEN_DETAILS.SYMBOL, hideDstToken: true, destinationAmount: dstAmount, onDestinationTokenChange: () => { }, onDestinationChainChange: () => { }, fiatPaymentMethodIndex: useAnyspendFlow_1.PanelView.FIAT_PAYMENT_METHOD, recipientSelectionPanelIndex: useAnyspendFlow_1.PanelView.RECIPIENT_SELECTION, anyspendQuote: anyspendQuote, onShowPointsDetail: () => setActivePanel(useAnyspendFlow_1.PanelView.POINTS_DETAIL), onShowFeeDetail: () => setActivePanel(useAnyspendFlow_1.PanelView.FEE_DETAIL), customUsdInputValues: customUsdInputValues }) })), (0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)("relative -my-1 flex h-0 items-center justify-center", paymentType === "fiat" && "hidden"), children: (0, jsx_runtime_1.jsx)(react_1.Button, { variant: "ghost", className: (0, cn_1.cn)("swap-direction-button border-as-stroke bg-as-surface-primary z-10 h-10 w-10 cursor-default rounded-xl border-2 sm:h-8 sm:w-8 sm:rounded-xl"), children: (0, jsx_runtime_1.jsx)("div", { className: "relative flex items-center justify-center transition-opacity", children: (0, jsx_runtime_1.jsx)(lucide_react_1.ArrowDown, { className: "text-as-primary/50 h-5 w-5" }) }) }) }), paymentType === "crypto" && ((0, jsx_runtime_1.jsx)(CryptoReceiveSection_1.CryptoReceiveSection, { isDepositMode: false, isBuyMode: true, selectedRecipientAddress: selectedRecipientOrDefault, recipientName: recipientName || undefined, onSelectRecipient: () => setActivePanel(useAnyspendFlow_1.PanelView.RECIPIENT_SELECTION), dstAmount: dstAmount, dstToken: selectedDstToken, dstTokenSymbol: DESTINATION_TOKEN_DETAILS.SYMBOL, dstTokenLogoURI: DESTINATION_TOKEN_DETAILS.LOGO_URI, selectedDstChainId: selectedDstChainId, setSelectedDstChainId: () => { }, setSelectedDstToken: () => { }, isSrcInputDirty: isSrcInputDirty, onChangeDstAmount: value => {
177
+ const mainView = ((0, jsx_runtime_1.jsxs)("div", { className: "mx-auto flex w-[460px] max-w-full flex-col items-center gap-2", children: [headerContent, (0, jsx_runtime_1.jsx)("div", { className: "relative flex w-full max-w-[calc(100vw-32px)] flex-col gap-2", children: (0, jsx_runtime_1.jsxs)("div", { className: "relative flex w-full max-w-[calc(100vw-32px)] flex-col gap-2", children: [paymentType === "crypto" ? ((0, jsx_runtime_1.jsx)(CryptoPaySection_1.CryptoPaySection, { selectedSrcChainId: selectedSrcChainId, setSelectedSrcChainId: setSelectedSrcChainId, selectedSrcToken: selectedSrcToken, setSelectedSrcToken: setSelectedSrcToken, srcAmount: srcAmount, setSrcAmount: setSrcAmount, isSrcInputDirty: isSrcInputDirty, setIsSrcInputDirty: setIsSrcInputDirty, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod, onSelectCryptoPaymentMethod: () => setActivePanel(useAnyspendFlow_1.PanelView.CRYPTO_PAYMENT_METHOD), anyspendQuote: anyspendQuote, onTokenSelect: onTokenSelect })) : ((0, jsx_runtime_1.jsx)(react_2.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: (0, jsx_runtime_1.jsx)(PanelOnramp_1.PanelOnramp, { srcAmountOnRamp: srcAmount, setSrcAmountOnRamp: setSrcAmount, selectedPaymentMethod: selectedFiatPaymentMethod, setActivePanel: setActivePanel, _recipientAddress: selectedRecipientOrDefault, destinationToken: selectedDstToken, destinationChainId: selectedDstChainId, dstTokenSymbol: DESTINATION_TOKEN_DETAILS.SYMBOL, hideDstToken: true, destinationAmount: dstAmount, onDestinationTokenChange: () => { }, onDestinationChainChange: () => { }, fiatPaymentMethodIndex: useAnyspendFlow_1.PanelView.FIAT_PAYMENT_METHOD, recipientSelectionPanelIndex: useAnyspendFlow_1.PanelView.RECIPIENT_SELECTION, anyspendQuote: anyspendQuote, onShowPointsDetail: () => setActivePanel(useAnyspendFlow_1.PanelView.POINTS_DETAIL), onShowFeeDetail: () => setActivePanel(useAnyspendFlow_1.PanelView.FEE_DETAIL), customUsdInputValues: customUsdInputValues }) })), (0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)("relative -my-1 flex h-0 items-center justify-center", paymentType === "fiat" && "hidden"), children: (0, jsx_runtime_1.jsx)(react_1.Button, { variant: "ghost", className: (0, cn_1.cn)("swap-direction-button border-as-stroke bg-as-surface-primary z-10 h-10 w-10 cursor-default rounded-xl border-2 sm:h-8 sm:w-8 sm:rounded-xl"), children: (0, jsx_runtime_1.jsx)("div", { className: "relative flex items-center justify-center transition-opacity", children: (0, jsx_runtime_1.jsx)(lucide_react_1.ArrowDown, { className: "text-as-primary/50 h-5 w-5" }) }) }) }), paymentType === "crypto" && ((0, jsx_runtime_1.jsx)(CryptoReceiveSection_1.CryptoReceiveSection, { isDepositMode: false, isBuyMode: true, effectiveRecipientAddress: selectedRecipientOrDefault, recipientName: recipientName || undefined, onSelectRecipient: () => setActivePanel(useAnyspendFlow_1.PanelView.RECIPIENT_SELECTION), dstAmount: dstAmount, dstToken: selectedDstToken, dstTokenSymbol: DESTINATION_TOKEN_DETAILS.SYMBOL, dstTokenLogoURI: DESTINATION_TOKEN_DETAILS.LOGO_URI, selectedDstChainId: selectedDstChainId, setSelectedDstChainId: () => { }, setSelectedDstToken: () => { }, isSrcInputDirty: isSrcInputDirty, onChangeDstAmount: value => {
178
178
  setIsSrcInputDirty(false);
179
179
  setSrcAmount(value);
180
180
  }, anyspendQuote: anyspendQuote, onShowPointsDetail: () => setActivePanel(useAnyspendFlow_1.PanelView.POINTS_DETAIL), onShowFeeDetail: () => setActivePanel(useAnyspendFlow_1.PanelView.FEE_DETAIL) }))] }) }), (0, jsx_runtime_1.jsx)(react_2.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: (0, cn_1.cn)("mt-4 flex w-full max-w-[460px] flex-col gap-2"), children: (0, jsx_runtime_1.jsx)(react_1.ShinyButton, { accentColor: "hsl(var(--as-brand))", disabled: btnInfo.disable, onClick: onMainButtonClick, className: (0, cn_1.cn)("as-main-button relative w-full", btnInfo.error ? "!bg-as-red" : btnInfo.disable ? "!bg-as-on-surface-2" : "!bg-as-brand"), textClassName: (0, cn_1.cn)(btnInfo.error ? "text-white" : btnInfo.disable ? "text-as-secondary" : "text-white"), children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-center gap-2", children: [btnInfo.loading && (0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "h-4 w-4 animate-spin" }), btnInfo.text] }) }) }), mainFooter ? mainFooter : null] }));
@@ -98,13 +98,6 @@ function CryptoPaymentMethod({ selectedPaymentMethod, setSelectedPaymentMethod,
98
98
  description: "Connect using WalletConnect protocol",
99
99
  connector: availableConnectors.find(c => c.name === "WalletConnect"),
100
100
  },
101
- {
102
- id: "phantom",
103
- name: "Phantom",
104
- icon: (0, jsx_runtime_1.jsx)(react_2.WalletPhantom, { size: 48 }),
105
- description: "Connect using Phantom wallet",
106
- connector: availableConnectors.find(c => c.name === "Phantom"),
107
- },
108
101
  ].filter(wallet => wallet.connector); // Only show wallets that have available connectors
109
102
  // Reset modal state when closing
110
103
  const handleCloseModal = () => {
@@ -1,14 +1,10 @@
1
1
  import { components } from "../../../types/api";
2
- import { CryptoPaymentMethodType } from "./CryptoPaymentMethod";
3
2
  interface CryptoReceiveSectionProps {
4
3
  isDepositMode?: boolean;
5
4
  isBuyMode?: boolean;
6
- selectedRecipientAddress?: string;
5
+ effectiveRecipientAddress?: string;
7
6
  recipientName?: string;
8
7
  onSelectRecipient: () => void;
9
- setRecipientAddress?: (address: string | undefined) => void;
10
- recipientAddressFromProps?: string;
11
- globalAddress?: string;
12
8
  dstAmount: string;
13
9
  dstToken: components["schemas"]["Token"];
14
10
  selectedDstChainId?: number;
@@ -21,7 +17,6 @@ interface CryptoReceiveSectionProps {
21
17
  dstTokenLogoURI?: string;
22
18
  onShowPointsDetail?: () => void;
23
19
  onShowFeeDetail?: () => void;
24
- selectedCryptoPaymentMethod?: CryptoPaymentMethodType;
25
20
  }
26
- export declare function CryptoReceiveSection({ isDepositMode, isBuyMode, selectedRecipientAddress, recipientName, onSelectRecipient, setRecipientAddress, recipientAddressFromProps, globalAddress, dstAmount, dstToken, selectedDstChainId, setSelectedDstChainId, setSelectedDstToken, isSrcInputDirty, onChangeDstAmount, anyspendQuote, dstTokenSymbol, dstTokenLogoURI, onShowPointsDetail, onShowFeeDetail, selectedCryptoPaymentMethod, }: CryptoReceiveSectionProps): import("react/jsx-runtime").JSX.Element;
21
+ export declare function CryptoReceiveSection({ isDepositMode, isBuyMode, effectiveRecipientAddress, recipientName, onSelectRecipient, dstAmount, dstToken, selectedDstChainId, setSelectedDstChainId, setSelectedDstToken, isSrcInputDirty, onChangeDstAmount, anyspendQuote, dstTokenSymbol, dstTokenLogoURI, onShowPointsDetail, onShowFeeDetail, }: CryptoReceiveSectionProps): import("react/jsx-runtime").JSX.Element;
27
22
  export {};
@@ -8,26 +8,16 @@ const formatAddress_1 = require("../../../../shared/utils/formatAddress");
8
8
  const number_1 = require("../../../../shared/utils/number");
9
9
  const lucide_react_1 = require("lucide-react");
10
10
  const react_1 = require("motion/react");
11
- const react_2 = require("react");
12
11
  const FeatureFlagsContext_1 = require("../../contexts/FeatureFlagsContext");
13
- const useConnectedWalletDisplay_1 = require("../../hooks/useConnectedWalletDisplay");
14
12
  const OrderTokenAmount_1 = require("./OrderTokenAmount");
15
13
  const PointsBadge_1 = require("./PointsBadge");
16
- function CryptoReceiveSection({ isDepositMode = false, isBuyMode = false, selectedRecipientAddress, recipientName, onSelectRecipient, setRecipientAddress, recipientAddressFromProps, globalAddress, dstAmount, dstToken, selectedDstChainId, setSelectedDstChainId, setSelectedDstToken, isSrcInputDirty, onChangeDstAmount, anyspendQuote, dstTokenSymbol, dstTokenLogoURI, onShowPointsDetail, onShowFeeDetail, selectedCryptoPaymentMethod, }) {
14
+ function CryptoReceiveSection({ isDepositMode = false, isBuyMode = false, effectiveRecipientAddress, recipientName, onSelectRecipient, dstAmount, dstToken, selectedDstChainId, setSelectedDstChainId, setSelectedDstToken, isSrcInputDirty, onChangeDstAmount, anyspendQuote, dstTokenSymbol, dstTokenLogoURI, onShowPointsDetail, onShowFeeDetail, }) {
17
15
  const featureFlags = (0, FeatureFlagsContext_1.useFeatureFlags)();
18
- // Get wallet address based on selected payment method
19
- const { walletAddress } = (0, useConnectedWalletDisplay_1.useConnectedWalletDisplay)(selectedCryptoPaymentMethod);
20
- // Set default recipient address when wallet changes
21
- (0, react_2.useEffect)(() => {
22
- if (setRecipientAddress) {
23
- setRecipientAddress(recipientAddressFromProps || walletAddress || globalAddress);
24
- }
25
- }, [recipientAddressFromProps, walletAddress, globalAddress, setRecipientAddress]);
26
- return ((0, jsx_runtime_1.jsxs)(react_1.motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0.1, ease: "easeInOut" }, className: "receive-section bg-as-surface-secondary border-as-border-secondary relative flex w-full flex-col gap-2 rounded-2xl border p-4 sm:p-6", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex w-full items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { className: "text-as-primary/50 flex h-7 items-center gap-1.5 text-sm", children: [isDepositMode ? "Deposit" : "Receive", isSrcInputDirty && anyspendQuote?.data?.fee && onShowFeeDetail && ((0, jsx_runtime_1.jsx)("button", { onClick: onShowFeeDetail, className: "text-as-primary/40 hover:text-as-primary/60 transition-colors", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Info, { className: "h-4 w-4" }) }))] }), selectedRecipientAddress ? ((0, jsx_runtime_1.jsx)("button", { className: (0, cn_1.cn)("text-as-tertiarry flex h-7 items-center gap-2 rounded-lg"), onClick: onSelectRecipient, children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { className: "text-as-tertiarry flex items-center gap-1 text-sm", children: recipientName ? (0, utils_1.formatUsername)(recipientName) : (0, formatAddress_1.shortenAddress)(selectedRecipientAddress || "") }), (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronRight, { className: "h-4 w-4" })] }) })) : ((0, jsx_runtime_1.jsx)("button", { className: "text-as-primary/70 flex items-center gap-1 rounded-lg", onClick: onSelectRecipient, children: (0, jsx_runtime_1.jsx)("div", { className: "text-sm font-medium", children: "Select recipient" }) }))] }), isBuyMode || isDepositMode ? (
16
+ return ((0, jsx_runtime_1.jsxs)(react_1.motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0.1, ease: "easeInOut" }, className: "receive-section bg-as-surface-secondary border-as-border-secondary relative flex w-full flex-col gap-2 rounded-2xl border p-4 sm:p-6", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex w-full items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { className: "text-as-primary/50 flex h-7 items-center gap-1.5 text-sm", children: [isDepositMode ? "Deposit" : "Receive", isSrcInputDirty && anyspendQuote?.data?.fee && onShowFeeDetail && ((0, jsx_runtime_1.jsx)("button", { onClick: onShowFeeDetail, className: "text-as-primary/40 hover:text-as-primary/60 transition-colors", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Info, { className: "h-4 w-4" }) }))] }), effectiveRecipientAddress ? ((0, jsx_runtime_1.jsx)("button", { className: (0, cn_1.cn)("text-as-tertiarry flex h-7 items-center gap-2 rounded-lg"), onClick: onSelectRecipient, children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { className: "text-as-tertiarry flex items-center gap-1 text-sm", children: recipientName ? (0, utils_1.formatUsername)(recipientName) : (0, formatAddress_1.shortenAddress)(effectiveRecipientAddress || "") }), (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronRight, { className: "h-4 w-4" })] }) })) : ((0, jsx_runtime_1.jsx)("button", { className: "text-as-primary/70 flex items-center gap-1 rounded-lg", onClick: onSelectRecipient, children: (0, jsx_runtime_1.jsx)("div", { className: "text-sm font-medium", children: "Select recipient" }) }))] }), isBuyMode || isDepositMode ? (
27
17
  // Fixed destination token display for buy mode and deposit mode
28
18
  (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-as-primary text-2xl font-bold", children: dstAmount || "0" }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-as-brand/10 border-as-brand/30 flex items-center gap-3 rounded-xl border px-4 py-3", children: [(dstTokenLogoURI || dstToken.metadata?.logoURI) && ((0, jsx_runtime_1.jsx)("img", { src: dstTokenLogoURI || dstToken.metadata?.logoURI, alt: dstTokenSymbol || dstToken.symbol, className: "h-8 w-8 rounded-full" })), (0, jsx_runtime_1.jsx)("span", { className: "text-as-brand text-lg font-bold", children: dstTokenSymbol || dstToken.symbol })] })] })) : (
29
19
  // Token selection for regular swap mode
30
- (0, jsx_runtime_1.jsx)(OrderTokenAmount_1.OrderTokenAmount, { address: selectedRecipientAddress, context: "to", inputValue: dstAmount, onChangeInput: onChangeDstAmount || (() => { }), chainId: selectedDstChainId || dstToken.chainId, setChainId: setSelectedDstChainId || (() => { }), token: dstToken, setToken: setSelectedDstToken || (() => { }) })), (0, jsx_runtime_1.jsxs)("div", { className: "text-as-primary/50 flex h-5 items-center justify-start gap-2 text-sm", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, number_1.formatDisplayNumber)(anyspendQuote?.data?.currencyOut?.amountUsd, {
20
+ (0, jsx_runtime_1.jsx)(OrderTokenAmount_1.OrderTokenAmount, { address: effectiveRecipientAddress, context: "to", inputValue: dstAmount, onChangeInput: onChangeDstAmount || (() => { }), chainId: selectedDstChainId || dstToken.chainId, setChainId: setSelectedDstChainId || (() => { }), token: dstToken, setToken: setSelectedDstToken || (() => { }) })), (0, jsx_runtime_1.jsxs)("div", { className: "text-as-primary/50 flex h-5 items-center justify-start gap-2 text-sm", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, number_1.formatDisplayNumber)(anyspendQuote?.data?.currencyOut?.amountUsd, {
31
21
  style: "currency",
32
22
  fallback: "",
33
23
  }), anyspendQuote?.data?.currencyIn?.amountUsd &&
@@ -8,6 +8,7 @@ export * from "./useCoinbaseOnrampOptions";
8
8
  export * from "./useConnectedUserProfile";
9
9
  export * from "./useGeoOnrampOptions";
10
10
  export * from "./useGetGeo";
11
+ export * from "./useRecipientAddressState";
11
12
  export * from "./useSigMint";
12
13
  export * from "./useStripeClientSecret";
13
14
  export * from "./useStripeSupport";
@@ -24,6 +24,7 @@ __exportStar(require("./useCoinbaseOnrampOptions"), exports);
24
24
  __exportStar(require("./useConnectedUserProfile"), exports);
25
25
  __exportStar(require("./useGeoOnrampOptions"), exports);
26
26
  __exportStar(require("./useGetGeo"), exports);
27
+ __exportStar(require("./useRecipientAddressState"), exports);
27
28
  __exportStar(require("./useSigMint"), exports);
28
29
  __exportStar(require("./useStripeClientSecret"), exports);
29
30
  __exportStar(require("./useStripeSupport"), exports);
@@ -102,7 +102,7 @@ export declare function useAnyspendFlow({ paymentType, recipientAddress, loadOrd
102
102
  selectedFiatPaymentMethod: FiatPaymentMethod;
103
103
  setSelectedFiatPaymentMethod: import("react").Dispatch<import("react").SetStateAction<FiatPaymentMethod>>;
104
104
  selectedRecipientAddress: string | undefined;
105
- setSelectedRecipientAddress: import("react").Dispatch<import("react").SetStateAction<string | undefined>>;
105
+ setSelectedRecipientAddress: (address: string | undefined) => void;
106
106
  recipientName: string | null | undefined;
107
107
  globalAddress: string | undefined;
108
108
  hasEnoughBalance: boolean;
@@ -17,6 +17,7 @@ const useAutoSelectCryptoPaymentMethod_1 = require("./useAutoSelectCryptoPayment
17
17
  const useAutoSetActiveWalletFromWagmi_1 = require("./useAutoSetActiveWalletFromWagmi");
18
18
  const useConnectedWalletDisplay_1 = require("./useConnectedWalletDisplay");
19
19
  const useCryptoPaymentMethodState_1 = require("./useCryptoPaymentMethodState");
20
+ const useRecipientAddressState_1 = require("./useRecipientAddressState");
20
21
  var PanelView;
21
22
  (function (PanelView) {
22
23
  PanelView[PanelView["MAIN"] = 0] = "MAIN";
@@ -50,20 +51,19 @@ function useAnyspendFlow({ paymentType = "crypto", recipientAddress, loadOrder,
50
51
  // Payment method state with dual-state system (auto + explicit user selection)
51
52
  const { cryptoPaymentMethod, setCryptoPaymentMethod, selectedCryptoPaymentMethod, setSelectedCryptoPaymentMethod, effectiveCryptoPaymentMethod, resetPaymentMethods, } = (0, useCryptoPaymentMethodState_1.useCryptoPaymentMethodState)();
52
53
  const [selectedFiatPaymentMethod, setSelectedFiatPaymentMethod] = (0, react_3.useState)(FiatPaymentMethod_1.FiatPaymentMethod.NONE);
53
- // Recipient state
54
+ // Recipient state with dual-state system (auto + explicit user selection)
54
55
  const { address: globalAddress } = (0, react_2.useAccountWallet)();
55
56
  const { walletAddress } = (0, useConnectedWalletDisplay_1.useConnectedWalletDisplay)(effectiveCryptoPaymentMethod);
56
- const [selectedRecipientAddress, setSelectedRecipientAddress] = (0, react_3.useState)(recipientAddress);
57
- const recipientProfile = (0, react_2.useProfile)({ address: selectedRecipientAddress, fresh: true });
58
- const recipientName = recipientProfile.data?.name;
59
57
  // Auto-set active wallet from wagmi
60
58
  (0, useAutoSetActiveWalletFromWagmi_1.useAutoSetActiveWalletFromWagmi)();
61
- // Set default recipient address when wallet changes
62
- (0, react_3.useEffect)(() => {
63
- if (!selectedRecipientAddress && globalAddress) {
64
- setSelectedRecipientAddress(globalAddress);
65
- }
66
- }, [selectedRecipientAddress, globalAddress]);
59
+ // Recipient address state - hook automatically manages priority: props > user selection > wallet/global
60
+ const { setSelectedRecipientAddress, effectiveRecipientAddress } = (0, useRecipientAddressState_1.useRecipientAddressState)({
61
+ recipientAddressFromProps: recipientAddress,
62
+ walletAddress,
63
+ globalAddress,
64
+ });
65
+ const recipientProfile = (0, react_2.useProfile)({ address: effectiveRecipientAddress, fresh: true });
66
+ const recipientName = recipientProfile.data?.name;
67
67
  // Check token balance for crypto payments
68
68
  const { rawBalance, isLoading: isBalanceLoading } = (0, react_2.useTokenBalance)({
69
69
  token: selectedSrcToken,
@@ -146,7 +146,7 @@ function useAnyspendFlow({ paymentType = "crypto", recipientAddress, loadOrder,
146
146
  dstTokenAddress: selectedDstToken.address,
147
147
  type: orderType,
148
148
  amount: activeInputAmountInWei,
149
- recipientAddress: selectedRecipientAddress,
149
+ recipientAddress: effectiveRecipientAddress,
150
150
  onrampVendor: paymentType === "fiat" ? getOnrampVendor(selectedFiatPaymentMethod) : undefined,
151
151
  });
152
152
  // Get geo options for fiat
@@ -261,7 +261,7 @@ function useAnyspendFlow({ paymentType = "crypto", recipientAddress, loadOrder,
261
261
  selectedFiatPaymentMethod,
262
262
  setSelectedFiatPaymentMethod,
263
263
  // Recipient
264
- selectedRecipientAddress,
264
+ selectedRecipientAddress: effectiveRecipientAddress,
265
265
  setSelectedRecipientAddress,
266
266
  recipientName,
267
267
  globalAddress,
@@ -11,6 +11,7 @@ const CryptoPaymentMethod_1 = require("../components/common/CryptoPaymentMethod"
11
11
  function useConnectedWalletDisplay(selectedCryptoPaymentMethod) {
12
12
  const { connectedEOAWallet, connectedSmartWallet } = (0, react_1.useAccountWallet)();
13
13
  const { address: wagmiAddress, isConnected: wagmiWalletIsConnected } = (0, wagmi_1.useAccount)();
14
+ const globalWalletAddress = connectedSmartWallet?.getAccount()?.address;
14
15
  // Helper function to check if two addresses are the same
15
16
  const isSameAddress = (addr1, addr2) => {
16
17
  if (!addr1 || !addr2)
@@ -19,7 +20,7 @@ function useConnectedWalletDisplay(selectedCryptoPaymentMethod) {
19
20
  };
20
21
  // Check if connectedEOAWallet and wagmi wallet represent the same wallet
21
22
  const connectedEOAAddress = connectedEOAWallet?.getAccount()?.address;
22
- const isWalletDuplicated = isSameAddress(connectedEOAAddress, wagmiAddress);
23
+ const isWalletDuplicated = isSameAddress(connectedEOAAddress, wagmiAddress) || isSameAddress(globalWalletAddress, wagmiAddress);
23
24
  // Determine which wallet to show (prefer connectedEOAWallet if both exist and are the same)
24
25
  const shouldShowConnectedEOA = !!connectedEOAWallet;
25
26
  const shouldShowWagmiWallet = wagmiWalletIsConnected && (!isWalletDuplicated || !connectedEOAWallet);
@@ -0,0 +1,52 @@
1
+ interface UseRecipientAddressStateProps {
2
+ /** Fixed recipient address from props (highest priority) */
3
+ recipientAddressFromProps?: string;
4
+ /** Connected wallet address from payment method */
5
+ walletAddress?: string;
6
+ /** Global account address */
7
+ globalAddress?: string;
8
+ }
9
+ interface UseRecipientAddressStateResult {
10
+ /** User explicitly selected recipient address (undefined means no explicit selection) */
11
+ selectedRecipientAddress: string | undefined;
12
+ /** Function to update the user-selected recipient address */
13
+ setSelectedRecipientAddress: (address: string | undefined) => void;
14
+ /** Effective recipient address (follows priority: props > user selection > wallet/global) */
15
+ effectiveRecipientAddress: string | undefined;
16
+ /** Reset recipient address state */
17
+ resetRecipientAddress: () => void;
18
+ }
19
+ /**
20
+ * Custom hook to manage recipient address state with automatic priority handling:
21
+ *
22
+ * **Priority System:**
23
+ * 1. `recipientAddressFromProps` - Fixed recipient from component props (highest priority)
24
+ * 2. `selectedRecipientAddress` - User's explicit manual selection
25
+ * 3. `walletAddress` or `globalAddress` - Auto-selected fallback
26
+ *
27
+ * **Key Features:**
28
+ * - Automatically manages recipient address based on priority
29
+ * - Preserves user's manual selections
30
+ * - Updates automatically when wallet/global address changes (if no manual selection)
31
+ * - Derived value approach - no useEffect needed, no stale state bugs
32
+ *
33
+ * @example
34
+ * ```tsx
35
+ * const {
36
+ * selectedRecipientAddress,
37
+ * setSelectedRecipientAddress,
38
+ * effectiveRecipientAddress,
39
+ * resetRecipientAddress
40
+ * } = useRecipientAddressState({
41
+ * recipientAddressFromProps,
42
+ * walletAddress,
43
+ * globalAddress,
44
+ * });
45
+ *
46
+ * // Use effectiveRecipientAddress for display and operations
47
+ * // Use setSelectedRecipientAddress when user explicitly selects
48
+ * // Call resetRecipientAddress when switching tabs or going back
49
+ * ```
50
+ */
51
+ export declare function useRecipientAddressState({ recipientAddressFromProps, walletAddress, globalAddress, }?: UseRecipientAddressStateProps): UseRecipientAddressStateResult;
52
+ export {};
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useRecipientAddressState = useRecipientAddressState;
4
+ const react_1 = require("react");
5
+ /**
6
+ * Custom hook to manage recipient address state with automatic priority handling:
7
+ *
8
+ * **Priority System:**
9
+ * 1. `recipientAddressFromProps` - Fixed recipient from component props (highest priority)
10
+ * 2. `selectedRecipientAddress` - User's explicit manual selection
11
+ * 3. `walletAddress` or `globalAddress` - Auto-selected fallback
12
+ *
13
+ * **Key Features:**
14
+ * - Automatically manages recipient address based on priority
15
+ * - Preserves user's manual selections
16
+ * - Updates automatically when wallet/global address changes (if no manual selection)
17
+ * - Derived value approach - no useEffect needed, no stale state bugs
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * const {
22
+ * selectedRecipientAddress,
23
+ * setSelectedRecipientAddress,
24
+ * effectiveRecipientAddress,
25
+ * resetRecipientAddress
26
+ * } = useRecipientAddressState({
27
+ * recipientAddressFromProps,
28
+ * walletAddress,
29
+ * globalAddress,
30
+ * });
31
+ *
32
+ * // Use effectiveRecipientAddress for display and operations
33
+ * // Use setSelectedRecipientAddress when user explicitly selects
34
+ * // Call resetRecipientAddress when switching tabs or going back
35
+ * ```
36
+ */
37
+ function useRecipientAddressState({ recipientAddressFromProps, walletAddress, globalAddress, } = {}) {
38
+ // selectedRecipientAddress: explicitly selected by user (undefined means no explicit selection)
39
+ const [selectedRecipientAddress, setSelectedRecipientAddress] = (0, react_1.useState)(undefined);
40
+ // The effective recipient address, derived on each render, respecting priority.
41
+ const effectiveRecipientAddress = recipientAddressFromProps || selectedRecipientAddress || walletAddress || globalAddress;
42
+ // Helper function to reset user's manual selection.
43
+ const resetRecipientAddress = () => {
44
+ setSelectedRecipientAddress(undefined);
45
+ };
46
+ return {
47
+ selectedRecipientAddress,
48
+ setSelectedRecipientAddress,
49
+ effectiveRecipientAddress,
50
+ resetRecipientAddress,
51
+ };
52
+ }
@@ -204,6 +204,11 @@ function useAuthentication(partnerId) {
204
204
  client: thirdweb_1.client,
205
205
  wallets: [wallet],
206
206
  onConnect,
207
+ onTimeout: () => {
208
+ logout().catch(error => {
209
+ debug("@@useAuthentication:logout on timeout failed", { error });
210
+ });
211
+ },
207
212
  });
208
213
  /**
209
214
  * useAutoConnectLoading starts as false