CakeWallet/lib/view_model/dashboard/home_settings_view_model.dart
Omar Hatem df3a26dc15
Zano with passphrase (#1971)
* CW-685 Add passphrase restore for xmr/wow (#1552)

* CW-685 Add passphrase restore for xmr/wow

* add support for polyseed passphrase

* disable 14 word seed passphrase (not supported in wownero-seed)
fix: Getting grayed screen on latest passphrase build after having restored a 14-word wownero seed (+passphrase) and attempting to restore a XMR seed, legacy or otherwise.

* fix pointer when restoring depracated wownero seed

* Fix polyseed encryption

* changes from review

* remove unused code

* add passphrase back to the screen
add passphrase to qr code backup export

* fix settings leaking through currencies on seed restore

* fix monero.com builds, make passphrase a getter on WalletBase

* add support for weird polyseed

* store passphrase for weird polyseed

* show encrypted seed only when passphrase is not empty

* force set restore height

* fix build issues

* fix build errors

* fix configure script

* print -> printV

* Update lib/view_model/wallet_keys_view_model.dart [skip ci]

* Update lib/view_model/wallet_keys_view_model.dart [skip ci]

* Update tool/configure.dart [skip ci]

* Update lib/view_model/wallet_new_vm.dart

* reuse existing passphrase field

* remove unused passphrase field

* make workflow run on pullrequests only [skip ci] [skip slack]

---------

Co-authored-by: Konstantin Ullrich <konstantinullrich12@gmail.com>
Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

* Zano (#1793)

* my experiments

* Inital code for Zano integration

* Added missing android log lib

* added dummy wallet & some zano implementation

* fixing api for zano

* fixed zano build script

* attempt tp fix namespace problem

* added copy script for Zano files

* changes for zano wallet

* last updates

* zano.dart test app

* wallet recovery

* added pending transfer, some cleanup of unused

* some cleanup

* send + receive qr code

* last upd

* updated build_zano.sh

* updated zano ApiCalls, removed dummy

* updated zano ApiCalls, removed dummy

* added logging for get status/get info

* restored old wallet.dart

* restoring original versions of files

* restoring original versions of files

* restored get_height_by_date.dart, removed unnecessary calls for zano get height

* restoring original versions

* added multiple destinations, send all flag; some refactoring

* logging

* removed the duplicate

* fixed syncing sync status, decimal division, safe null json parsing

* some fixes after merge

* added multibalance/asset support for zano (ui)

* adding/removing from whitelist

* transfers in different assets

* transfers for multiple destinations and send all, some refactoring

* whitelists, some refactoring

* added different digits (decimal points) for formatters, some refactoring

* open, create, restore wallet refactoring; whitelists

* whitelists

* getting and updating transaction list; restoring a wallet from QR code

* several attempts to close wallet

* some refactoring

* added seed phrase

* changed fields to BigInt, some fixes

* modified build scripts for android

* build scripts

* restored accidently removed cw_haven.dart

* inital ios integration(zano libs built)

* update in script

* latest changes

* Applied a patch for iOS build (Boost and Zano scripts)

* Removed zano.dart (script-generated) and some unnecessary files

* Revert "Removed zano.dart (script-generated) and some unnecessary files"

This reverts commit 367c86398e.

* Removed zano.dart (generated by scripts), some files restored to initial versions

* added timer library

* changed paths in build_zano.sh

* build_zano.sh

* edit_token_page.dart - removed flag skipZanoAddressValidation

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

* lib/core/address_validator.dart - updated zano address regex
lib/src/screens/dashboard/edit_token_page.dart - using AddressValidator().call

* fix zano build issues on android

* remove contrib/depends to save space

* move async call to a synchronouse one

* call sync call in isolate to make it async
generate framework for iOS as well
fix UR issues

* zano changes from monero_c repo

* update monero_c hash

* fix invalid zano imports, add support for linux, speed up CI builds

* update monero_c hash

* bump monero_c commit (yes, again, I know)

* fix wallet resttore, fix hardcoded IP

* fix regex, don't throw error when opening wallet, fix tx history, fix async calls, move stuff to isolate

* fix api calls in async transaction creation

* update build scripts

* fix some build issues

* update dependencies

* fix dependencies

* update ci scripts

* Improve multithread use of zano api

* Fix build issue

* fix zano node selection, move other zano calls to separate isolate

* update moneroc hash
WIP fixes for zano

* update monero_c

* fix monero.com builds

* sync wallet after connecting

* update monero_c

* Fix windows builds

* update monero_c

* update monero_c

* unshallow submodule

* cherry pick CW-867 Wownero fixes (#1881)

* fix wownero syntax error

* remove print statements in zano

* update zano node URL

* [PATCH] Apply new CI script (https://github.com/cake-tech/cake_wallet/pull/1948)

* drop env -i to fix cmake build errors on newer system

* [skip ci] Revert "[PATCH] Apply new CI script (https://github.com/cake-tech/cake_wallet/pull/1948)"

This reverts commit 5acb5bfe57.

* [run tests] [skip slack] Fix env in build

* Dynamically detect number of cores used to build monero_c, since it appears that zano requires more memory to link (and it reliably fails for first couple builds due to OOM on CI/VM with memory constrains).
Drop unshallowing of all modules
[run tests]

* Changes from review [run tests]

* drop zano on linux (missing symbols)
fix wownero on linux
add aarch64-linux-gnu
[run tests]

* - remove duplicate entry in addToken()
- use walletPassword in createZanoNewWalletCredentials
- remove createZanoRestoreWalletFromKeysCredentials
[run tests]

* [skip ci] update dockerfile

* fix parameter issue

---------

Co-authored-by: leo <leonid.ivanov@gmail.com>
Co-authored-by: cr.zoidberg <crypto.zoidberg@gmail.com>
Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

* - Add Zano Aliases
- Enable simpleswap [skip ci]
- Fix settings migration versions

* push missing file [skip ci]

* Zano pr with CW-685 passphrase (#1969)

* my experiments

* Inital code for Zano integration

* Added missing android log lib

* added dummy wallet & some zano implementation

* fixing api for zano

* fixed zano build script

* attempt tp fix namespace problem

* added copy script for Zano files

* changes for zano wallet

* last updates

* zano.dart test app

* wallet recovery

* added pending transfer, some cleanup of unused

* some cleanup

* send + receive qr code

* last upd

* updated build_zano.sh

* updated zano ApiCalls, removed dummy

* updated zano ApiCalls, removed dummy

* added logging for get status/get info

* restored old wallet.dart

* restoring original versions of files

* restoring original versions of files

* restored get_height_by_date.dart, removed unnecessary calls for zano get height

* restoring original versions

* added multiple destinations, send all flag; some refactoring

* logging

* removed the duplicate

* fixed syncing sync status, decimal division, safe null json parsing

* some fixes after merge

* added multibalance/asset support for zano (ui)

* adding/removing from whitelist

* transfers in different assets

* transfers for multiple destinations and send all, some refactoring

* whitelists, some refactoring

* added different digits (decimal points) for formatters, some refactoring

* open, create, restore wallet refactoring; whitelists

* whitelists

* getting and updating transaction list; restoring a wallet from QR code

* several attempts to close wallet

* some refactoring

* added seed phrase

* CW-685 Add passphrase restore for xmr/wow

* add support for polyseed passphrase

* disable 14 word seed passphrase (not supported in wownero-seed)
fix: Getting grayed screen on latest passphrase build after having restored a 14-word wownero seed (+passphrase) and attempting to restore a XMR seed, legacy or otherwise.

* fix pointer when restoring depracated wownero seed

* Fix polyseed encryption

* changed fields to BigInt, some fixes

* modified build scripts for android

* build scripts

* restored accidently removed cw_haven.dart

* inital ios integration(zano libs built)

* update in script

* latest changes

* changes from review

* remove unused code

* add passphrase back to the screen
add passphrase to qr code backup export

* fix settings leaking through currencies on seed restore

* fix monero.com builds, make passphrase a getter on WalletBase

* add support for weird polyseed

* store passphrase for weird polyseed

* show encrypted seed only when passphrase is not empty

* force set restore height

* Applied a patch for iOS build (Boost and Zano scripts)

* Removed zano.dart (script-generated) and some unnecessary files

* Revert "Removed zano.dart (script-generated) and some unnecessary files"

This reverts commit 367c86398e.

* Removed zano.dart (generated by scripts), some files restored to initial versions

* fix build issues

* fix build errors

* added timer library

* changed paths in build_zano.sh

* build_zano.sh

* edit_token_page.dart - removed flag skipZanoAddressValidation

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

* lib/core/address_validator.dart - updated zano address regex
lib/src/screens/dashboard/edit_token_page.dart - using AddressValidator().call

* fix zano build issues on android

* remove contrib/depends to save space

* move async call to a synchronouse one

* call sync call in isolate to make it async
generate framework for iOS as well
fix UR issues

* zano changes from monero_c repo

* update monero_c hash

* fix invalid zano imports, add support for linux, speed up CI builds

* update monero_c hash

* bump monero_c commit (yes, again, I know)

* fix wallet resttore, fix hardcoded IP

* fix regex, don't throw error when opening wallet, fix tx history, fix async calls, move stuff to isolate

* fix api calls in async transaction creation

* fix configure script

* update build scripts

* fix some build issues

* update dependencies

* fix dependencies

* update ci scripts

* Improve multithread use of zano api

* Fix build issue

* fix zano node selection, move other zano calls to separate isolate

* update moneroc hash
WIP fixes for zano

* update monero_c

* fix monero.com builds

* sync wallet after connecting

* update monero_c

* Fix windows builds

* update monero_c

* print -> printV

* update monero_c

* unshallow submodule

* cherry pick CW-867 Wownero fixes (#1881)

* fix wownero syntax error

* remove print statements in zano

* update zano node URL

* [PATCH] Apply new CI script (https://github.com/cake-tech/cake_wallet/pull/1948)

* drop env -i to fix cmake build errors on newer system

* Update lib/view_model/wallet_keys_view_model.dart [skip ci]

* Update lib/view_model/wallet_keys_view_model.dart [skip ci]

* Update tool/configure.dart [skip ci]

* Update lib/view_model/wallet_new_vm.dart

* [skip ci] Revert "[PATCH] Apply new CI script (https://github.com/cake-tech/cake_wallet/pull/1948)"

This reverts commit 5acb5bfe57.

* [run tests] [skip slack] Fix env in build

* Dynamically detect number of cores used to build monero_c, since it appears that zano requires more memory to link (and it reliably fails for first couple builds due to OOM on CI/VM with memory constrains).
Drop unshallowing of all modules
[run tests]

* Changes from review [run tests]

* drop zano on linux (missing symbols)
fix wownero on linux
add aarch64-linux-gnu
[run tests]

* - remove duplicate entry in addToken()
- use walletPassword in createZanoNewWalletCredentials
- remove createZanoRestoreWalletFromKeysCredentials
[run tests]

* [skip ci] update dockerfile

* reuse existing passphrase field

* add passphrase support for zano

* Drop aarch64-linux-gnu for now.

* fix passphrase display, fix gray screen

* catch errors in polyseed encryption, encrypt only polyseed, fix coin in wownero

* update monero_c
update wownero to 0.11.3.0

* Show passphrase only when non-empty, fix passphrase being displayed as view key private.

* fix NanoAccountListPage showing up instead of MoneroAccountListPage for wownero

* build zano dependencies on android

* fix parameter issue

* minor merge leftover [skip ci]

* minor cleanup [skip ci]

* fix zano alias
update eth url for ens lookup
change $MAKE_JOB_COUNT to $NPROC

* minor cleanup [skip ci]

* fix zano alias

* Disable passphrase for creation of xmr/wow/zano
minor fixes

* fix zano on iOS

* - Fix get token data
- Enable unavailable balance
- Enable confirmations count
- Adjust explorer link

---------

Co-authored-by: leo <leonid.ivanov@gmail.com>
Co-authored-by: Konstantin Ullrich <konstantinullrich12@gmail.com>
Co-authored-by: cr.zoidberg <crypto.zoidberg@gmail.com>
Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

---------

Co-authored-by: cyan <cyjan@mrcyjanek.net>
Co-authored-by: Konstantin Ullrich <konstantinullrich12@gmail.com>
Co-authored-by: leo <leonid.ivanov@gmail.com>
Co-authored-by: cr.zoidberg <crypto.zoidberg@gmail.com>
2025-01-24 20:33:24 +02:00

511 lines
16 KiB
Dart

import 'dart:convert';
import 'dart:developer';
import 'package:cake_wallet/core/fiat_conversion_service.dart';
import 'package:cake_wallet/entities/erc20_token_info_explorers.dart';
import 'package:cake_wallet/entities/fiat_api_mode.dart';
import 'package:cake_wallet/entities/erc20_token_info_moralis.dart';
import 'package:cake_wallet/entities/sort_balance_types.dart';
import 'package:cake_wallet/ethereum/ethereum.dart';
import 'package:cake_wallet/polygon/polygon.dart';
import 'package:cake_wallet/reactions/wallet_connect.dart';
import 'package:cake_wallet/solana/solana.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/tron/tron.dart';
import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart';
import 'package:cake_wallet/zano/zano.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/erc20_token.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:mobx/mobx.dart';
import 'package:http/http.dart' as http;
import 'package:cake_wallet/.secrets.g.dart' as secrets;
part 'home_settings_view_model.g.dart';
class HomeSettingsViewModel = HomeSettingsViewModelBase with _$HomeSettingsViewModel;
abstract class HomeSettingsViewModelBase with Store {
HomeSettingsViewModelBase(this._settingsStore, this._balanceViewModel)
: tokens = ObservableSet<CryptoCurrency>(),
isAddingToken = false,
isDeletingToken = false,
isValidatingContractAddress = false {
_updateTokensList();
}
final SettingsStore _settingsStore;
final BalanceViewModel _balanceViewModel;
final ObservableSet<CryptoCurrency> tokens;
WalletType get walletType => _balanceViewModel.wallet.type;
@observable
bool isAddingToken;
@observable
bool isDeletingToken;
@observable
bool isValidatingContractAddress;
@observable
String searchText = '';
@computed
SortBalanceBy get sortBalanceBy => _settingsStore.sortBalanceBy;
@action
void setSortBalanceBy(SortBalanceBy value) {
_settingsStore.sortBalanceBy = value;
_updateTokensList();
}
@computed
bool get pinNativeToken => _settingsStore.pinNativeTokenAtTop;
@action
void setPinNativeToken(bool value) => _settingsStore.pinNativeTokenAtTop = value;
@action
Future<void> addToken({
required String contractAddress,
required CryptoCurrency token,
}) async {
try {
isAddingToken = true;
if (_balanceViewModel.wallet.type == WalletType.ethereum) {
final erc20token = Erc20Token(
name: token.name,
symbol: token.title,
decimal: token.decimals,
contractAddress: contractAddress,
iconPath: token.iconPath,
);
await ethereum!.addErc20Token(_balanceViewModel.wallet, erc20token);
}
if (_balanceViewModel.wallet.type == WalletType.polygon) {
final polygonToken = Erc20Token(
name: token.name,
symbol: token.title,
decimal: token.decimals,
contractAddress: contractAddress,
iconPath: token.iconPath,
);
await polygon!.addErc20Token(_balanceViewModel.wallet, polygonToken);
}
if (_balanceViewModel.wallet.type == WalletType.solana) {
await solana!.addSPLToken(
_balanceViewModel.wallet,
token,
contractAddress,
);
}
if (_balanceViewModel.wallet.type == WalletType.tron) {
await tron!.addTronToken(_balanceViewModel.wallet, token, contractAddress);
}
if (_balanceViewModel.wallet.type == WalletType.zano) {
await zano!.addZanoAssetById(_balanceViewModel.wallet, contractAddress);
}
_updateTokensList();
_updateFiatPrices(token);
} finally {
isAddingToken = false;
}
}
@action
Future<void> deleteToken(CryptoCurrency token) async {
try {
isDeletingToken = true;
if (_balanceViewModel.wallet.type == WalletType.ethereum) {
await ethereum!.deleteErc20Token(_balanceViewModel.wallet, token as Erc20Token);
}
if (_balanceViewModel.wallet.type == WalletType.polygon) {
await polygon!.deleteErc20Token(_balanceViewModel.wallet, token as Erc20Token);
}
if (_balanceViewModel.wallet.type == WalletType.solana) {
await solana!.deleteSPLToken(_balanceViewModel.wallet, token);
}
if (_balanceViewModel.wallet.type == WalletType.tron) {
await tron!.deleteTronToken(_balanceViewModel.wallet, token);
}
if (_balanceViewModel.wallet.type == WalletType.zano) {
await zano!.deleteZanoAsset(_balanceViewModel.wallet, token);
}
_updateTokensList();
} finally {
isDeletingToken = false;
}
}
Future<bool> checkIfERC20TokenContractAddressIsAPotentialScamAddress(
String contractAddress,
) async {
try {
isValidatingContractAddress = true;
if (!isEVMCompatibleChain(_balanceViewModel.wallet.type)) {
return false;
}
bool isEthereum = _balanceViewModel.wallet.type == WalletType.ethereum;
bool isPotentialScamViaMoralis = await _isPotentialScamTokenViaMoralis(
contractAddress,
isEthereum ? 'eth' : 'polygon',
);
bool isPotentialScamViaExplorers = await _isPotentialScamTokenViaExplorers(
contractAddress,
isEthereum: isEthereum,
);
bool isUnverifiedContract = await _isContractUnverified(
contractAddress,
isEthereum: isEthereum,
);
final showWarningForContractAddress =
isPotentialScamViaMoralis || isUnverifiedContract || isPotentialScamViaExplorers;
return showWarningForContractAddress;
} finally {
isValidatingContractAddress = false;
}
}
Future<bool> _isPotentialScamTokenViaMoralis(
String contractAddress,
String chainName,
) async {
final uri = Uri.https(
'deep-index.moralis.io',
'/api/v2.2/erc20/metadata',
{
"chain": chainName,
"addresses": contractAddress,
},
);
try {
final response = await http.get(
uri,
headers: {
"Accept": "application/json",
"X-API-Key": secrets.moralisApiKey,
},
);
final decodedResponse = jsonDecode(response.body);
final tokenInfo = Erc20TokenInfoMoralis.fromJson(decodedResponse[0] as Map<String, dynamic>);
// Based on analysis using Moralis internal metrics
if (tokenInfo.possibleSpam == true) {
return true;
}
// Tokens whose contract have not been verified are potentially risky tokens.
if (tokenInfo.verifiedContract == false) {
return true;
}
// Tokens with a security score less than 40 are potentially risky, requiring caution when dealing with them.
if (tokenInfo.securityScore == null || tokenInfo.securityScore! < 40) {
return true;
}
// Absence of a website URL for an ERC-20 token can be a potential red flag. A legitimate ERC-20 projects should have a well-maintained website that provides information about the token, its purpose, team, and roadmap.
if (tokenInfo.links?.website == null || tokenInfo.links!.website!.isEmpty) {
return true;
}
// Having a Fully Diluted Valiuation of 0 is a significant red flag that could signify:
// - An abandoned/unlaunched project
// - Incorrect/missing token data
// - Suspicious manipulation of token data
if (tokenInfo.fullyDilutedValuation == '0') {
return true;
}
// I mean, a logo is the most basic of all the potential causes, but why does your fully functional project not have a logo?
if (tokenInfo.logo == null) {
return true;
}
return false;
} catch (e) {
printV('Error while checking scam via moralis: ${e.toString()}');
return true;
}
}
Future<bool> _isPotentialScamTokenViaExplorers(
String contractAddress, {
required bool isEthereum,
}) async {
final uri = Uri.https(
isEthereum ? "api.etherscan.io" : "api.polygonscan.com",
"/api",
{
"module": "token",
"action": "tokeninfo",
"contractaddress": contractAddress,
"apikey": isEthereum ? secrets.etherScanApiKey : secrets.polygonScanApiKey,
},
);
try {
final response = await http.get(uri);
final decodedResponse = jsonDecode(response.body) as Map<String, dynamic>;
if (decodedResponse['status'] != '1') {
log('${response.body}\n');
log('${decodedResponse['result']}\n');
return true;
}
final tokenInfo =
Erc20TokenInfoExplorers.fromJson(decodedResponse['result'][0] as Map<String, dynamic>);
// A token without a website is a potential red flag
if (tokenInfo.website?.isEmpty == true) {
return true;
}
return false;
} catch (e) {
printV('Error while checking scam via explorers: ${e.toString()}');
return true;
}
}
Future<bool> _isContractUnverified(
String contractAddress, {
required bool isEthereum,
}) async {
final uri = Uri.https(
isEthereum ? "api.etherscan.io" : "api.polygonscan.com",
"/api",
{
"module": "contract",
"action": "getsourcecode",
"address": contractAddress,
"apikey": isEthereum ? secrets.etherScanApiKey : secrets.polygonScanApiKey,
},
);
try {
final response = await http.get(uri);
final decodedResponse = jsonDecode(response.body) as Map<String, dynamic>;
if (decodedResponse['status'] == '0') {
printV('${response.body}\n');
printV('${decodedResponse['result']}\n');
return true;
}
if (decodedResponse['status'] == '1' &&
decodedResponse['result'][0]['ABI'] == 'Contract source code not verified') {
printV('Call is valid but contract is not verified');
return true; // Contract is not verified
} else {
printV('Call is valid and contract is verified');
return false; // Contract is verified
}
} catch (e) {
printV('Error while checking contract verification: ${e.toString()}');
return true;
}
}
Future<CryptoCurrency?> getToken(String contractAddress) async {
if (_balanceViewModel.wallet.type == WalletType.ethereum) {
return await ethereum!.getErc20Token(_balanceViewModel.wallet, contractAddress);
}
if (_balanceViewModel.wallet.type == WalletType.polygon) {
return await polygon!.getErc20Token(_balanceViewModel.wallet, contractAddress);
}
if (_balanceViewModel.wallet.type == WalletType.solana) {
return await solana!.getSPLToken(_balanceViewModel.wallet, contractAddress);
}
if (_balanceViewModel.wallet.type == WalletType.tron) {
return await tron!.getTronToken(_balanceViewModel.wallet, contractAddress);
}
if (_balanceViewModel.wallet.type == WalletType.zano) {
return await zano!.getZanoAsset(_balanceViewModel.wallet, contractAddress);
}
return null;
}
CryptoCurrency get nativeToken => _balanceViewModel.wallet.currency;
void _updateFiatPrices(CryptoCurrency token) async {
try {
_balanceViewModel.fiatConvertationStore.prices[token] =
await FiatConversionService.fetchPrice(
crypto: token,
fiat: _settingsStore.fiatCurrency,
torOnly: _settingsStore.fiatApiMode == FiatApiMode.torOnly);
} catch (_) {}
}
void changeTokenAvailability(CryptoCurrency token, bool value) async {
token.enabled = value;
if (_balanceViewModel.wallet.type == WalletType.ethereum) {
ethereum!.addErc20Token(_balanceViewModel.wallet, token as Erc20Token);
if (!value) ethereum!.removeTokenTransactionsInHistory(_balanceViewModel.wallet, token);
}
if (_balanceViewModel.wallet.type == WalletType.polygon) {
polygon!.addErc20Token(_balanceViewModel.wallet, token as Erc20Token);
if (!value) polygon!.removeTokenTransactionsInHistory(_balanceViewModel.wallet, token);
}
if (_balanceViewModel.wallet.type == WalletType.solana) {
final address = solana!.getTokenAddress(token);
solana!.addSPLToken(_balanceViewModel.wallet, token, address);
}
if (_balanceViewModel.wallet.type == WalletType.tron) {
final address = tron!.getTokenAddress(token);
tron!.addTronToken(_balanceViewModel.wallet, token, address);
}
if (_balanceViewModel.wallet.type == WalletType.zano) {
await zano!.changeZanoAssetAvailability(_balanceViewModel.wallet, token);
}
_refreshTokensList();
}
@action
void _updateTokensList() {
int _sortFunc(CryptoCurrency e1, CryptoCurrency e2) {
int index1 = _balanceViewModel.formattedBalances.indexWhere((element) => element.asset == e1);
int index2 = _balanceViewModel.formattedBalances.indexWhere((element) => element.asset == e2);
if (e1.enabled && !e2.enabled) {
return -1;
} else if (e2.enabled && !e1.enabled) {
return 1;
} else if (!e1.enabled && !e2.enabled) {
// if both are disabled then sort alphabetically
return e1.name.compareTo(e2.name);
}
return index1.compareTo(index2);
}
tokens.clear();
if (_balanceViewModel.wallet.type == WalletType.ethereum) {
tokens.addAll(ethereum!
.getERC20Currencies(_balanceViewModel.wallet)
.where((element) => _matchesSearchText(element))
.toList()
..sort(_sortFunc));
}
if (_balanceViewModel.wallet.type == WalletType.polygon) {
tokens.addAll(polygon!
.getERC20Currencies(_balanceViewModel.wallet)
.where((element) => _matchesSearchText(element))
.toList()
..sort(_sortFunc));
}
if (_balanceViewModel.wallet.type == WalletType.solana) {
tokens.addAll(solana!
.getSPLTokenCurrencies(_balanceViewModel.wallet)
.where((element) => _matchesSearchText(element))
.toList()
..sort(_sortFunc));
}
if (_balanceViewModel.wallet.type == WalletType.tron) {
tokens.addAll(tron!
.getTronTokenCurrencies(_balanceViewModel.wallet)
.where((element) => _matchesSearchText(element))
.toList()
..sort(_sortFunc));
}
if (_balanceViewModel.wallet.type == WalletType.zano) {
tokens.addAll(zano!.getZanoAssets(_balanceViewModel.wallet)
.where((element) => _matchesSearchText(element))
.toList()
..sort(_sortFunc));
}
}
@action
void _refreshTokensList() {
final _tokens = Set.of(tokens);
tokens.clear();
tokens.addAll(_tokens);
}
@action
void changeSearchText(String text) {
searchText = text;
_updateTokensList();
}
bool _matchesSearchText(CryptoCurrency asset) {
final address = getTokenAddressBasedOnWallet(asset);
// The homes settings would only be displayed for either of Tron, Ethereum, Polygon or Solana Wallets.
if (address == null) return false;
return searchText.isEmpty ||
asset.fullName!.toLowerCase().contains(searchText.toLowerCase()) ||
asset.title.toLowerCase().contains(searchText.toLowerCase()) ||
address == searchText;
}
String? getTokenAddressBasedOnWallet(CryptoCurrency asset) {
if (_balanceViewModel.wallet.type == WalletType.tron) {
return tron!.getTokenAddress(asset);
}
if (_balanceViewModel.wallet.type == WalletType.solana) {
return solana!.getTokenAddress(asset);
}
if (_balanceViewModel.wallet.type == WalletType.ethereum) {
return ethereum!.getTokenAddress(asset);
}
if (_balanceViewModel.wallet.type == WalletType.polygon) {
return polygon!.getTokenAddress(asset);
}
if (_balanceViewModel.wallet.type == WalletType.zano) {
return zano!.getZanoAssetAddress(asset);
}
// We return null if it's neither Tron, Polygon, Ethereum or Solana wallet (which is actually impossible because we only display home settings for either of these three wallets).
return null;
}
}