diff --git a/src/navigation/services/components/externalServicesWalletSelector.tsx b/src/navigation/services/components/externalServicesWalletSelector.tsx index c0e9d3790..24ff391ea 100644 --- a/src/navigation/services/components/externalServicesWalletSelector.tsx +++ b/src/navigation/services/components/externalServicesWalletSelector.tsx @@ -113,6 +113,7 @@ interface ExternalServicesWalletSelectorScreenProps { sellCryptoSupportedCoinsFullObj?: SellCryptoCoin[] | undefined; onWalletSelected?: (wallet: Wallet) => void; fromWallet?: Wallet; + fromAccount?: {keyId: string; accountAddress: string}; // used when entering from an EVM/SVM account (AccountDetails) currencyAbbreviation?: string | undefined; // used from charts and deeplinks. chain?: string | undefined; // used from charts and deeplinks. partner?: BuyCryptoExchangeKey | undefined; // used from deeplinks. @@ -131,6 +132,7 @@ const ExternalServicesWalletSelector: React.FC< sellCryptoSupportedCoins, onWalletSelected, fromWallet, + fromAccount, currencyAbbreviation, chain, loading, @@ -188,6 +190,22 @@ const ExternalServicesWalletSelector: React.FC< } }; + const isWalletBuySupported = (wallet: Wallet): boolean => { + return ( + wallet.credentials && + wallet.network === 'livenet' && + wallet.isComplete() && + !wallet.hideWallet && + !wallet.hideWalletByAccount && + buyCryptoSupportedCoins.includes( + getExternalServiceSymbol( + wallet.currencyAbbreviation.toLowerCase(), + wallet.chain, + ), + ) + ); + }; + const selectFirstAvailableWallet = async () => { const keysList: Key[] = Object.values(allKeys).filter( key => key.backupComplete, @@ -199,6 +217,47 @@ const ExternalServicesWalletSelector: React.FC< return; } + if ( + context === 'buyCrypto' && + !preSetWallet?.id && + !fromCurrencyAbbreviation + ) { + let scopedWallets: Wallet[]; + if (fromAccount?.keyId && fromAccount?.accountAddress) { + const accountKey = keysList.find(k => k.id === fromAccount.keyId); + scopedWallets = (accountKey?.wallets || []).filter( + w => w.receiveAddress === fromAccount.accountAddress, + ); + } else { + scopedWallets = keysList.flatMap(k => k.wallets || []); + } + const candidateWallets = scopedWallets.filter(isWalletBuySupported); + + const lastPurchaseWalletId = buyCryptoOpts?.lastPurchaseData?.walletId; + const lastUsedWallet = lastPurchaseWalletId + ? candidateWallets.find(w => w.id === lastPurchaseWalletId) + : undefined; + if (lastUsedWallet) { + setWallet(lastUsedWallet); + return; + } + + const fundedWallets = candidateWallets.filter( + w => (w.balance?.sat || 0) > 0, + ); + if (fundedWallets[0]) { + const [highestBalanceWallet] = orderBy( + fundedWallets, + w => w.balance?.fiat || 0, + 'desc', + ); + _setSelectedWallet(highestBalanceWallet); + return; + } + + return; + } + if (preSetWallet?.id || buyCryptoOpts?.lastPurchaseData?.walletId) { // Selected wallet from Wallet Details let fromWalletData; diff --git a/src/navigation/services/screens/BuyAndSellRoot.tsx b/src/navigation/services/screens/BuyAndSellRoot.tsx index 342e724ca..fa075b983 100644 --- a/src/navigation/services/screens/BuyAndSellRoot.tsx +++ b/src/navigation/services/screens/BuyAndSellRoot.tsx @@ -465,6 +465,7 @@ export interface BuyAndSellRootProps { context: ExternalServicesContext; fromWallet?: Wallet; + fromAccount?: {keyId: string; accountAddress: string}; // used when entering from an EVM/SVM account (AccountDetails) amount?: number; // deeplink params are strings, ensure this is number so offers will work currencyAbbreviation?: string; // used from charts and deeplinks. chain?: string; // used from charts and deeplinks. @@ -531,6 +532,7 @@ const BuyAndSellRoot = ({ // Real route params const context = route.params?.context; const fromWallet = route.params?.fromWallet; + const fromAccount = route.params?.fromAccount; const fromAmount = useMemo(() => { const DEFAULT_USD_VALUE = 200; @@ -4154,6 +4156,7 @@ const BuyAndSellRoot = ({ sellCryptoSupportedCoinsFullObj ?? [] } fromWallet={fromWallet} + fromAccount={fromAccount} currencyAbbreviation={fromCurrencyAbbreviation} chain={fromChain} partner={preSetPartner} diff --git a/src/navigation/wallet/screens/AccountDetails.tsx b/src/navigation/wallet/screens/AccountDetails.tsx index 868aa066e..f9059294e 100644 --- a/src/navigation/wallet/screens/AccountDetails.tsx +++ b/src/navigation/wallet/screens/AccountDetails.tsx @@ -1530,6 +1530,10 @@ const AccountDetails: React.FC = ({route}) => { ); navigation.navigate(ExternalServicesScreens.ROOT_BUY_AND_SELL, { context: 'buyCrypto', + fromAccount: { + keyId, + accountAddress: selectedAccountAddress, + }, }); }, }}