fix: solana wallet bugs and security issues (#3484)

* fix android CI

* fix: duplicate outgoing tx for jup swaps and stuck pending state

* fix solana security risk by handling duplicate token symbols in wallet transactions

* feat: implement additional cost handling for pending transactions in Solana wallet.

* fix: Items on security audit list for solana wallet

* refactor: streamline fee payer index handling and improve error logging

* fix: verifySignature for solana and handle wrong mint on default token

* fix: token decimals defaulting to zero and breaking amount parsing in solana

* fix: use token mask in tx history

* refactor: apply lint to modified code

* fix: merge conflicts

* fix: use Money and mint decimals when parsing sol swaps

* test: add unit tests for SPL token amount handling and parsing

* test: add more tests

* fix: update decimal handling for fetched token and remove unused fields
This commit is contained in:
David Adegoke
2026-08-24 23:21:29 +03:00
committed by GitHub
parent f97e09cfc5
commit 703cc22b33
52 changed files with 687 additions and 373 deletions
+20 -4
View File
@@ -336,6 +336,18 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
@observable
PendingTransaction? pendingTransaction;
String? get pendingTransactionAdditionalCostNotice {
final additionalCost = pendingTransaction?.additionalCost;
if (additionalCost == null) {
return null;
}
return S.current.recipient_account_creation_fee(
_appStore.amountParsingProxy.asDisplayStringWithSymbol(additionalCost),
);
}
@computed
String get balance {
if (walletType == WalletType.litecoin && coinTypeToSpendFrom == UnspentCoinType.mweb) {
@@ -1179,11 +1191,11 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
await sharedPreferences.setString(PreferencesKey.backgroundSyncLastTrigger(wallet.name),
DateTime.now().add(Duration(minutes: 1)).toIso8601String());
} catch (e) {
if (e is JupiterSwapFailedException) {
await _updateSolanaTrade(signature: e.signature, isSuccess: false);
}
state = FailureState(translateErrorMessage(e, wallet.type, wallet.currency));
await _updateSolanaTrade(signature: '', isSuccess: false);
final failedSignature = e is JupiterSwapFailedException ? e.signature : "";
await _updateSolanaTrade(signature: failedSignature, isSuccess: false);
}
}
@@ -1509,6 +1521,10 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
return S.current.solana_no_associated_token_account_exception;
}
if (error is AmbiguousTokenSymbolException) {
return S.current.ambiguous_token_symbol_exception(error.symbol);
}
if (errorMessage.contains('found no record of a prior credit')) {
return S.current.insufficient_funds_for_tx;
}