From 86497d7b24bd82ff34475d53258ed935cfc9103d Mon Sep 17 00:00:00 2001 From: Tomas Martykan Date: Thu, 23 Jan 2025 09:49:49 +0100 Subject: [PATCH 1/3] fix(suite): solana account.misc may be undefined --- suite-common/wallet-core/src/accounts/accountsReducer.ts | 4 ++-- suite-common/wallet-core/src/send/sendFormSolanaThunks.ts | 2 +- suite-common/wallet-types/src/account.ts | 2 +- suite-common/wallet-utils/src/solanaStakingUtils.ts | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/suite-common/wallet-core/src/accounts/accountsReducer.ts b/suite-common/wallet-core/src/accounts/accountsReducer.ts index 1b074c3f955..0a90f01c410 100644 --- a/suite-common/wallet-core/src/accounts/accountsReducer.ts +++ b/suite-common/wallet-core/src/accounts/accountsReducer.ts @@ -474,13 +474,13 @@ export const selectIsDeviceNotEmpty = createMemoizedSelector( ); export const selectSolStakingAccounts = createMemoizedSelector([selectAccountByKey], account => { - if (!account || account.networkType !== 'solana') return null; + if (!account?.misc || account.networkType !== 'solana') return null; return account.misc.solStakingAccounts ?? []; }); export const selectSolAccountHasStaked = createMemoizedSelector([selectAccountByKey], account => { - if (!account || account.networkType !== 'solana') return false; + if (!account?.misc || account.networkType !== 'solana') return false; return !!account.misc.solStakingAccounts?.length; }); diff --git a/suite-common/wallet-core/src/send/sendFormSolanaThunks.ts b/suite-common/wallet-core/src/send/sendFormSolanaThunks.ts index 9170850fbb2..459d42d5415 100644 --- a/suite-common/wallet-core/src/send/sendFormSolanaThunks.ts +++ b/suite-common/wallet-core/src/send/sendFormSolanaThunks.ts @@ -226,7 +226,7 @@ export const composeSolanaTransactionFeeLevelsThunk = createThunk< output, level, decimals, - account.misc.rent ?? 0, + account.misc?.rent ?? 0, tokenInfo, ), ); diff --git a/suite-common/wallet-types/src/account.ts b/suite-common/wallet-types/src/account.ts index 0c557cab25c..ec329037bc3 100644 --- a/suite-common/wallet-types/src/account.ts +++ b/suite-common/wallet-types/src/account.ts @@ -68,7 +68,7 @@ type AccountNetworkSpecific = } | { networkType: 'solana'; - misc: { + misc?: { rent?: number; solStakingAccounts?: SolanaStakingAccount[]; solEpoch?: number; diff --git a/suite-common/wallet-utils/src/solanaStakingUtils.ts b/suite-common/wallet-utils/src/solanaStakingUtils.ts index 90f36684211..9123c17b1b4 100644 --- a/suite-common/wallet-utils/src/solanaStakingUtils.ts +++ b/suite-common/wallet-utils/src/solanaStakingUtils.ts @@ -71,7 +71,7 @@ export const calculateTotalSolStakingBalance = (stakingAccounts: SolanaStakingAc }; export const getSolAccountTotalStakingBalance = (account: Account) => { - if (!account || account.networkType !== 'solana') { + if (!account?.misc || account.networkType !== 'solana') { return null; } @@ -112,7 +112,7 @@ interface StakingAccountWithStatus extends SolDelegation { export const getSolanaStakingAccountsWithStatus = ( account: Account, ): StakingAccountWithStatus[] | null => { - if (account.networkType !== 'solana') return null; + if (!account.misc || account.networkType !== 'solana') return null; const { solStakingAccounts, solEpoch } = account.misc; if (!solStakingAccounts?.length || !solEpoch) return null; From 2b85a29c695ac451a60927158ea0e05e298f3957 Mon Sep 17 00:00:00 2001 From: Tomas Martykan Date: Thu, 23 Jan 2025 09:50:32 +0100 Subject: [PATCH 2/3] fix(blockchain-link): don't log error on solana rpc channel closed --- packages/blockchain-link/src/workers/solana/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/blockchain-link/src/workers/solana/index.ts b/packages/blockchain-link/src/workers/solana/index.ts index 29f80bb4bbd..c6a763e2b35 100644 --- a/packages/blockchain-link/src/workers/solana/index.ts +++ b/packages/blockchain-link/src/workers/solana/index.ts @@ -615,12 +615,13 @@ const handleAccountNotification = async ( }); } } catch (error) { - console.error('Solana subscription error:', error); if (isSolanaError(error, SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED)) { // The WS was closed, we should unsubscribe if (account.subscriptionId) abortSubscription(account.subscriptionId); state.removeAccounts([account]); context.onNetworkDisconnect(); + } else { + console.error('Solana subscription error:', error); } } }; From 9902f9d27f01689e53adc9ed52aae55c1afb7f2b Mon Sep 17 00:00:00 2001 From: Tomas Martykan Date: Thu, 23 Jan 2025 10:14:20 +0100 Subject: [PATCH 3/3] fix(suite): subscribe to solana blocks in coinmarket form --- .../form/useCoinmarketExchangeForm.ts | 4 ++++ .../coinmarket/form/useCoinmarketSellForm.ts | 4 ++++ .../wallet/form/useSolanaSubscribeBlocks.ts | 22 +++++++++++++++++++ .../src/hooks/wallet/useSendFormCompose.ts | 21 ++++-------------- 4 files changed, 34 insertions(+), 17 deletions(-) create mode 100644 packages/suite/src/hooks/wallet/form/useSolanaSubscribeBlocks.ts diff --git a/packages/suite/src/hooks/wallet/coinmarket/form/useCoinmarketExchangeForm.ts b/packages/suite/src/hooks/wallet/coinmarket/form/useCoinmarketExchangeForm.ts index 569e41bcff2..b4a09095778 100644 --- a/packages/suite/src/hooks/wallet/coinmarket/form/useCoinmarketExchangeForm.ts +++ b/packages/suite/src/hooks/wallet/coinmarket/form/useCoinmarketExchangeForm.ts @@ -60,6 +60,7 @@ import { useCoinmarketFiatValues } from 'src/hooks/wallet/coinmarket/form/common import type { CryptoAmountLimitProps } from 'src/utils/suite/validation'; import { useCoinmarketExchangeQuotesFilter } from 'src/hooks/wallet/coinmarket/form/common/useCoinmarketExchangeQuotesFilter'; import { useCoinmarketPreviousRoute } from 'src/hooks/wallet/coinmarket/form/common/useCoinmarketPreviousRoute'; +import { useSolanaSubscribeBlocks } from 'src/hooks/wallet/form/useSolanaSubscribeBlocks'; import { useCoinmarketInitializer } from './common/useCoinmarketInitializer'; @@ -681,6 +682,9 @@ export const useCoinmarketExchangeForm = ({ }; }, []); + // Subscribe to blocks for Solana, since they are not fetched globally + useSolanaSubscribeBlocks(account); + return { type, ...methods, diff --git a/packages/suite/src/hooks/wallet/coinmarket/form/useCoinmarketSellForm.ts b/packages/suite/src/hooks/wallet/coinmarket/form/useCoinmarketSellForm.ts index 9bf4204ee90..acb85367740 100644 --- a/packages/suite/src/hooks/wallet/coinmarket/form/useCoinmarketSellForm.ts +++ b/packages/suite/src/hooks/wallet/coinmarket/form/useCoinmarketSellForm.ts @@ -56,6 +56,7 @@ import { useCoinmarketAccount } from 'src/hooks/wallet/coinmarket/form/common/us import { useCoinmarketInfo } from 'src/hooks/wallet/coinmarket/useCoinmarketInfo'; import type { AmountLimitProps } from 'src/utils/suite/validation'; import { useCoinmarketPreviousRoute } from 'src/hooks/wallet/coinmarket/form/common/useCoinmarketPreviousRoute'; +import { useSolanaSubscribeBlocks } from 'src/hooks/wallet/form/useSolanaSubscribeBlocks'; import { useCoinmarketInitializer } from './common/useCoinmarketInitializer'; @@ -657,6 +658,9 @@ export const useCoinmarketSellForm = ({ }; }, []); + // Subscribe to blocks for Solana, since they are not fetched globally + useSolanaSubscribeBlocks(account); + return { type, form: { diff --git a/packages/suite/src/hooks/wallet/form/useSolanaSubscribeBlocks.ts b/packages/suite/src/hooks/wallet/form/useSolanaSubscribeBlocks.ts new file mode 100644 index 00000000000..9bf5bea0597 --- /dev/null +++ b/packages/suite/src/hooks/wallet/form/useSolanaSubscribeBlocks.ts @@ -0,0 +1,22 @@ +import { useEffect } from 'react'; + +import TrezorConnect from '@trezor/connect'; +import { Account } from '@suite-common/wallet-types'; + +export const useSolanaSubscribeBlocks = (account: Account) => { + useEffect(() => { + if (account.networkType === 'solana') { + TrezorConnect.blockchainSubscribe({ + coin: account.symbol, + blocks: true, + }); + + return () => { + TrezorConnect.blockchainUnsubscribe({ + coin: account.symbol, + blocks: true, + }); + }; + } + }, [account]); +}; diff --git a/packages/suite/src/hooks/wallet/useSendFormCompose.ts b/packages/suite/src/hooks/wallet/useSendFormCompose.ts index 78890a4e4cb..e5a83f812a5 100644 --- a/packages/suite/src/hooks/wallet/useSendFormCompose.ts +++ b/packages/suite/src/hooks/wallet/useSendFormCompose.ts @@ -15,7 +15,7 @@ import { import { useDebounce } from '@trezor/react-utils'; import { isChanged } from '@suite-common/suite-utils'; import { findComposeErrors } from '@suite-common/wallet-utils'; -import TrezorConnect, { FeeLevel } from '@trezor/connect'; +import { FeeLevel } from '@trezor/connect'; import { COMPOSE_ERROR_TYPES } from '@suite-common/wallet-constants'; import { composeSendFormTransactionFeeLevelsThunk } from '@suite-common/wallet-core'; @@ -23,6 +23,7 @@ import { TranslationKey } from 'src/components/suite/Translation'; import { SendContextValues, UseSendFormState } from 'src/types/wallet/sendForm'; import { useTranslation } from '../suite'; +import { useSolanaSubscribeBlocks } from './form/useSolanaSubscribeBlocks'; type Props = UseFormReturn & { state: UseSendFormState; @@ -344,22 +345,8 @@ export const useSendFormCompose = ({ setLoading, ]); - useEffect(() => { - // Subscribe to blocks for Solana, since they are not fetched globally - if (state.account.networkType === 'solana') { - TrezorConnect.blockchainSubscribe({ - coin: state.account.symbol, - blocks: true, - }); - - return () => { - TrezorConnect.blockchainUnsubscribe({ - coin: state.account.symbol, - blocks: true, - }); - }; - } - }, [state.account]); + // Subscribe to blocks for Solana, since they are not fetched globally + useSolanaSubscribeBlocks(state.account); return { composeDraft,