What changed, and why it matters
This commit fixes a navigation bug when users open a Solana token wallet. Previously, the app created a Solana token wallet object directly in two places, which could leave important wallet services (preferences, node connection, secure storage, and database) uninitialized. The fix adds a single factory helper that copies those services from the main Solana wallet into the token wallet before use. There is no direct evidence this is a security vulnerability, but missing service wiring in a wallet app can lead to crashes, incorrect state, or unexpected behavior.
Treat as a routine functional bug fix. Review whether any other token wallet types (e.g., Ethereum token wallets) are instantiated directly outside of a proper factory and could suffer from the same uninitialized-service issue. No immediate security response is indicated by the diff alone.
Security signals we found
Missing service initialization in wallet object construction
Refactoring to centralize wallet instantiation
UI/navigation bug fix with wallet lifecycle implications
Evidence from the diff
The patch introduces Wallet.loadSolTokenWallet(), a static factory that constructs a SolanaTokenWallet from a SolanaWallet and SolContract while also copying prefs, nodeService, secureStorageInterface, and mainDB from the parent wallet. Both sol_token_select_item.dart and wallet_card.dart are updated to use this factory instead of directly instantiating SolanaTokenWallet. The change centralizes initialization and ensures the token wallet has the same backing services as the parent wallet. No cryptographic, authorization, or input-validation changes are present.
Changed components
lib/pages/token_view/sub_widgets/sol_token_select_item.dartlib/wallets/wallet/wallet.dartlib/widgets/wallet_card.dartInspect captured patch +30 / −9
diff --git a/lib/pages/token_view/sub_widgets/sol_token_select_item.dart b/lib/pages/token_view/sub_widgets/sol_token_select_item.dart
index b7a149b..498ef02 100644
--- a/lib/pages/token_view/sub_widgets/sol_token_select_item.dart
+++ b/lib/pages/token_view/sub_widgets/sol_token_select_item.dart
@@ -24,6 +24,7 @@ import '../../../wallets/isar/providers/solana/current_sol_token_wallet_provider
import '../../../wallets/isar/providers/solana/sol_token_balance_provider.dart';
import '../../../wallets/wallet/impl/solana_wallet.dart';
import '../../../wallets/wallet/impl/sub_wallets/solana_token_wallet.dart';
+import '../../../wallets/wallet/wallet.dart';
import '../../../widgets/desktop/primary_button.dart';
import '../../../widgets/dialogs/basic_dialog.dart';
import '../../../widgets/icon_widgets/sol_token_icon.dart';
@@ -103,10 +104,12 @@ class _SolTokenSelectItemState extends ConsumerState<SolTokenSelectItem> {
return;
}
- ref.read(solanaTokenServiceStateProvider.state).state = SolanaTokenWallet(
- solanaWallet,
- widget.token,
- );
+ ref.read(solanaTokenServiceStateProvider.state).state =
+ Wallet.loadSolTokenWallet(
+ solWallet: solanaWallet,
+ contract: widget.token,
+ )
+ as SolanaTokenWallet;
final success = await showLoading<bool>(
whileFuture: _loadTokenWallet(context, ref),
diff --git a/lib/wallets/wallet/wallet.dart b/lib/wallets/wallet/wallet.dart
index 85002c1..1aa40ef 100644
--- a/lib/wallets/wallet/wallet.dart
+++ b/lib/wallets/wallet/wallet.dart
@@ -7,6 +7,7 @@ import 'package:mutex/mutex.dart';
import '../../db/isar/main_db.dart';
import '../../models/isar/models/blockchain_data/address.dart';
import '../../models/isar/models/ethereum/eth_contract.dart';
+import '../../models/isar/models/solana/sol_contract.dart';
import '../../models/keys/view_only_wallet_data.dart';
import '../../models/node_model.dart';
import '../../models/paymint/fee_object_model.dart';
@@ -48,16 +49,17 @@ import 'impl/salvium_wallet.dart';
import 'impl/solana_wallet.dart';
import 'impl/stellar_wallet.dart';
import 'impl/sub_wallets/eth_token_wallet.dart';
+import 'impl/sub_wallets/solana_token_wallet.dart';
import 'impl/tezos_wallet.dart';
import 'impl/wownero_wallet.dart';
import 'impl/xelis_wallet.dart';
import 'intermediate/cryptonote_wallet.dart';
import 'wallet_mixin_interfaces/electrumx_interface.dart';
-import 'wallet_mixin_interfaces/spark_interface.dart';
import 'wallet_mixin_interfaces/mnemonic_interface.dart';
import 'wallet_mixin_interfaces/multi_address_interface.dart';
import 'wallet_mixin_interfaces/paynym_interface.dart';
import 'wallet_mixin_interfaces/private_key_interface.dart';
+import 'wallet_mixin_interfaces/spark_interface.dart';
import 'wallet_mixin_interfaces/view_only_option_interface.dart';
abstract class Wallet<T extends CryptoCurrency> {
@@ -286,6 +288,20 @@ abstract class Wallet<T extends CryptoCurrency> {
return wallet.._walletId = ethWallet.info.walletId;
}
+ static Wallet loadSolTokenWallet({
+ required SolanaWallet solWallet,
+ required SolContract contract,
+ }) {
+ final Wallet wallet = SolanaTokenWallet(solWallet, contract);
+
+ wallet.prefs = solWallet.prefs;
+ wallet.nodeService = solWallet.nodeService;
+ wallet.secureStorageInterface = solWallet.secureStorageInterface;
+ wallet.mainDB = solWallet.mainDB;
+
+ return wallet.._walletId = solWallet.info.walletId;
+ }
+
//============================================================================
// ========== Static Util ====================================================
diff --git a/lib/widgets/wallet_card.dart b/lib/widgets/wallet_card.dart
index f502d21..b6690b7 100644
--- a/lib/widgets/wallet_card.dart
+++ b/lib/widgets/wallet_card.dart
@@ -108,10 +108,12 @@ class SimpleWalletCard extends ConsumerWidget {
final old = ref.read(solanaTokenServiceStateProvider);
// exit previous if there is one
unawaited(old?.exit());
- ref.read(solanaTokenServiceStateProvider.state).state = SolanaTokenWallet(
- wallet as SolanaWallet,
- token,
- );
+ ref.read(solanaTokenServiceStateProvider.state).state =
+ Wallet.loadSolTokenWallet(
+ solWallet: wallet as SolanaWallet,
+ contract: token,
+ )
+ as SolanaTokenWallet;
try {
await ref.read(pCurrentSolanaTokenWallet)!.init();
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.