fix: SPL token balance display for xstocks and non-6-decimal tokens (#3052)
David Adegoke committed
Mar 13, 2026 at 02:02 UTC
4d26b4ee6b42d2937faad4d8b6dec67410913148
3 files changed
+17
-11
cw_solana/lib/solana_balance.dart
+5
-2
@@ -7,12 +7,15 @@ class SolanaBalance extends Balance {
7
BigInt.from(int.tryParse(balance.toStringAsFixed(isToken ? 6 : 9).replaceFirst(".", "")) ?? 0),
8
BigInt.from(int.tryParse(balance.toStringAsFixed(isToken ? 6 : 9).replaceFirst(".", "")) ?? 0));
9
10
+ // Using raw amount from RPC to avoid decimals mismatch for SPL tokens.
11
+ SolanaBalance.forToken(BigInt rawAmount, double uiAmount)
12
+ : balance = uiAmount,
13
+ super(rawAmount, rawAmount);
14
+
15
final double balance;
16
12
- @override
17
String get formattedAdditionalBalance => _balanceFormatted();
18
15
- @override
19
String get formattedAvailableBalance => _balanceFormatted();
20
21
String _balanceFormatted() {
cw_solana/lib/solana_client.dart
+9
-7
@@ -111,22 +111,24 @@ class SolanaWalletClient {
111
return null;
112
}
113
114
- // Sum the balances of all accounts with the specified mint address
115
- double totalBalance = 0.0;
114
+ // Sum raw amounts and ui amounts across all token accounts
115
+ BigInt totalRaw = BigInt.zero;
116
+ double totalUi = 0.0;
117
118
for (var tokenAccount in tokenAccounts) {
119
final tokenAmountResult = await _provider!.request(
120
SolanaRPCGetTokenAccountBalance(account: tokenAccount.pubkey),
121
);
122
122
- final balance = tokenAmountResult.uiAmountString;
123
+ final raw = BigInt.tryParse(tokenAmountResult.amount) ?? BigInt.zero;
124
+ totalRaw += raw;
125
124
- final balanceAsDouble = double.tryParse(balance ?? '0.0') ?? 0.0;
125
-
126
- totalBalance += balanceAsDouble;
126
+ final ui = tokenAmountResult.uiAmount ??
127
+ (double.tryParse(tokenAmountResult.uiAmountString ?? '0') ?? 0.0);
128
+ totalUi += ui;
129
}
130
129
- return SolanaBalance(totalBalance, true);
131
+ return SolanaBalance.forToken(totalRaw, totalUi);
132
} catch (_) {
133
if (throwOnError) {
134
rethrow;
cw_solana/lib/solana_wallet.dart
+3
-2
@@ -588,7 +588,8 @@ abstract class SolanaWalletBase
588
for (final entry in results) {
589
final token = entry.key;
590
final fetchedBalance = entry.value;
591
- final currentBalance = balance[token] ?? SolanaBalance(0.0, true);
591
+ final currentBalance = balance[token] ??
592
+ SolanaBalance.forToken(BigInt.zero, 0.0);
593
balance[token] = fetchedBalance ?? currentBalance;
594
}
595
}
@@ -636,7 +637,7 @@ abstract class SolanaWalletBase
637
if (token.enabled) {
638
final tokenBalance = await _client.getSplTokenBalance(token.mintAddress, solanaAddress) ??
639
balance[token] ??
639
- SolanaBalance(0.0, true);
640
+ SolanaBalance.forToken(BigInt.zero, 0.0);
641
642
balance[token] = tokenBalance;
643
} else {