feat(spl): add Solana token storage and state mgmt providers
What changed, and why it matters
This commit adds new code to support Solana SPL tokens in Stack Wallet. It introduces a way to store token mint addresses in wallet metadata and two placeholder data providers for retrieving those addresses. The actual token detail fetching is left as a TODO and returns an empty list. There is no evidence of a security fix or vulnerability being addressed.
No security action required. Treat as routine feature scaffolding. If reviewing for broader security, verify that the eventual TODO implementation for fetching Solana token metadata validates RPC endpoints and token metadata sources.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit adds three pieces of Solana token scaffolding: (1) a solanaTokenMintAddresses getter and update method on WalletInfo backed by otherData, (2) a pSolanaWalletTokenAddresses Riverpod provider that exposes stored mint addresses, and (3) a pSolanaWalletTokens provider that currently returns an empty list with a TODO for metadata/API fetching. No input validation, serialization, network, or cryptographic changes are present. No security-relevant behavior is modified.
Changed components
lib/wallets/isar/models/wallet_info.dartlib/wallets/isar/providers/solana/sol_tokens_provider.dartlib/wallets/isar/providers/solana/sol_wallet_token_addresses_provider.dartInspect captured patch +78 / −0
diff --git a/lib/wallets/isar/models/wallet_info.dart b/lib/wallets/isar/models/wallet_info.dart
index 5b2d656..f4dbab5 100644
--- a/lib/wallets/isar/models/wallet_info.dart
+++ b/lib/wallets/isar/models/wallet_info.dart
@@ -75,6 +75,17 @@ class WalletInfo implements IsarId {
}
}
+ @ignore
+ List<String> get solanaTokenMintAddresses {
+ if (otherData[WalletInfoKeys.solanaTokenMintAddresses] is List) {
+ return List<String>.from(
+ otherData[WalletInfoKeys.solanaTokenMintAddresses] as List,
+ );
+ } else {
+ return [];
+ }
+ }
+
/// Special case for coins such as firo lelantus
@ignore
Balance get cachedBalanceSecondary {
@@ -396,6 +407,19 @@ class WalletInfo implements IsarId {
);
}
+ /// Update Solana token mint addresses and update the db.
+ Future<void> updateSolanaTokenMintAddresses({
+ required Set<String> newMintAddresses,
+ required Isar isar,
+ }) async {
+ await updateOtherData(
+ newEntries: {
+ WalletInfoKeys.solanaTokenMintAddresses: newMintAddresses.toList(),
+ },
+ isar: isar,
+ );
+ }
+
Future<void> setMwebEnabled({
required bool newValue,
required Isar isar,
@@ -524,4 +548,5 @@ abstract class WalletInfoKeys {
static const String mwebScanHeight = "mwebScanHeightKey";
static const String firoSparkUsedTagsCacheResetVersion =
"firoSparkUsedTagsCacheResetVersionKey";
+ static const String solanaTokenMintAddresses = "solanaTokenMintAddressesKey";
}
diff --git a/lib/wallets/isar/providers/solana/sol_tokens_provider.dart b/lib/wallets/isar/providers/solana/sol_tokens_provider.dart
new file mode 100644
index 0000000..1396a91
--- /dev/null
+++ b/lib/wallets/isar/providers/solana/sol_tokens_provider.dart
@@ -0,0 +1,30 @@
+/*
+ * This file is part of Stack Wallet.
+ *
+ * Copyright (c) 2025 Cypher Stack
+ * All Rights Reserved.
+ * The code is distributed under GPLv3 license, see LICENSE file for details.
+ *
+ */
+
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+
+/// Provides a list of Solana token mint addresses for a specific wallet.
+///
+/// This provider returns the list of Solana SPL token mint addresses
+/// that the wallet has selected. Token details are not currently persisted
+/// in the database - only the mint addresses are stored in WalletInfo's otherData.
+///
+/// Example usage:
+/// ```
+/// final tokenAddresses = ref.watch(pSolanaWalletTokenAddresses('wallet_id'));
+/// ```
+/// Note: For full token details (name, symbol, decimals), these would need to be
+/// fetched from the Solana token metadata or a token list API.
+final pSolanaWalletTokens = Provider.family<List<String>, String>(
+ (ref, walletId) {
+ // TODO: Implement token details fetching from Solana metadata or API.
+ // For now, just return an empty list as token details are not persisted.
+ return [];
+ },
+);
diff --git a/lib/wallets/isar/providers/solana/sol_wallet_token_addresses_provider.dart b/lib/wallets/isar/providers/solana/sol_wallet_token_addresses_provider.dart
new file mode 100644
index 0000000..defccf4
--- /dev/null
+++ b/lib/wallets/isar/providers/solana/sol_wallet_token_addresses_provider.dart
@@ -0,0 +1,23 @@
+/*
+ * This file is part of Stack Wallet.
+ *
+ * Copyright (c) 2025 Cypher Stack
+ * All Rights Reserved.
+ * The code is distributed under GPLv3 license, see LICENSE file for details.
+ *
+ */
+
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+
+import '../wallet_info_provider.dart';
+
+/// Provides the list of Solana SPL token mint addresses for a wallet.
+///
+/// This is a family provider that takes a walletId and returns the list of
+/// mint addresses from the WalletInfo's otherData.
+final pSolanaWalletTokenAddresses = Provider.family<List<String>, String>(
+ (ref, walletId) {
+ final walletInfo = ref.watch(pWalletInfo(walletId));
+ return walletInfo.solanaTokenMintAddresses;
+ },
+);
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.