mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-21 06:18:42 +02:00
Cw 78 ethereum (#862)
* Add initial flow for ethereum * Add initial create Eth wallet flow * Complete Ethereum wallet creation flow * Fix web3dart versioning issue * Add primary receive address extracted from private key * Implement open wallet functionality * Implement restore wallet from seed functionality * Fixate web3dart version as higher versions cause some issues * Add Initial Transaction priorities for eth Add estimated gas price * Rename priority value to tip * Re-order wallet types * Change ethereum node Fix connection issues * Fix estimating gas for priority * Add case for ethereum to fetch it's seeds * Add case for ethereum to request node * Fix Exchange screen initial pairs * Add initial send transaction flow * Add missing configure for ethereum class * Add Eth address initial setup * Fix Private key for Ethereum wallets * Change sign/send transaction flow * - Fix Conflicts with main - Remove unused function from Haven configure.dart * Add build command for ethereum package * Add missing Node list file to pubspec * - Fix balance display - Fix parsing of Ethereum amount - Add more Ethereum Nodes * - Fix extracting Ethereum Private key from seeds - Integrate signing/sending transaction with the send view model * - Update and Fix Conflicts with main * Add Balances for ERC20 tokens * Fix conflicts with main * Add erc20 abi json * Add send erc20 tokens initial function * add missing getHeightByDate in Haven * Allow contacts and wallets from the same tag * Add Shiba Inu icon * Add send ERC-20 tokens initial flow * Add missing import in generated file * Add initial approach for transaction sending for ERC-20 tokens * Refactor signing/sending transactions * Add initial flow for transactions subscription * Refactor signing/sending transactions * Add home settings icon * Fix conflicts with main * Initial flow for home settings * Add logic flow for adding erc20 tokens * Fix initial UI * Finalize UI for Tokens * Integrate UI with Ethereum flow * Add "Enable/Disable" feature for ERC20 tokens * Add initial Erc20 tokens * Add Sorting and Pin Native Token features * Fix price sorting * Sort tokens list as well when Sort criteria changes * - Improve sorting balances flow - Add initial add token from search bar flow * Fix Accounts Popup UI * Fix Pin native token * Fix Enabling/Disabling tokens Fix sorting by fiat once app is opened Improve token availability mechanism * Fix deleting token Fix renaming tokens * Fix issue with search * Add more tokens * - Fix scroll issue - Add ERC20 tokens placeholder image in picker * - Separate and organize default erc20 tokens - Fix scrolling - Add token placeholder images in picker - Sort disabled tokens alphabetically * Change BNB token initial availability * Fix Conflicts with main * Fix Conflicts with main * Add Verse ERC20 token to the initial tokens list * Add rename wallet to Ethereum * Integrate EtherScan API for fetching address transactions Generate Ethereum specific secrets in Ethereum package * Adjust transactions fiat price for ERC20 tokens * Free Up GitHub Actions Ubuntu Runner Disk Space * Free Up GitHub Actions Ubuntu Runner Disk space (trial 2) * Fix Transaction Fee display * Save transaction history * Enhance loading time for erc20 tokens transactions * Minor Fixes and Enhancements * Fix sending erc20 fix block explorer issue * Fix int overflow * Fix transaction amount conversions * Minor: `slow` -> `Slow` * Update build guide * Fix fetching fiat rate taking a lot of time by only fetching enabled tokens only and making the API calls in parallel not sequential * Update transactions on a periodic basis * For fee, use ETH spot price, not ERC-20 spot price * Add Etherscan History privacy option to enable/disable Etherscan API * Show estimated fee amounts in the send screen * fix send fiat fields parsing issue * Fix transactions estimated fee less than actual fee * handle balance sorting when balance is disabled Handle empty transactions list * Fix Delete Ethereum wallet Fix balance < 0.01 * Fix Decimal place for Ethereum amount Fix sending amount issue * Change words count * Remove balance hint and Full balance row from Ethereum wallets * support changing the asset type in send templates * Fix Templates for ERC tokens issues * Fix conflicts in send templates * Disable batch sending in Ethereum * Fix Fee calculation with different priorities * Fix Conflicts with main * Add offline error to ignored exceptions --------- Co-authored-by: Justin Ehrenhofer <justin.ehrenhofer@gmail.com>
This commit is contained in:
co-authored by
Justin Ehrenhofer
parent
4120394121
commit
3ce4000dcf
@@ -1,4 +1,5 @@
|
||||
import 'dart:async';
|
||||
import 'package:cake_wallet/entities/contact_base.dart';
|
||||
import 'package:cake_wallet/entities/wallet_contact.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
@@ -57,11 +58,15 @@ abstract class ContactListViewModelBase with Store {
|
||||
|
||||
@computed
|
||||
List<ContactRecord> get contactsToShow => contacts
|
||||
.where((element) => _currency == null || element.type == _currency)
|
||||
.where((element) => _isValidForCurrency(element))
|
||||
.toList();
|
||||
|
||||
@computed
|
||||
List<WalletContact> get walletContactsToShow => walletContacts
|
||||
.where((element) => _currency == null || element.type == _currency)
|
||||
.where((element) => _isValidForCurrency(element))
|
||||
.toList();
|
||||
|
||||
bool _isValidForCurrency(ContactBase element) {
|
||||
return _currency == null || element.type == _currency || element.type.title == _currency!.tag;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:cake_wallet/entities/fiat_api_mode.dart';
|
||||
import 'package:cake_wallet/entities/sort_balance_types.dart';
|
||||
import 'package:cw_core/transaction_history.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/balance.dart';
|
||||
@@ -79,6 +80,15 @@ abstract class BalanceViewModelBase with Store {
|
||||
@computed
|
||||
bool get isFiatDisabled => settingsStore.fiatApiMode == FiatApiMode.disabled;
|
||||
|
||||
@computed
|
||||
bool get isHomeScreenSettingsEnabled => wallet.type == WalletType.ethereum;
|
||||
|
||||
@computed
|
||||
SortBalanceBy get sortBalanceBy => settingsStore.sortBalanceBy;
|
||||
|
||||
@computed
|
||||
bool get pinNativeToken => settingsStore.pinNativeTokenAtTop;
|
||||
|
||||
@computed
|
||||
String get asset {
|
||||
final typeFormatted = walletTypeToString(appStore.wallet!.type);
|
||||
@@ -109,6 +119,7 @@ abstract class BalanceViewModelBase with Store {
|
||||
switch(wallet.type) {
|
||||
case WalletType.monero:
|
||||
case WalletType.haven:
|
||||
case WalletType.ethereum:
|
||||
return S.current.xmr_available_balance;
|
||||
default:
|
||||
return S.current.confirmed;
|
||||
@@ -120,6 +131,7 @@ abstract class BalanceViewModelBase with Store {
|
||||
switch(wallet.type) {
|
||||
case WalletType.monero:
|
||||
case WalletType.haven:
|
||||
case WalletType.ethereum:
|
||||
return S.current.xmr_full_balance;
|
||||
default:
|
||||
return S.current.unconfirmed;
|
||||
@@ -262,32 +274,58 @@ abstract class BalanceViewModelBase with Store {
|
||||
});
|
||||
}
|
||||
|
||||
@computed
|
||||
bool get hasAdditionalBalance => wallet.type != WalletType.ethereum;
|
||||
|
||||
@computed
|
||||
List<BalanceRecord> get formattedBalances {
|
||||
final balance = balances.values.toList();
|
||||
|
||||
balance.sort((BalanceRecord a, BalanceRecord b) {
|
||||
if (b.asset == CryptoCurrency.xhv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (b.asset == CryptoCurrency.xusd) {
|
||||
if (a.asset == CryptoCurrency.xhv) {
|
||||
return -1;
|
||||
if (wallet.currency == CryptoCurrency.xhv) {
|
||||
if (b.asset == CryptoCurrency.xhv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
if (b.asset == CryptoCurrency.xusd) {
|
||||
if (a.asset == CryptoCurrency.xhv) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (b.asset == CryptoCurrency.xbtc) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (b.asset == CryptoCurrency.xeur) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (b.asset == CryptoCurrency.xbtc) {
|
||||
return 1;
|
||||
if (pinNativeToken) {
|
||||
if (b.asset == wallet.currency) return 1;
|
||||
if (a.asset == wallet.currency) return -1;
|
||||
}
|
||||
|
||||
if (b.asset == CryptoCurrency.xeur) {
|
||||
return 1;
|
||||
}
|
||||
switch (sortBalanceBy) {
|
||||
case SortBalanceBy.FiatBalance:
|
||||
final aFiatBalance = _getFiatBalance(
|
||||
price: fiatConvertationStore.prices[a.asset] ?? 0, cryptoAmount: a.availableBalance);
|
||||
final bFiatBalance = _getFiatBalance(
|
||||
price: fiatConvertationStore.prices[b.asset] ?? 0, cryptoAmount: b.availableBalance);
|
||||
|
||||
return 0;
|
||||
return (double.tryParse(bFiatBalance) ?? 0)
|
||||
.compareTo((double.tryParse(aFiatBalance)) ?? 0);
|
||||
case SortBalanceBy.GrossBalance:
|
||||
return (double.tryParse(b.availableBalance) ?? 0)
|
||||
.compareTo(double.tryParse(a.availableBalance) ?? 0);
|
||||
case SortBalanceBy.Alphabetical:
|
||||
return a.asset.title.compareTo(b.asset.title);
|
||||
}
|
||||
});
|
||||
|
||||
return balance;
|
||||
@@ -335,7 +373,7 @@ abstract class BalanceViewModelBase with Store {
|
||||
}
|
||||
|
||||
String _getFiatBalance({required double price, String? cryptoAmount}) {
|
||||
if (cryptoAmount == null || cryptoAmount.isEmpty) {
|
||||
if (cryptoAmount == null || cryptoAmount.isEmpty || double.tryParse(cryptoAmount) == null) {
|
||||
return '0.00';
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
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/store/settings_store.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: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<Erc20Token>() {
|
||||
_updateTokensList();
|
||||
}
|
||||
|
||||
final SettingsStore _settingsStore;
|
||||
final BalanceViewModel _balanceViewModel;
|
||||
|
||||
final ObservableSet<Erc20Token> 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> addErc20Token(Erc20Token token) async {
|
||||
await ethereum!.addErc20Token(_balanceViewModel.wallet, token);
|
||||
_updateTokensList();
|
||||
_updateFiatPrices(token);
|
||||
}
|
||||
|
||||
Future<void> deleteErc20Token(Erc20Token token) async {
|
||||
await ethereum!.deleteErc20Token(_balanceViewModel.wallet, token);
|
||||
_updateTokensList();
|
||||
}
|
||||
|
||||
Future<Erc20Token?> getErc20Token(String contractAddress) async =>
|
||||
await ethereum!.getErc20Token(_balanceViewModel.wallet, contractAddress);
|
||||
|
||||
CryptoCurrency get nativeToken => _balanceViewModel.wallet.currency;
|
||||
|
||||
void _updateFiatPrices(Erc20Token token) async {
|
||||
try {
|
||||
_balanceViewModel.fiatConvertationStore.prices[token] =
|
||||
await FiatConversionService.fetchPrice(
|
||||
crypto: token,
|
||||
fiat: _settingsStore.fiatCurrency,
|
||||
torOnly: _settingsStore.fiatApiMode == FiatApiMode.torOnly);
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
void changeTokenAvailability(Erc20Token token, bool value) async {
|
||||
token.enabled = value;
|
||||
ethereum!.addErc20Token(_balanceViewModel.wallet, token);
|
||||
_refreshTokensList();
|
||||
}
|
||||
|
||||
@action
|
||||
void _updateTokensList() {
|
||||
int _sortFunc(Erc20Token e1, Erc20Token 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();
|
||||
|
||||
tokens.addAll(ethereum!
|
||||
.getERC20Currencies(_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(Erc20Token asset) {
|
||||
return searchText.isEmpty ||
|
||||
asset.fullName!.toLowerCase().contains(searchText.toLowerCase()) ||
|
||||
asset.title.toLowerCase().contains(searchText.toLowerCase()) ||
|
||||
asset.contractAddress == searchText;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:cake_wallet/entities/balance_display_mode.dart';
|
||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||
import 'package:cake_wallet/ethereum/ethereum.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cw_core/transaction_direction.dart';
|
||||
import 'package:cw_core/transaction_info.dart';
|
||||
@@ -84,6 +85,13 @@ class TransactionListItem extends ActionListItem with Keyable {
|
||||
cryptoAmount: haven!.formatterMoneroAmountToDouble(amount: transaction.amount),
|
||||
price: price);
|
||||
break;
|
||||
case WalletType.ethereum:
|
||||
final asset = ethereum!.assetOfTransaction(balanceViewModel.wallet, transaction);
|
||||
final price = balanceViewModel.fiatConvertationStore.prices[asset];
|
||||
amount = calculateFiatAmountRaw(
|
||||
cryptoAmount: ethereum!.formatterEthereumAmountToDouble(transaction: transaction),
|
||||
price: price);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -699,6 +699,10 @@ abstract class ExchangeViewModelBase with Store {
|
||||
depositCurrency = CryptoCurrency.xhv;
|
||||
receiveCurrency = CryptoCurrency.btc;
|
||||
break;
|
||||
case WalletType.ethereum:
|
||||
depositCurrency = CryptoCurrency.eth;
|
||||
receiveCurrency = CryptoCurrency.xmr;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -63,6 +63,9 @@ abstract class NodeListViewModelBase with Store {
|
||||
case WalletType.haven:
|
||||
node = getHavenDefaultNode(nodes: _nodeSource)!;
|
||||
break;
|
||||
case WalletType.ethereum:
|
||||
node = getEthereumDefaultNode(nodes: _nodeSource)!;
|
||||
break;
|
||||
default:
|
||||
throw Exception('Unexpected wallet type: ${_appStore.wallet!.type}');
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/entities/calculate_fiat_amount_raw.dart';
|
||||
import 'package:cake_wallet/entities/parse_address_from_domain.dart';
|
||||
import 'package:cake_wallet/entities/parsed_address.dart';
|
||||
import 'package:cake_wallet/ethereum/ethereum.dart';
|
||||
import 'package:cake_wallet/haven/haven.dart';
|
||||
import 'package:cake_wallet/src/screens/send/widgets/extract_address_from_parsed.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
@@ -90,6 +91,9 @@ abstract class OutputBase with Store {
|
||||
case WalletType.haven:
|
||||
_amount = haven!.formatterMoneroParseAmount(amount: _cryptoAmount);
|
||||
break;
|
||||
case WalletType.ethereum:
|
||||
_amount = ethereum!.formatterEthereumParseAmount(_cryptoAmount);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -123,6 +127,10 @@ abstract class OutputBase with Store {
|
||||
if (_wallet.type == WalletType.haven) {
|
||||
return haven!.formatterMoneroAmountToDouble(amount: fee);
|
||||
}
|
||||
|
||||
if (_wallet.type == WalletType.ethereum) {
|
||||
return ethereum!.formatterEthereumAmountToDouble(amount: BigInt.from(fee));
|
||||
}
|
||||
} catch (e) {
|
||||
print(e.toString());
|
||||
}
|
||||
@@ -133,8 +141,9 @@ abstract class OutputBase with Store {
|
||||
@computed
|
||||
String get estimatedFeeFiatAmount {
|
||||
try {
|
||||
final currency = _wallet.type == WalletType.ethereum ? _wallet.currency : cryptoCurrencyHandler();
|
||||
final fiat = calculateFiatAmountRaw(
|
||||
price: _fiatConversationStore.prices[cryptoCurrencyHandler()]!,
|
||||
price: _fiatConversationStore.prices[currency]!,
|
||||
cryptoAmount: estimatedFee);
|
||||
return fiat;
|
||||
} catch (_) {
|
||||
@@ -228,6 +237,9 @@ abstract class OutputBase with Store {
|
||||
case WalletType.haven:
|
||||
maximumFractionDigits = 12;
|
||||
break;
|
||||
case WalletType.ethereum:
|
||||
maximumFractionDigits = 12;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -13,8 +13,7 @@ import 'package:cake_wallet/store/settings_store.dart';
|
||||
|
||||
part 'send_template_view_model.g.dart';
|
||||
|
||||
class SendTemplateViewModel = SendTemplateViewModelBase
|
||||
with _$SendTemplateViewModel;
|
||||
class SendTemplateViewModel = SendTemplateViewModelBase with _$SendTemplateViewModel;
|
||||
|
||||
abstract class SendTemplateViewModelBase with Store {
|
||||
final WalletBase _wallet;
|
||||
@@ -22,8 +21,8 @@ abstract class SendTemplateViewModelBase with Store {
|
||||
final SendTemplateStore _sendTemplateStore;
|
||||
final FiatConversionStore _fiatConversationStore;
|
||||
|
||||
SendTemplateViewModelBase(this._wallet, this._settingsStore,
|
||||
this._sendTemplateStore, this._fiatConversationStore)
|
||||
SendTemplateViewModelBase(
|
||||
this._wallet, this._settingsStore, this._sendTemplateStore, this._fiatConversationStore)
|
||||
: recipients = ObservableList<TemplateViewModel>() {
|
||||
addRecipient();
|
||||
}
|
||||
@@ -33,7 +32,6 @@ abstract class SendTemplateViewModelBase with Store {
|
||||
@action
|
||||
void addRecipient() {
|
||||
recipients.add(TemplateViewModel(
|
||||
cryptoCurrency: cryptoCurrency,
|
||||
wallet: _wallet,
|
||||
settingsStore: _settingsStore,
|
||||
fiatConversationStore: _fiatConversationStore));
|
||||
@@ -47,11 +45,13 @@ abstract class SendTemplateViewModelBase with Store {
|
||||
AmountValidator get amountValidator =>
|
||||
AmountValidator(currency: walletTypeToCryptoCurrency(_wallet.type));
|
||||
|
||||
AddressValidator get addressValidator =>
|
||||
AddressValidator(type: _wallet.currency);
|
||||
AddressValidator get addressValidator => AddressValidator(type: _wallet.currency);
|
||||
|
||||
TemplateValidator get templateValidator => TemplateValidator();
|
||||
|
||||
bool get hasMultiRecipient =>
|
||||
_wallet.type != WalletType.haven && _wallet.type != WalletType.ethereum;
|
||||
|
||||
@computed
|
||||
CryptoCurrency get cryptoCurrency => _wallet.currency;
|
||||
|
||||
@@ -68,6 +68,7 @@ abstract class SendTemplateViewModelBase with Store {
|
||||
void addTemplate(
|
||||
{required String name,
|
||||
required bool isCurrencySelected,
|
||||
required String cryptoCurrency,
|
||||
required String address,
|
||||
required String amount,
|
||||
required String amountFiat,
|
||||
@@ -76,7 +77,7 @@ abstract class SendTemplateViewModelBase with Store {
|
||||
name: name,
|
||||
isCurrencySelected: isCurrencySelected,
|
||||
address: address,
|
||||
cryptoCurrency: cryptoCurrency.title,
|
||||
cryptoCurrency: cryptoCurrency,
|
||||
fiatCurrency: fiatCurrency,
|
||||
amount: amount,
|
||||
amountFiat: amountFiat,
|
||||
@@ -89,4 +90,7 @@ abstract class SendTemplateViewModelBase with Store {
|
||||
_sendTemplateStore.remove(template: template);
|
||||
updateTemplate();
|
||||
}
|
||||
|
||||
@computed
|
||||
List<CryptoCurrency> get walletCurrencies => _wallet.balance.keys.toList();
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
|
||||
import 'package:cake_wallet/entities/transaction_description.dart';
|
||||
import 'package:cake_wallet/entities/wallet_contact.dart';
|
||||
import 'package:cake_wallet/view_model/contact_list/contact_list_view_model.dart';
|
||||
import 'package:cake_wallet/ethereum/ethereum.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart';
|
||||
import 'package:cw_core/transaction_priority.dart';
|
||||
import 'package:cake_wallet/view_model/send/output.dart';
|
||||
@@ -45,6 +46,7 @@ abstract class SendViewModelBase with Store {
|
||||
: state = InitialExecutionState(),
|
||||
currencies = _wallet.balance.keys.toList(),
|
||||
selectedCryptoCurrency = _wallet.currency,
|
||||
hasMultipleTokens = _wallet.type == WalletType.ethereum,
|
||||
outputs = ObservableList<Output>(),
|
||||
fiatFromSettings = _settingsStore.fiatCurrency {
|
||||
final priority = _settingsStore.priority[_wallet.type];
|
||||
@@ -105,8 +107,11 @@ abstract class SendViewModelBase with Store {
|
||||
String get pendingTransactionFeeFiatAmount {
|
||||
try {
|
||||
if (pendingTransaction != null) {
|
||||
final currency = walletType == WalletType.ethereum
|
||||
? _wallet.currency
|
||||
: selectedCryptoCurrency;
|
||||
final fiat = calculateFiatAmount(
|
||||
price: _fiatConversationStore.prices[selectedCryptoCurrency]!,
|
||||
price: _fiatConversationStore.prices[currency]!,
|
||||
cryptoAmount: pendingTransaction!.feeFormatted);
|
||||
return fiat;
|
||||
} else {
|
||||
@@ -131,14 +136,14 @@ abstract class SendViewModelBase with Store {
|
||||
|
||||
CryptoCurrency get currency => _wallet.currency;
|
||||
|
||||
Validator get amountValidator =>
|
||||
Validator<String> get amountValidator =>
|
||||
AmountValidator(currency: walletTypeToCryptoCurrency(_wallet.type));
|
||||
|
||||
Validator get allAmountValidator => AllAmountValidator();
|
||||
Validator<String> get allAmountValidator => AllAmountValidator();
|
||||
|
||||
Validator get addressValidator => AddressValidator(type: selectedCryptoCurrency);
|
||||
Validator<String> get addressValidator => AddressValidator(type: selectedCryptoCurrency);
|
||||
|
||||
Validator get textValidator => TextValidator();
|
||||
Validator<String> get textValidator => TextValidator();
|
||||
|
||||
final FiatCurrency fiatFromSettings;
|
||||
|
||||
@@ -146,7 +151,7 @@ abstract class SendViewModelBase with Store {
|
||||
PendingTransaction? pendingTransaction;
|
||||
|
||||
@computed
|
||||
String get balance => balanceViewModel.availableBalance;
|
||||
String get balance => _wallet.balance[selectedCryptoCurrency]!.formattedAvailableBalance;
|
||||
|
||||
@computed
|
||||
bool get isFiatDisabled => balanceViewModel.isFiatDisabled;
|
||||
@@ -176,10 +181,9 @@ abstract class SendViewModelBase with Store {
|
||||
|
||||
List<CryptoCurrency> currencies;
|
||||
|
||||
bool get hasMultiRecipient => _wallet.type != WalletType.haven;
|
||||
|
||||
bool get hasYat => outputs
|
||||
.any((out) => out.isParsedAddress && out.parsedAddress.parseFrom == ParseFrom.yatRecord);
|
||||
bool get hasYat => outputs.any((out) =>
|
||||
out.isParsedAddress &&
|
||||
out.parsedAddress.parseFrom == ParseFrom.yatRecord);
|
||||
|
||||
WalletType get walletType => _wallet.type;
|
||||
|
||||
@@ -198,6 +202,7 @@ abstract class SendViewModelBase with Store {
|
||||
final ContactListViewModel contactListViewModel;
|
||||
final FiatConversionStore _fiatConversationStore;
|
||||
final Box<TransactionDescription> transactionDescriptionBox;
|
||||
final bool hasMultipleTokens;
|
||||
|
||||
@computed
|
||||
List<ContactRecord> get contactsToShow => contactListViewModel.contacts
|
||||
@@ -351,6 +356,15 @@ abstract class SendViewModelBase with Store {
|
||||
|
||||
return haven!.createHavenTransactionCreationCredentials(
|
||||
outputs: outputs, priority: priority, assetType: selectedCryptoCurrency.title);
|
||||
case WalletType.ethereum:
|
||||
final priority = _settingsStore.priority[_wallet.type];
|
||||
|
||||
if (priority == null) {
|
||||
throw Exception('Priority is null for wallet type: ${_wallet.type}');
|
||||
}
|
||||
|
||||
return ethereum!.createEthereumTransactionCredentials(
|
||||
outputs, priority: priority, currency: selectedCryptoCurrency);
|
||||
default:
|
||||
throw Exception('Unexpected wallet type: ${_wallet.type}');
|
||||
}
|
||||
@@ -369,11 +383,22 @@ abstract class SendViewModelBase with Store {
|
||||
}
|
||||
|
||||
bool _isEqualCurrency(String currency) =>
|
||||
currency.toLowerCase() == _wallet.currency.title.toLowerCase();
|
||||
_wallet.balance.keys.any((e) => currency.toLowerCase() == e.title.toLowerCase());
|
||||
|
||||
@action
|
||||
void onClose() => _settingsStore.fiatCurrency = fiatFromSettings;
|
||||
|
||||
@action
|
||||
void setFiatCurrency(FiatCurrency fiat) => _settingsStore.fiatCurrency = fiat;
|
||||
void setFiatCurrency(FiatCurrency fiat) =>
|
||||
_settingsStore.fiatCurrency = fiat;
|
||||
|
||||
@action
|
||||
void setSelectedCryptoCurrency(String cryptoCurrency) {
|
||||
try {
|
||||
selectedCryptoCurrency = _wallet.balance.keys
|
||||
.firstWhere((e) => cryptoCurrency.toLowerCase() == e.title.toLowerCase());
|
||||
} catch (e) {
|
||||
selectedCryptoCurrency = _wallet.currency;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,23 +11,20 @@ part 'template_view_model.g.dart';
|
||||
class TemplateViewModel = TemplateViewModelBase with _$TemplateViewModel;
|
||||
|
||||
abstract class TemplateViewModelBase with Store {
|
||||
final CryptoCurrency cryptoCurrency;
|
||||
final WalletBase _wallet;
|
||||
final SettingsStore _settingsStore;
|
||||
final FiatConversionStore _fiatConversationStore;
|
||||
|
||||
TemplateViewModelBase(
|
||||
{required this.cryptoCurrency,
|
||||
required WalletBase wallet,
|
||||
required SettingsStore settingsStore,
|
||||
required FiatConversionStore fiatConversationStore})
|
||||
: _wallet = wallet,
|
||||
TemplateViewModelBase({
|
||||
required WalletBase wallet,
|
||||
required SettingsStore settingsStore,
|
||||
required FiatConversionStore fiatConversationStore,
|
||||
}) : _wallet = wallet,
|
||||
_settingsStore = settingsStore,
|
||||
_fiatConversationStore = fiatConversationStore,
|
||||
output = Output(wallet, settingsStore, fiatConversationStore,
|
||||
() => wallet.currency) {
|
||||
output = Output(
|
||||
_wallet, _settingsStore, _fiatConversationStore, () => cryptoCurrency);
|
||||
_currency = wallet.currency,
|
||||
output = Output(wallet, settingsStore, fiatConversationStore, () => wallet.currency) {
|
||||
output = Output(_wallet, _settingsStore, _fiatConversationStore, () => _currency);
|
||||
}
|
||||
|
||||
@observable
|
||||
@@ -39,6 +36,9 @@ abstract class TemplateViewModelBase with Store {
|
||||
@observable
|
||||
String address = '';
|
||||
|
||||
@observable
|
||||
CryptoCurrency _currency;
|
||||
|
||||
@observable
|
||||
bool isCurrencySelected = true;
|
||||
|
||||
@@ -66,8 +66,7 @@ abstract class TemplateViewModelBase with Store {
|
||||
output.reset();
|
||||
}
|
||||
|
||||
Template toTemplate(
|
||||
{required String cryptoCurrency, required String fiatCurrency}) {
|
||||
Template toTemplate({required String cryptoCurrency, required String fiatCurrency}) {
|
||||
return Template(
|
||||
isCurrencySelectedRaw: isCurrencySelected,
|
||||
nameRaw: name,
|
||||
@@ -77,4 +76,13 @@ abstract class TemplateViewModelBase with Store {
|
||||
amountRaw: output.cryptoAmount,
|
||||
amountFiatRaw: output.fiatAmount);
|
||||
}
|
||||
|
||||
@action
|
||||
void changeSelectedCurrency(CryptoCurrency currency) {
|
||||
isCurrencySelected = true;
|
||||
_currency = currency;
|
||||
}
|
||||
|
||||
@computed
|
||||
CryptoCurrency get selectedCurrency => _currency;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import 'package:cake_wallet/entities/exchange_api_mode.dart';
|
||||
import 'package:cake_wallet/ethereum/ethereum.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cake_wallet/entities/fiat_api_mode.dart';
|
||||
|
||||
@@ -8,9 +11,10 @@ part 'privacy_settings_view_model.g.dart';
|
||||
class PrivacySettingsViewModel = PrivacySettingsViewModelBase with _$PrivacySettingsViewModel;
|
||||
|
||||
abstract class PrivacySettingsViewModelBase with Store {
|
||||
PrivacySettingsViewModelBase(this._settingsStore);
|
||||
PrivacySettingsViewModelBase(this._settingsStore, this._wallet);
|
||||
|
||||
final SettingsStore _settingsStore;
|
||||
final WalletBase _wallet;
|
||||
|
||||
@computed
|
||||
ExchangeApiMode get exchangeStatus => _settingsStore.exchangeStatus;
|
||||
@@ -30,8 +34,14 @@ abstract class PrivacySettingsViewModelBase with Store {
|
||||
@computed
|
||||
bool get disableSell => _settingsStore.disableSell;
|
||||
|
||||
@computed
|
||||
bool get useEtherscan => _settingsStore.useEtherscan;
|
||||
|
||||
bool get canUseEtherscan => _wallet.type == WalletType.ethereum;
|
||||
|
||||
@action
|
||||
void setShouldSaveRecipientAddress(bool value) => _settingsStore.shouldSaveRecipientAddress = value;
|
||||
void setShouldSaveRecipientAddress(bool value) =>
|
||||
_settingsStore.shouldSaveRecipientAddress = value;
|
||||
|
||||
@action
|
||||
void setExchangeApiMode(ExchangeApiMode value) => _settingsStore.exchangeStatus = value;
|
||||
@@ -48,4 +58,9 @@ abstract class PrivacySettingsViewModelBase with Store {
|
||||
@action
|
||||
void setDisableSell(bool value) => _settingsStore.disableSell = value;
|
||||
|
||||
@action
|
||||
void setUseEtherscan(bool value) {
|
||||
_settingsStore.useEtherscan = value;
|
||||
ethereum!.updateEtherscanUsageState(_wallet, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import 'package:cw_core/transaction_direction.dart';
|
||||
import 'package:cake_wallet/utils/date_formatter.dart';
|
||||
import 'package:cake_wallet/entities/transaction_description.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:intl/src/intl/date_format.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
@@ -27,105 +28,27 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
required this.wallet,
|
||||
required this.settingsStore})
|
||||
: items = [],
|
||||
isRecipientAddressShown = false,
|
||||
showRecipientAddress = settingsStore.shouldSaveRecipientAddress {
|
||||
isRecipientAddressShown = false,
|
||||
showRecipientAddress = settingsStore.shouldSaveRecipientAddress {
|
||||
final dateFormat = DateFormatter.withCurrentLocal();
|
||||
final tx = transactionInfo;
|
||||
|
||||
if (wallet.type == WalletType.monero) {
|
||||
final key = tx.additionalInfo['key'] as String?;
|
||||
final accountIndex = tx.additionalInfo['accountIndex'] as int;
|
||||
final addressIndex = tx.additionalInfo['addressIndex'] as int;
|
||||
final feeFormatted = tx.feeFormatted();
|
||||
final _items = [
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_transaction_id, value: tx.id),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_date,
|
||||
value: dateFormat.format(tx.date)),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_height, value: '${tx.height}'),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_amount,
|
||||
value: tx.amountFormatted()),
|
||||
if (feeFormatted != null)
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_fee, value: feeFormatted),
|
||||
if (key?.isNotEmpty ?? false)
|
||||
StandartListItem(title: S.current.transaction_key, value: key!)
|
||||
];
|
||||
|
||||
if (tx.direction == TransactionDirection.incoming &&
|
||||
accountIndex != null &&
|
||||
addressIndex != null) {
|
||||
try {
|
||||
final address = monero!.getTransactionAddress(wallet, accountIndex, addressIndex);
|
||||
final label = monero!.getSubaddressLabel(wallet, accountIndex, addressIndex);
|
||||
|
||||
if (address?.isNotEmpty ?? false) {
|
||||
isRecipientAddressShown = true;
|
||||
_items.add(
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_recipient_address,
|
||||
value: address));
|
||||
}
|
||||
|
||||
if (label?.isNotEmpty ?? false) {
|
||||
_items.add(
|
||||
StandartListItem(
|
||||
title: S.current.address_label,
|
||||
value: label)
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
print(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
items.addAll(_items);
|
||||
}
|
||||
|
||||
if (wallet.type == WalletType.bitcoin
|
||||
|| wallet.type == WalletType.litecoin) {
|
||||
final _items = [
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_transaction_id, value: tx.id),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_date,
|
||||
value: dateFormat.format(tx.date)),
|
||||
StandartListItem(
|
||||
title: S.current.confirmations,
|
||||
value: tx.confirmations.toString()),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_height, value: '${tx.height}'),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_amount,
|
||||
value: tx.amountFormatted()),
|
||||
if (tx.feeFormatted()?.isNotEmpty ?? false)
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_fee,
|
||||
value: tx.feeFormatted()!),
|
||||
];
|
||||
|
||||
items.addAll(_items);
|
||||
}
|
||||
|
||||
if (wallet.type == WalletType.haven) {
|
||||
items.addAll([
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_transaction_id, value: tx.id),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_date,
|
||||
value: dateFormat.format(tx.date)),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_height, value: '${tx.height}'),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_amount,
|
||||
value: tx.amountFormatted()),
|
||||
if (tx.feeFormatted()?.isNotEmpty ?? false)
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_fee, value: tx.feeFormatted()!),
|
||||
]);
|
||||
switch (wallet.type) {
|
||||
case WalletType.monero:
|
||||
_addMoneroListItems(tx, dateFormat);
|
||||
break;
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.litecoin:
|
||||
_addElectrumListItems(tx, dateFormat);
|
||||
break;
|
||||
case WalletType.haven:
|
||||
_addHavenListItems(tx, dateFormat);
|
||||
break;
|
||||
case WalletType.ethereum:
|
||||
_addEthereumListItems(tx, dateFormat);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (showRecipientAddress && !isRecipientAddressShown) {
|
||||
@@ -136,10 +59,9 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
|
||||
if (recipientAddress?.isNotEmpty ?? false) {
|
||||
items.add(StandartListItem(
|
||||
title: S.current.transaction_details_recipient_address,
|
||||
value: recipientAddress!));
|
||||
title: S.current.transaction_details_recipient_address, value: recipientAddress!));
|
||||
}
|
||||
} catch(_) {
|
||||
} catch (_) {
|
||||
// FIX-ME: Unhandled exception
|
||||
}
|
||||
}
|
||||
@@ -192,6 +114,8 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
return 'https://blockchair.com/litecoin/transaction/${txId}';
|
||||
case WalletType.haven:
|
||||
return 'https://explorer.havenprotocol.org/search?value=${txId}';
|
||||
case WalletType.ethereum:
|
||||
return 'https://etherscan.io/tx/${txId}';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
@@ -207,8 +131,92 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
return S.current.view_transaction_on + 'Blockchair.com';
|
||||
case WalletType.haven:
|
||||
return S.current.view_transaction_on + 'explorer.havenprotocol.org';
|
||||
case WalletType.ethereum:
|
||||
return S.current.view_transaction_on + 'etherscan.io';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
void _addMoneroListItems(TransactionInfo tx, DateFormat dateFormat) {
|
||||
final key = tx.additionalInfo['key'] as String?;
|
||||
final accountIndex = tx.additionalInfo['accountIndex'] as int;
|
||||
final addressIndex = tx.additionalInfo['addressIndex'] as int;
|
||||
final feeFormatted = tx.feeFormatted();
|
||||
final _items = [
|
||||
StandartListItem(title: S.current.transaction_details_transaction_id, value: tx.id),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_date, value: dateFormat.format(tx.date)),
|
||||
StandartListItem(title: S.current.transaction_details_height, value: '${tx.height}'),
|
||||
StandartListItem(title: S.current.transaction_details_amount, value: tx.amountFormatted()),
|
||||
if (feeFormatted != null)
|
||||
StandartListItem(title: S.current.transaction_details_fee, value: feeFormatted),
|
||||
if (key?.isNotEmpty ?? false) StandartListItem(title: S.current.transaction_key, value: key!),
|
||||
];
|
||||
|
||||
if (tx.direction == TransactionDirection.incoming) {
|
||||
try {
|
||||
final address = monero!.getTransactionAddress(wallet, accountIndex, addressIndex);
|
||||
final label = monero!.getSubaddressLabel(wallet, accountIndex, addressIndex);
|
||||
|
||||
if (address.isNotEmpty) {
|
||||
isRecipientAddressShown = true;
|
||||
_items.add(StandartListItem(
|
||||
title: S.current.transaction_details_recipient_address,
|
||||
value: address,
|
||||
));
|
||||
}
|
||||
|
||||
if (label.isNotEmpty) {
|
||||
_items.add(StandartListItem(title: S.current.address_label, value: label));
|
||||
}
|
||||
} catch (e) {
|
||||
print(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
items.addAll(_items);
|
||||
}
|
||||
|
||||
void _addElectrumListItems(TransactionInfo tx, DateFormat dateFormat) {
|
||||
final _items = [
|
||||
StandartListItem(title: S.current.transaction_details_transaction_id, value: tx.id),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_date, value: dateFormat.format(tx.date)),
|
||||
StandartListItem(title: S.current.confirmations, value: tx.confirmations.toString()),
|
||||
StandartListItem(title: S.current.transaction_details_height, value: '${tx.height}'),
|
||||
StandartListItem(title: S.current.transaction_details_amount, value: tx.amountFormatted()),
|
||||
if (tx.feeFormatted()?.isNotEmpty ?? false)
|
||||
StandartListItem(title: S.current.transaction_details_fee, value: tx.feeFormatted()!),
|
||||
];
|
||||
|
||||
items.addAll(_items);
|
||||
}
|
||||
|
||||
void _addHavenListItems(TransactionInfo tx, DateFormat dateFormat) {
|
||||
items.addAll([
|
||||
StandartListItem(title: S.current.transaction_details_transaction_id, value: tx.id),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_date, value: dateFormat.format(tx.date)),
|
||||
StandartListItem(title: S.current.transaction_details_height, value: '${tx.height}'),
|
||||
StandartListItem(title: S.current.transaction_details_amount, value: tx.amountFormatted()),
|
||||
if (tx.feeFormatted()?.isNotEmpty ?? false)
|
||||
StandartListItem(title: S.current.transaction_details_fee, value: tx.feeFormatted()!),
|
||||
]);
|
||||
}
|
||||
|
||||
void _addEthereumListItems(TransactionInfo tx, DateFormat dateFormat) {
|
||||
final _items = [
|
||||
StandartListItem(title: S.current.transaction_details_transaction_id, value: tx.id),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_date, value: dateFormat.format(tx.date)),
|
||||
StandartListItem(title: S.current.confirmations, value: tx.confirmations.toString()),
|
||||
StandartListItem(title: S.current.transaction_details_height, value: '${tx.height}'),
|
||||
StandartListItem(title: S.current.transaction_details_amount, value: tx.amountFormatted()),
|
||||
if (tx.feeFormatted()?.isNotEmpty ?? false)
|
||||
StandartListItem(title: S.current.transaction_details_fee, value: tx.feeFormatted()!),
|
||||
];
|
||||
|
||||
items.addAll(_items);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:cake_wallet/ethereum/ethereum.dart';
|
||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
|
||||
import 'package:cake_wallet/store/yat/yat_store.dart';
|
||||
@@ -93,6 +94,22 @@ class LitecoinURI extends PaymentURI {
|
||||
}
|
||||
}
|
||||
|
||||
class EthereumURI extends PaymentURI {
|
||||
EthereumURI({required String amount, required String address})
|
||||
: super(amount: amount, address: address);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
var base = 'ethereum:' + address;
|
||||
|
||||
if (amount.isNotEmpty) {
|
||||
base += '?amount=${amount.replaceAll(',', '.')}';
|
||||
}
|
||||
|
||||
return base;
|
||||
}
|
||||
}
|
||||
|
||||
abstract class WalletAddressListViewModelBase with Store {
|
||||
WalletAddressListViewModelBase({
|
||||
required AppStore appStore,
|
||||
@@ -151,6 +168,10 @@ abstract class WalletAddressListViewModelBase with Store {
|
||||
return LitecoinURI(amount: amount, address: address.address);
|
||||
}
|
||||
|
||||
if (_wallet.type == WalletType.ethereum) {
|
||||
return EthereumURI(amount: amount, address: address.address);
|
||||
}
|
||||
|
||||
throw Exception('Unexpected type: ${type.toString()}');
|
||||
}
|
||||
|
||||
@@ -202,6 +223,12 @@ abstract class WalletAddressListViewModelBase with Store {
|
||||
addressList.addAll(bitcoinAddresses);
|
||||
}
|
||||
|
||||
if (wallet.type == WalletType.ethereum) {
|
||||
final primaryAddress = ethereum!.getAddress(wallet);
|
||||
|
||||
addressList.add(WalletAddressListItem(isPrimary: true, name: null, address: primaryAddress));
|
||||
}
|
||||
|
||||
return addressList;
|
||||
}
|
||||
|
||||
@@ -226,6 +253,10 @@ abstract class WalletAddressListViewModelBase with Store {
|
||||
@computed
|
||||
bool get hasAddressList => _wallet.type == WalletType.monero || _wallet.type == WalletType.haven;
|
||||
|
||||
@computed
|
||||
bool get showElectrumAddressDisclaimer =>
|
||||
_wallet.type == WalletType.bitcoin || _wallet.type == WalletType.litecoin;
|
||||
|
||||
@observable
|
||||
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> _wallet;
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@ class WalletKeysViewModel = WalletKeysViewModelBase with _$WalletKeysViewModel;
|
||||
abstract class WalletKeysViewModelBase with Store {
|
||||
WalletKeysViewModelBase(this._appStore)
|
||||
: title = _appStore.wallet!.type == WalletType.bitcoin ||
|
||||
_appStore.wallet!.type == WalletType.litecoin
|
||||
_appStore.wallet!.type == WalletType.litecoin ||
|
||||
_appStore.wallet!.type == WalletType.ethereum
|
||||
? S.current.wallet_seed
|
||||
: S.current.wallet_keys,
|
||||
_restoreHeight = _appStore.wallet!.walletInfo.restoreHeight,
|
||||
@@ -89,7 +90,8 @@ abstract class WalletKeysViewModelBase with Store {
|
||||
}
|
||||
|
||||
if (_appStore.wallet!.type == WalletType.bitcoin ||
|
||||
_appStore.wallet!.type == WalletType.litecoin) {
|
||||
_appStore.wallet!.type == WalletType.litecoin ||
|
||||
_appStore.wallet!.type == WalletType.ethereum) {
|
||||
items.addAll([
|
||||
StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed),
|
||||
]);
|
||||
@@ -116,6 +118,8 @@ abstract class WalletKeysViewModelBase with Store {
|
||||
return 'litecoin-wallet';
|
||||
case WalletType.haven:
|
||||
return 'haven-wallet';
|
||||
case WalletType.ethereum:
|
||||
return 'ethereum-wallet';
|
||||
default:
|
||||
throw Exception('Unexpected wallet type: ${_appStore.wallet!.toString()}');
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:cake_wallet/view_model/restore/restore_wallet.dart';
|
||||
import 'package:cake_wallet/ethereum/ethereum.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
@@ -42,6 +43,8 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
|
||||
case WalletType.haven:
|
||||
return haven!.createHavenNewWalletCredentials(
|
||||
name: name, language: options as String);
|
||||
case WalletType.ethereum:
|
||||
return ethereum!.createEthereumNewWalletCredentials(name: name);
|
||||
default:
|
||||
throw Exception('Unexpected type: ${type.toString()}');;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:cake_wallet/core/mnemonic_length.dart';
|
||||
import 'package:cake_wallet/view_model/restore/restore_wallet.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:cake_wallet/ethereum/ethereum.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
@@ -85,6 +86,11 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||
height: height,
|
||||
mnemonic: seed,
|
||||
password: password);
|
||||
case WalletType.ethereum:
|
||||
return ethereum!.createEthereumRestoreWalletFromSeedCredentials(
|
||||
name: name,
|
||||
mnemonic: seed,
|
||||
password: password);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user