dart format and a couple tweaks/fixes
What changed, and why it matters
This commit is mostly code formatting, but it includes two small functional changes in the Solana custom-token screen: it now safely parses the 'decimals' value from fetched metadata instead of assuming it is a whole number, and it reads wallet info once with a non-reactive lookup rather than setting up a live watch. These are minor robustness fixes; there is no clear security vulnerability being patched.
No urgent action. Treat as routine maintenance. If reviewing, verify that the token metadata API can never return a non-numeric decimals string that would silently fall back to 6, and consider adding explicit user-facing validation for decimals input.
Security signals we found
Type-safety hardening: metadata decimals parsed with int.tryParse instead of unsafe cast
Flutter lifecycle fix: ref.watch replaced with ref.read in initState to avoid reactive rebuild issues
No changes to validation, signing, key storage, or network trust boundaries
Evidence from the diff
The diff is dominated by dart format reformatting across four files. The substantive changes are in add_custom_solana_token_view.dart: (1) decimals: metadata['decimals'] as int? ?? 6 is replaced with decimals: int.tryParse(metadata['decimals']?.toString() ?? '') ?? 6, making token-decimal parsing tolerant of string-typed API responses; and (2) ref.watch(pWalletInfo(...)) is changed to ref.read(pWalletInfo(...)) inside initState, removing an unintended reactive listener in a build-unsafe lifecycle method. The model files only add @override annotations on fields inherited from Contract and formatting. No cryptographic, authentication, or storage-security logic is changed.
Changed components
lib/pages/add_wallet_views/add_token_view/add_custom_solana_token_view.dartlib/models/isar/models/solana/spl_token.dartlib/models/isar/models/ethereum/eth_contract.dartlib/db/isar/main_db.dartInspect captured patch +60 / −56
diff --git a/lib/db/isar/main_db.dart b/lib/db/isar/main_db.dart
index 4245729..a593647 100644
--- a/lib/db/isar/main_db.dart
+++ b/lib/db/isar/main_db.dart
@@ -641,8 +641,7 @@ class MainDB {
return await isar.splTokens.put(token);
});
- Future<void> putSplTokens(List<SplToken> tokens) =>
- isar.writeTxn(() async {
- await isar.splTokens.putAll(tokens);
- });
+ Future<void> putSplTokens(List<SplToken> tokens) => isar.writeTxn(() async {
+ await isar.splTokens.putAll(tokens);
+ });
}
diff --git a/lib/models/isar/models/ethereum/eth_contract.dart b/lib/models/isar/models/ethereum/eth_contract.dart
index adaec31..ad98f29 100644
--- a/lib/models/isar/models/ethereum/eth_contract.dart
+++ b/lib/models/isar/models/ethereum/eth_contract.dart
@@ -9,6 +9,7 @@
*/
import 'package:isar_community/isar.dart';
+
import '../contract.dart';
part 'eth_contract.g.dart';
@@ -26,13 +27,17 @@ class EthContract extends Contract {
Id id = Isar.autoIncrement;
+ @override
@Index(unique: true, replace: true)
late final String address;
+ @override
late final String name;
+ @override
late final String symbol;
+ @override
late final int decimals;
late final String? abi;
@@ -50,21 +55,16 @@ class EthContract extends Contract {
List<String>? walletIds,
String? abi,
String? otherData,
- }) =>
- EthContract(
- address: address ?? this.address,
- name: name ?? this.name,
- symbol: symbol ?? this.symbol,
- decimals: decimals ?? this.decimals,
- type: type ?? this.type,
- abi: abi ?? this.abi,
- )..id = id ?? this.id;
+ }) => EthContract(
+ address: address ?? this.address,
+ name: name ?? this.name,
+ symbol: symbol ?? this.symbol,
+ decimals: decimals ?? this.decimals,
+ type: type ?? this.type,
+ abi: abi ?? this.abi,
+ )..id = id ?? this.id;
}
// Used in Isar db and stored there as int indexes so adding/removing values
// in this definition should be done extremely carefully in production
-enum EthContractType {
- unknown,
- erc20,
- erc721;
-}
+enum EthContractType { unknown, erc20, erc721 }
diff --git a/lib/models/isar/models/solana/spl_token.dart b/lib/models/isar/models/solana/spl_token.dart
index 736ee31..218001d 100644
--- a/lib/models/isar/models/solana/spl_token.dart
+++ b/lib/models/isar/models/solana/spl_token.dart
@@ -8,6 +8,7 @@
*/
import 'package:isar_community/isar.dart';
+
import '../contract.dart';
part 'spl_token.g.dart';
@@ -25,13 +26,17 @@ class SplToken extends Contract {
Id id = Isar.autoIncrement;
+ @override
@Index(unique: true, replace: true)
late final String address; // Mint address.
+ @override
late final String name;
+ @override
late final String symbol;
+ @override
late final int decimals;
late final String? logoUri;
@@ -46,13 +51,12 @@ class SplToken extends Contract {
int? decimals,
String? logoUri,
String? metadataAddress,
- }) =>
- SplToken(
- address: address ?? this.address,
- name: name ?? this.name,
- symbol: symbol ?? this.symbol,
- decimals: decimals ?? this.decimals,
- logoUri: logoUri ?? this.logoUri,
- metadataAddress: metadataAddress ?? this.metadataAddress,
- )..id = id ?? this.id;
+ }) => SplToken(
+ address: address ?? this.address,
+ name: name ?? this.name,
+ symbol: symbol ?? this.symbol,
+ decimals: decimals ?? this.decimals,
+ logoUri: logoUri ?? this.logoUri,
+ metadataAddress: metadataAddress ?? this.metadataAddress,
+ )..id = id ?? this.id;
}
diff --git a/lib/pages/add_wallet_views/add_token_view/add_custom_solana_token_view.dart b/lib/pages/add_wallet_views/add_token_view/add_custom_solana_token_view.dart
index 9c3b2f9..c99816d 100644
--- a/lib/pages/add_wallet_views/add_token_view/add_custom_solana_token_view.dart
+++ b/lib/pages/add_wallet_views/add_token_view/add_custom_solana_token_view.dart
@@ -30,10 +30,7 @@ import '../../../widgets/desktop/secondary_button.dart';
import '../../../widgets/stack_dialog.dart';
class AddCustomSolanaTokenView extends ConsumerStatefulWidget {
- const AddCustomSolanaTokenView({
- super.key,
- this.walletId,
- });
+ const AddCustomSolanaTokenView({super.key, this.walletId});
static const routeName = "/addCustomSolanaToken";
@@ -71,7 +68,7 @@ class _AddCustomSolanaTokenViewState
// Check if token is already in the wallet.
if (widget.walletId != null) {
- final walletInfo = ref.watch(pWalletInfo(widget.walletId!));
+ final walletInfo = ref.read(pWalletInfo(widget.walletId!));
final allTokenMints = <String>{
...walletInfo.solanaTokenMintAddresses,
...walletInfo.solanaCustomTokenMintAddresses,
@@ -119,7 +116,8 @@ class _AddCustomSolanaTokenViewState
Expanded(
child: PrimaryButton(
label: "OK",
- onPressed: () => Navigator.of(dialogContext).pop(),
+ onPressed: () =>
+ Navigator.of(dialogContext).pop(),
),
),
],
@@ -149,10 +147,7 @@ class _AddCustomSolanaTokenViewState
builder: (child) => DesktopDialog(
maxWidth: 500,
maxHeight: double.infinity,
- child: Padding(
- padding: const EdgeInsets.all(32),
- child: child,
- ),
+ child: Padding(padding: const EdgeInsets.all(32), child: child),
),
child: ConditionalParent(
condition: !Util.isDesktop,
@@ -166,7 +161,8 @@ class _AddCustomSolanaTokenViewState
),
const SizedBox(height: 8),
Text(
- "Please enter a valid Solana SPL token mint address (base58 encoded, ~44 characters).",
+ "Please enter a valid Solana SPL token mint address "
+ "(base58 encoded, ~44 characters).",
style: STextStyles.smallMed14(context),
),
const SizedBox(height: 20),
@@ -192,13 +188,19 @@ class _AddCustomSolanaTokenViewState
}
// Fetch token metadata.
- debugPrint('[ADD_CUSTOM_SOLANA_TOKEN] Fetching metadata for mint: ${mintController.text.trim()}');
- final response =
- await tokenApi.fetchTokenMetadataByMint(mintController.text.trim());
+ debugPrint(
+ '[ADD_CUSTOM_SOLANA_TOKEN] Fetching metadata for'
+ ' mint: ${mintController.text.trim()}',
+ );
+ final response = await tokenApi.fetchTokenMetadataByMint(
+ mintController.text.trim(),
+ );
if (!mounted) return;
- debugPrint('[ADD_CUSTOM_SOLANA_TOKEN] Metadata response: ${response.value}');
+ debugPrint(
+ '[ADD_CUSTOM_SOLANA_TOKEN] Metadata response: ${response.value}',
+ );
if (response.value != null && response.value!.isNotEmpty) {
final metadata = response.value!;
@@ -206,7 +208,7 @@ class _AddCustomSolanaTokenViewState
address: mintController.text.trim(),
name: metadata['name'] as String? ?? 'Unknown Token',
symbol: metadata['symbol'] as String? ?? '???',
- decimals: metadata['decimals'] as int? ?? 6,
+ decimals: int.tryParse(metadata['decimals']?.toString() ?? "") ?? 6,
logoUri: metadata['logoUri'] as String?,
);
@@ -222,12 +224,15 @@ class _AddCustomSolanaTokenViewState
debugPrint('[ADD_CUSTOM_SOLANA_TOKEN] Metadata found, fields populated');
} else {
// Token not found, allow user to manually enter details.
- debugPrint('[ADD_CUSTOM_SOLANA_TOKEN] Metadata not found, enabling manual entry');
+ debugPrint(
+ '[ADD_CUSTOM_SOLANA_TOKEN] Metadata not found, enabling manual entry',
+ );
nameController.text = "";
symbolController.text = "";
decimalsController.text = "";
- // Enable fields for manual entry and allow user to create token with custom values.
+ // Enable fields for manual entry and allow user to create token with
+ // custom values.
setState(() {
enableSubFields = true;
currentToken = SplToken(
@@ -241,7 +246,8 @@ class _AddCustomSolanaTokenViewState
addTokenButtonEnabled = true;
});
- // Show dialog for manual entry & alert the user they need to enter details manually.
+ // Show dialog for manual entry & alert the user they need to enter
+ // details manually.
if (mounted) {
unawaited(
showDialog<void>(
@@ -251,10 +257,7 @@ class _AddCustomSolanaTokenViewState
builder: (child) => DesktopDialog(
maxWidth: 500,
maxHeight: double.infinity,
- child: Padding(
- padding: const EdgeInsets.all(32),
- child: child,
- ),
+ child: Padding(padding: const EdgeInsets.all(32), child: child),
),
child: ConditionalParent(
condition: !Util.isDesktop,
@@ -268,7 +271,8 @@ class _AddCustomSolanaTokenViewState
),
const SizedBox(height: 8),
Text(
- "Could not fetch token metadata. Please enter the token details manually below.",
+ "Could not fetch token metadata. Please enter the token"
+ " details manually below.",
style: STextStyles.smallMed14(context),
),
const SizedBox(height: 20),
@@ -371,10 +375,7 @@ class _AddCustomSolanaTokenViewState
),
),
SizedBox(height: isDesktop ? 16 : 8),
- PrimaryButton(
- label: "Search",
- onPressed: _searchTokenMetadata,
- ),
+ PrimaryButton(label: "Search", onPressed: _searchTokenMetadata),
SizedBox(height: isDesktop ? 16 : 8),
TextField(
enabled: enableSubFields,
@@ -497,7 +498,7 @@ class _AddCustomSolanaTokenViewState
: currentToken!.symbol,
decimals: decimalsController.text.isNotEmpty
? int.tryParse(decimalsController.text) ??
- currentToken!.decimals
+ currentToken!.decimals
: currentToken!.decimals,
);
Navigator.of(context).pop(finalToken);
Why this scored 23/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.