mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-25 13:09:32 +00:00
d1870ba8b8
* chore: Initial setup for Tron Wallet * feat: Create Tron Wallet base flow implemented, keys, address, receive, restore and proxy classes all setup * feat: Display seed and key within the app * feat: Activate restore from key and seed for Tron wallet * feat: Add icon for tron wallet in wallet listing page * feat: Activate display of receive address for tron * feat: Fetch and display tron balance, sending transaction flow setup, fee limit calculation setup * feat: Implement sending of native tron, setup sending of trc20 tokens * chore: Rename function * Delete lib/tron/tron.dart * feat: Activate exchange for tron and its tokens, implement balance display for trc20 tokens and setup secrets configuration for tron * feat: Implement tron token management, add, remove, delete, and get tokens in home settings view, also minor cleanup * feat: Activate buy and sell for tron * feat: Implement restore from QR, transactions history listing for both native transactions and trc20 transactions * feat: Activate send all and do some minor cleanups * chore: Fix some lint infos and warnings * chore: Adjust configurations * ci: Modify CI to create and add secrets for node * fix: Fixes made while self reviewing the PR for this feature * feat: Add guide for adding new wallet types, and add fixes to requested changes * fix: Handle exceptions gracefully * fix: Alternative for trc20 estimated fee * fix: Fixes to display of amount and fee, removing clashes * fix: Fee calculation WIP * fix: Fix issue with handling of send all flow and display of amount and fee values before broadcasting transaction * fix: PR review fixes and fix merge conflicts * fix: Modify fetching assetOfTransaction [skip ci] * fix: Move tron settings migration to 33
264 lines
8.3 KiB
Dart
264 lines
8.3 KiB
Dart
import 'package:cake_wallet/core/fiat_conversion_service.dart';
|
|
import 'package:cake_wallet/entities/fiat_api_mode.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/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:cw_core/crypto_currency.dart';
|
|
import 'package:cw_core/erc20_token.dart';
|
|
import 'package:cw_core/wallet_type.dart';
|
|
import 'package:mobx/mobx.dart';
|
|
|
|
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>() {
|
|
_updateTokensList();
|
|
}
|
|
|
|
final SettingsStore _settingsStore;
|
|
final BalanceViewModel _balanceViewModel;
|
|
|
|
final ObservableSet<CryptoCurrency> tokens;
|
|
|
|
@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;
|
|
|
|
Future<void> addToken({
|
|
required String contractAddress,
|
|
required CryptoCurrency token,
|
|
}) async {
|
|
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);
|
|
}
|
|
|
|
_updateTokensList();
|
|
_updateFiatPrices(token);
|
|
}
|
|
|
|
Future<void> deleteToken(CryptoCurrency token) async {
|
|
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);
|
|
}
|
|
_updateTokensList();
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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 (_balanceViewModel.wallet.type == WalletType.polygon) {
|
|
polygon!.addErc20Token(_balanceViewModel.wallet, token as Erc20Token);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
_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));
|
|
}
|
|
}
|
|
|
|
@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);
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
}
|