mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-29 06:38:45 +01:00
CW-438 add nano (#1015)
* 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 [skip ci] * - 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 [skip ci] * 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 [skip ci] * 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` [skip-ci] * initial changes * more base config stuff * config changes * successfully builds! * save * successfully add nano wallet * save * seed generation * receive screen + node screen working * tx history working and fiat fixes * balance working * derivation updates * nano-unfinished * sends working * remove fees from send screen, send and receive transactions working * fixes + auto receive incoming txs * fix for scanning QR codes * save * update translations * fixes * more fixes * more strings * small fix * fix github actions workflow * potential fix * potential fix * ci/cd fix * change rep working * seed generation fixes * fixes * save * change rep screen functional * save * banano changes * fixes, start adding ui for PoW * pow node changes * update translations * fix * account changing barely working * save * disable account generation * small fix * save * UI work * save * fixes after merge main * fixes * remove monero stuff, work on derivation ui * lots of fixes + finish up seed derivation * last minute fixes * node related fixes * more fixes * small fix * more fixes * fixes * pretty big refactor for pow, still some bugs * finally works! * get transactions after send * fix * merge conflict fixes * save * fix pow node showing up twice * done * initial changes * small fix * more merge fixes * fixes * more fixes * fix * save * fix manage pow nodes setting appearing on other wallets * fix contact bug * fixes * fiat fixes * save * save * save * save * updates * cleanup * restore fix * fixes * remove deprecated alert * fix * small fix * remove outdated warning * electrum restore fixes * fixes * fixes * fix * derivation fixes * nano fixes pt.1 * nano fixes pt.2 * bip39 fixes * pownode refactor * nodes pages fixes * observer fix * ssl fix * remove old references * remove unused imports * code cleanup * small fix * small potential fix * save * undo all bitcoin related changes * remove dead code * review fixes * more fixes * fix * fix * review fix * small fix * nano derivation and nanoutil fixes * exchange nano fix * nano review fixes pt.1 * nano fixes pt.2 * nano fixes pt.3 * remove old imports + stop using dynamic in di * nanoutil fixes * add nano.dart to gitignore, configure fixes * review fixes, getnanowalletservice removed * fix settings screen, add changeRep to configure.dart, other minor fixes * remove manage_pow_nodes_page, key derivation edge case handled * remove old refs * more small fixes * Generic Enhancements/Minor fixes * review fixes * hopefully final fixes * review fixes * node connection fixes --------- Co-authored-by: OmarHatem <omarh.ismail1@gmail.com> Co-authored-by: Justin Ehrenhofer <justin.ehrenhofer@gmail.com> Co-authored-by: fossephate <fosse@book.local>
This commit is contained in:
co-authored by
OmarHatem
Justin Ehrenhofer
fossephate
parent
6233422643
commit
4c60b178be
@@ -15,12 +15,11 @@ import 'package:collection/collection.dart';
|
||||
|
||||
part 'contact_list_view_model.g.dart';
|
||||
|
||||
class ContactListViewModel = ContactListViewModelBase
|
||||
with _$ContactListViewModel;
|
||||
class ContactListViewModel = ContactListViewModelBase with _$ContactListViewModel;
|
||||
|
||||
abstract class ContactListViewModelBase with Store {
|
||||
ContactListViewModelBase(this.contactSource, this.walletInfoSource,
|
||||
this._currency, this.settingsStore)
|
||||
ContactListViewModelBase(
|
||||
this.contactSource, this.walletInfoSource, this._currency, this.settingsStore)
|
||||
: contacts = ObservableList<ContactRecord>(),
|
||||
walletContacts = [],
|
||||
isAutoGenerateEnabled =
|
||||
@@ -48,6 +47,12 @@ abstract class ContactListViewModelBase with Store {
|
||||
walletTypeToCryptoCurrency(info.type),
|
||||
));
|
||||
});
|
||||
} else if (info.address != null) {
|
||||
walletContacts.add(WalletContact(
|
||||
info.address,
|
||||
info.name,
|
||||
walletTypeToCryptoCurrency(info.type),
|
||||
));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -78,14 +83,12 @@ abstract class ContactListViewModelBase with Store {
|
||||
Future<void> delete(ContactRecord contact) async => contact.original.delete();
|
||||
|
||||
@computed
|
||||
List<ContactRecord> get contactsToShow => contacts
|
||||
.where((element) => _isValidForCurrency(element))
|
||||
.toList();
|
||||
List<ContactRecord> get contactsToShow =>
|
||||
contacts.where((element) => _isValidForCurrency(element)).toList();
|
||||
|
||||
@computed
|
||||
List<WalletContact> get walletContactsToShow => walletContacts
|
||||
.where((element) => _isValidForCurrency(element))
|
||||
.toList();
|
||||
List<WalletContact> get walletContactsToShow =>
|
||||
walletContacts.where((element) => _isValidForCurrency(element)).toList();
|
||||
|
||||
bool _isValidForCurrency(ContactBase element) {
|
||||
return _currency == null || element.type == _currency || element.type.title == _currency!.tag;
|
||||
|
||||
@@ -47,74 +47,71 @@ abstract class DashboardViewModelBase with Store {
|
||||
required this.yatStore,
|
||||
required this.ordersStore,
|
||||
required this.anonpayTransactionsStore})
|
||||
: isOutdatedElectrumWallet = false,
|
||||
hasSellAction = false,
|
||||
hasBuyAction = false,
|
||||
hasExchangeAction = false,
|
||||
isShowFirstYatIntroduction = false,
|
||||
isShowSecondYatIntroduction = false,
|
||||
isShowThirdYatIntroduction = false,
|
||||
filterItems = {
|
||||
S.current.transactions: [
|
||||
FilterItem(
|
||||
value: () => transactionFilterStore.displayAll,
|
||||
caption: S.current.all_transactions,
|
||||
onChanged: transactionFilterStore.toggleAll),
|
||||
FilterItem(
|
||||
value: () => transactionFilterStore.displayIncoming,
|
||||
caption: S.current.incoming,
|
||||
onChanged: transactionFilterStore.toggleIncoming),
|
||||
FilterItem(
|
||||
value: () => transactionFilterStore.displayOutgoing,
|
||||
caption: S.current.outgoing,
|
||||
onChanged: transactionFilterStore.toggleOutgoing),
|
||||
// FilterItem(
|
||||
// value: () => false,
|
||||
// caption: S.current.transactions_by_date,
|
||||
// onChanged: null),
|
||||
],
|
||||
S.current.trades: [
|
||||
FilterItem(
|
||||
value: () => tradeFilterStore.displayAllTrades,
|
||||
caption: S.current.all_trades,
|
||||
onChanged: () =>
|
||||
tradeFilterStore.toggleDisplayExchange(ExchangeProviderDescription.all)),
|
||||
FilterItem(
|
||||
value: () => tradeFilterStore.displayChangeNow,
|
||||
caption: ExchangeProviderDescription.changeNow.title,
|
||||
onChanged: () =>
|
||||
tradeFilterStore.toggleDisplayExchange(ExchangeProviderDescription.changeNow)),
|
||||
FilterItem(
|
||||
value: () => tradeFilterStore.displaySideShift,
|
||||
caption: ExchangeProviderDescription.sideShift.title,
|
||||
onChanged: () =>
|
||||
tradeFilterStore.toggleDisplayExchange(ExchangeProviderDescription.sideShift)),
|
||||
FilterItem(
|
||||
value: () => tradeFilterStore.displaySimpleSwap,
|
||||
caption: ExchangeProviderDescription.simpleSwap.title,
|
||||
onChanged: () =>
|
||||
tradeFilterStore.toggleDisplayExchange(ExchangeProviderDescription.simpleSwap)),
|
||||
FilterItem(
|
||||
value: () => tradeFilterStore.displayTrocador,
|
||||
caption: ExchangeProviderDescription.trocador.title,
|
||||
onChanged: () =>
|
||||
tradeFilterStore.toggleDisplayExchange(ExchangeProviderDescription.trocador)),
|
||||
FilterItem(
|
||||
value: () => tradeFilterStore.displayExolix,
|
||||
caption: ExchangeProviderDescription.exolix.title,
|
||||
onChanged: () =>
|
||||
tradeFilterStore.toggleDisplayExchange(ExchangeProviderDescription.exolix)),
|
||||
]
|
||||
},
|
||||
subname = '',
|
||||
name = appStore.wallet!.name,
|
||||
type = appStore.wallet!.type,
|
||||
transactions = ObservableList<TransactionListItem>(),
|
||||
wallet = appStore.wallet! {
|
||||
: hasSellAction = false,
|
||||
hasBuyAction = false,
|
||||
hasExchangeAction = false,
|
||||
isShowFirstYatIntroduction = false,
|
||||
isShowSecondYatIntroduction = false,
|
||||
isShowThirdYatIntroduction = false,
|
||||
filterItems = {
|
||||
S.current.transactions: [
|
||||
FilterItem(
|
||||
value: () => transactionFilterStore.displayAll,
|
||||
caption: S.current.all_transactions,
|
||||
onChanged: transactionFilterStore.toggleAll),
|
||||
FilterItem(
|
||||
value: () => transactionFilterStore.displayIncoming,
|
||||
caption: S.current.incoming,
|
||||
onChanged:transactionFilterStore.toggleIncoming),
|
||||
FilterItem(
|
||||
value: () => transactionFilterStore.displayOutgoing,
|
||||
caption: S.current.outgoing,
|
||||
onChanged: transactionFilterStore.toggleOutgoing),
|
||||
// FilterItem(
|
||||
// value: () => false,
|
||||
// caption: S.current.transactions_by_date,
|
||||
// onChanged: null),
|
||||
],
|
||||
S.current.trades: [
|
||||
FilterItem(
|
||||
value: () => tradeFilterStore.displayAllTrades,
|
||||
caption: S.current.all_trades,
|
||||
onChanged: () => tradeFilterStore
|
||||
.toggleDisplayExchange(ExchangeProviderDescription.all)),
|
||||
FilterItem(
|
||||
value: () => tradeFilterStore.displayChangeNow,
|
||||
caption: ExchangeProviderDescription.changeNow.title,
|
||||
onChanged: () => tradeFilterStore
|
||||
.toggleDisplayExchange(ExchangeProviderDescription.changeNow)),
|
||||
FilterItem(
|
||||
value: () => tradeFilterStore.displaySideShift,
|
||||
caption: ExchangeProviderDescription.sideShift.title,
|
||||
onChanged: () => tradeFilterStore
|
||||
.toggleDisplayExchange(ExchangeProviderDescription.sideShift)),
|
||||
FilterItem(
|
||||
value: () => tradeFilterStore.displaySimpleSwap,
|
||||
caption: ExchangeProviderDescription.simpleSwap.title,
|
||||
onChanged: () => tradeFilterStore
|
||||
.toggleDisplayExchange(ExchangeProviderDescription.simpleSwap)),
|
||||
FilterItem(
|
||||
value: () => tradeFilterStore.displayTrocador,
|
||||
caption: ExchangeProviderDescription.trocador.title,
|
||||
onChanged: () => tradeFilterStore
|
||||
.toggleDisplayExchange(ExchangeProviderDescription.trocador)),
|
||||
FilterItem(
|
||||
value: () => tradeFilterStore.displayExolix,
|
||||
caption: ExchangeProviderDescription.exolix.title,
|
||||
onChanged: () => tradeFilterStore
|
||||
.toggleDisplayExchange(ExchangeProviderDescription.exolix)),
|
||||
]
|
||||
},
|
||||
subname = '',
|
||||
name = appStore.wallet!.name,
|
||||
type = appStore.wallet!.type,
|
||||
transactions = ObservableList<TransactionListItem>(),
|
||||
wallet = appStore.wallet! {
|
||||
name = wallet.name;
|
||||
type = wallet.type;
|
||||
isOutdatedElectrumWallet =
|
||||
wallet.type == WalletType.bitcoin && wallet.seed!.split(' ').length < 24;
|
||||
isShowFirstYatIntroduction = false;
|
||||
isShowSecondYatIntroduction = false;
|
||||
isShowThirdYatIntroduction = false;
|
||||
@@ -151,6 +148,11 @@ abstract class DashboardViewModelBase with Store {
|
||||
settingsStore: appStore.settingsStore)));
|
||||
}
|
||||
|
||||
// TODO: nano sub-account generation is disabled:
|
||||
// if (_wallet.type == WalletType.nano || _wallet.type == WalletType.banano) {
|
||||
// subname = nano!.getCurrentAccount(_wallet).label;
|
||||
// }
|
||||
|
||||
reaction((_) => appStore.wallet, _onWalletChange);
|
||||
|
||||
connectMapToListWithTransform(
|
||||
@@ -315,12 +317,16 @@ abstract class DashboardViewModelBase with Store {
|
||||
|
||||
ReactionDisposer? _onMoneroBalanceChangeReaction;
|
||||
|
||||
@observable
|
||||
bool isOutdatedElectrumWallet;
|
||||
@computed
|
||||
bool get hasPowNodes => wallet.type == WalletType.nano || wallet.type == WalletType.banano;
|
||||
|
||||
Future<void> reconnect() async {
|
||||
final node = appStore.settingsStore.getCurrentNode(wallet.type);
|
||||
await wallet.connectToNode(node: node);
|
||||
if (hasPowNodes) {
|
||||
final powNode = settingsStore.getCurrentPowNode(wallet.type);
|
||||
await wallet.connectToPowNode(node: powNode);
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
@@ -333,8 +339,6 @@ abstract class DashboardViewModelBase with Store {
|
||||
this.wallet = wallet;
|
||||
type = wallet.type;
|
||||
name = wallet.name;
|
||||
isOutdatedElectrumWallet =
|
||||
wallet.type == WalletType.bitcoin && wallet.seed!.split(' ').length < 24;
|
||||
updateActions();
|
||||
|
||||
if (wallet.type == WalletType.monero) {
|
||||
|
||||
@@ -2,6 +2,7 @@ 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:cake_wallet/nano/nano.dart';
|
||||
import 'package:cw_core/transaction_direction.dart';
|
||||
import 'package:cw_core/transaction_info.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
@@ -16,9 +17,7 @@ import 'package:cw_core/wallet_type.dart';
|
||||
|
||||
class TransactionListItem extends ActionListItem with Keyable {
|
||||
TransactionListItem(
|
||||
{required this.transaction,
|
||||
required this.balanceViewModel,
|
||||
required this.settingsStore});
|
||||
{required this.transaction, required this.balanceViewModel, required this.settingsStore});
|
||||
|
||||
final TransactionInfo transaction;
|
||||
final BalanceViewModel balanceViewModel;
|
||||
@@ -34,10 +33,9 @@ class TransactionListItem extends ActionListItem with Keyable {
|
||||
dynamic get keyIndex => transaction.id;
|
||||
|
||||
String get formattedCryptoAmount {
|
||||
return displayMode == BalanceDisplayMode.hiddenBalance
|
||||
? '---'
|
||||
: transaction.amountFormatted();
|
||||
return displayMode == BalanceDisplayMode.hiddenBalance ? '---' : transaction.amountFormatted();
|
||||
}
|
||||
|
||||
String get formattedTitle {
|
||||
if (transaction.direction == TransactionDirection.incoming) {
|
||||
return S.current.received;
|
||||
@@ -57,33 +55,47 @@ class TransactionListItem extends ActionListItem with Keyable {
|
||||
if (transaction.direction == TransactionDirection.incoming) {
|
||||
if (balanceViewModel.wallet.type == WalletType.monero ||
|
||||
balanceViewModel.wallet.type == WalletType.haven) {
|
||||
return formattedPendingStatus;
|
||||
}
|
||||
return formattedPendingStatus;
|
||||
}
|
||||
return transaction.isPending ? S.current.pending : '';
|
||||
}
|
||||
return transaction.isPending ? S.current.pending : '';
|
||||
}
|
||||
|
||||
String get formattedFiatAmount {
|
||||
var amount = '';
|
||||
|
||||
switch(balanceViewModel.wallet.type) {
|
||||
switch (balanceViewModel.wallet.type) {
|
||||
case WalletType.monero:
|
||||
amount = calculateFiatAmountRaw(
|
||||
cryptoAmount: monero!.formatterMoneroAmountToDouble(amount: transaction.amount),
|
||||
price: price);
|
||||
cryptoAmount: monero!.formatterMoneroAmountToDouble(amount: transaction.amount),
|
||||
price: price);
|
||||
break;
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.litecoin:
|
||||
amount = calculateFiatAmountRaw(
|
||||
cryptoAmount: bitcoin!.formatterBitcoinAmountToDouble(amount: transaction.amount),
|
||||
price: price);
|
||||
cryptoAmount: bitcoin!.formatterBitcoinAmountToDouble(amount: transaction.amount),
|
||||
price: price);
|
||||
break;
|
||||
case WalletType.haven:
|
||||
final asset = haven!.assetOfTransaction(transaction);
|
||||
final price = balanceViewModel.fiatConvertationStore.prices[asset];
|
||||
amount = calculateFiatAmountRaw(
|
||||
cryptoAmount: haven!.formatterMoneroAmountToDouble(amount: transaction.amount),
|
||||
price: price);
|
||||
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;
|
||||
case WalletType.nano:
|
||||
amount = calculateFiatAmountRaw(
|
||||
cryptoAmount: nanoUtil!
|
||||
.getRawAsDecimal(nano!.getTransactionAmountRaw(transaction).toString(), nanoUtil!.rawPerNano)
|
||||
.toDouble(),
|
||||
price: price);
|
||||
break;
|
||||
case WalletType.ethereum:
|
||||
final asset = ethereum!.assetOfTransaction(balanceViewModel.wallet, transaction);
|
||||
|
||||
@@ -86,13 +86,12 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
|
||||
super(appStore: appStore) {
|
||||
_useTorOnly = _settingsStore.exchangeStatus == ExchangeApiMode.torOnly;
|
||||
_setProviders();
|
||||
const excludeDepositCurrencies = [CryptoCurrency.btt, CryptoCurrency.nano];
|
||||
const excludeDepositCurrencies = [CryptoCurrency.btt];
|
||||
const excludeReceiveCurrencies = [
|
||||
CryptoCurrency.xlm,
|
||||
CryptoCurrency.xrp,
|
||||
CryptoCurrency.bnb,
|
||||
CryptoCurrency.btt,
|
||||
CryptoCurrency.nano
|
||||
CryptoCurrency.btt
|
||||
];
|
||||
_initialPairBasedOnWallet();
|
||||
|
||||
@@ -703,6 +702,10 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
|
||||
depositCurrency = CryptoCurrency.eth;
|
||||
receiveCurrency = CryptoCurrency.xmr;
|
||||
break;
|
||||
case WalletType.nano:
|
||||
depositCurrency = CryptoCurrency.nano;
|
||||
receiveCurrency = CryptoCurrency.xmr;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
import 'package:cake_wallet/nano/nano.dart';
|
||||
import 'package:cw_core/nano_account.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cake_wallet/core/execution_state.dart';
|
||||
|
||||
part 'nano_account_edit_or_create_view_model.g.dart';
|
||||
|
||||
class NanoAccountEditOrCreateViewModel = NanoAccountEditOrCreateViewModelBase
|
||||
with _$NanoAccountEditOrCreateViewModel;
|
||||
|
||||
abstract class NanoAccountEditOrCreateViewModelBase with Store {
|
||||
NanoAccountEditOrCreateViewModelBase(this._nanoAccountList,
|
||||
{required WalletBase wallet, NanoAccount? accountListItem})
|
||||
: state = InitialExecutionState(),
|
||||
isEdit = accountListItem != null,
|
||||
label = accountListItem?.label ?? '',
|
||||
_accountListItem = accountListItem,
|
||||
_wallet = wallet;
|
||||
|
||||
final bool isEdit;
|
||||
|
||||
@observable
|
||||
ExecutionState state;
|
||||
|
||||
@observable
|
||||
String label;
|
||||
|
||||
final NanoAccountList _nanoAccountList;
|
||||
final NanoAccount? _accountListItem;
|
||||
final WalletBase _wallet;
|
||||
|
||||
Future<void> save() async {
|
||||
if (_wallet.type == WalletType.nano) {
|
||||
await saveNano();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> saveNano() async {
|
||||
try {
|
||||
state = IsExecutingState();
|
||||
|
||||
if (_accountListItem != null) {
|
||||
await _nanoAccountList.setLabelAccount(_wallet,
|
||||
accountIndex: _accountListItem!.id, label: label);
|
||||
} else {
|
||||
await _nanoAccountList.addAccount(_wallet, label: label);
|
||||
}
|
||||
|
||||
await _wallet.save();
|
||||
state = ExecutedSuccessfullyState();
|
||||
} catch (e) {
|
||||
state = FailureState(e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import 'package:cake_wallet/nano/nano.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cw_core/nano_account.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
|
||||
part 'nano_account_list_view_model.g.dart';
|
||||
|
||||
class NanoAccountListViewModel = NanoAccountListViewModelBase with _$NanoAccountListViewModel;
|
||||
|
||||
abstract class NanoAccountListViewModelBase with Store {
|
||||
NanoAccountListViewModelBase(this._wallet) : scrollOffsetFromTop = 0;
|
||||
|
||||
@observable
|
||||
double scrollOffsetFromTop;
|
||||
|
||||
@action
|
||||
void setScrollOffsetFromTop(double scrollOffsetFromTop) {
|
||||
this.scrollOffsetFromTop = scrollOffsetFromTop;
|
||||
}
|
||||
|
||||
CryptoCurrency get currency => _wallet.currency;
|
||||
|
||||
@computed
|
||||
List<NanoAccount> get accounts {
|
||||
if (_wallet.type == WalletType.nano) {
|
||||
return nano!
|
||||
.getAccountList(_wallet)
|
||||
.accounts
|
||||
.map((acc) => NanoAccount(
|
||||
label: acc.label,
|
||||
id: acc.id,
|
||||
isSelected: acc.id == nano?.getCurrentAccount(_wallet).id,
|
||||
))
|
||||
.toList();
|
||||
}
|
||||
|
||||
throw Exception('Unexpected wallet type: ${_wallet.type}');
|
||||
}
|
||||
|
||||
final WalletBase _wallet;
|
||||
|
||||
void select(NanoAccount item) {
|
||||
if (_wallet.type == WalletType.nano) {
|
||||
nano!.setCurrentAccount(
|
||||
_wallet,
|
||||
item.id,
|
||||
item.label,
|
||||
item.balance,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,6 +66,9 @@ abstract class NodeListViewModelBase with Store {
|
||||
case WalletType.ethereum:
|
||||
node = getEthereumDefaultNode(nodes: _nodeSource)!;
|
||||
break;
|
||||
case WalletType.nano:
|
||||
node = getNanoDefaultNode(nodes: _nodeSource)!;
|
||||
break;
|
||||
default:
|
||||
throw Exception('Unexpected wallet type: ${_appStore.wallet!.type}');
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
import 'package:cake_wallet/utils/mobx.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cw_core/node.dart';
|
||||
import 'package:cake_wallet/entities/node_list.dart';
|
||||
import 'package:cake_wallet/entities/default_settings_migration.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
|
||||
part 'pow_node_list_view_model.g.dart';
|
||||
|
||||
class PowNodeListViewModel = PowNodeListViewModelBase with _$PowNodeListViewModel;
|
||||
|
||||
abstract class PowNodeListViewModelBase with Store {
|
||||
PowNodeListViewModelBase(this._nodeSource, this._appStore)
|
||||
: nodes = ObservableList<Node>(),
|
||||
settingsStore = _appStore.settingsStore {
|
||||
_bindNodes();
|
||||
|
||||
reaction((_) => _appStore.wallet, (WalletBase? _wallet) {
|
||||
_bindNodes();
|
||||
});
|
||||
}
|
||||
|
||||
@computed
|
||||
Node get currentNode {
|
||||
final node = settingsStore.powNodes[_appStore.wallet!.type];
|
||||
|
||||
if (node == null) {
|
||||
throw Exception('No node for wallet type: ${_appStore.wallet!.type}');
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
String getAlertContent(String uri) =>
|
||||
S.current.change_current_node(uri) +
|
||||
'${uri.endsWith('.onion') || uri.contains('.onion:') ? '\n' + S.current.orbot_running_alert : ''}';
|
||||
|
||||
final ObservableList<Node> nodes;
|
||||
final SettingsStore settingsStore;
|
||||
final Box<Node> _nodeSource;
|
||||
final AppStore _appStore;
|
||||
|
||||
Future<void> reset() async {
|
||||
await resetPowToDefault(_nodeSource);
|
||||
|
||||
Node node;
|
||||
|
||||
switch (_appStore.wallet!.type) {
|
||||
case WalletType.nano:
|
||||
node = getNanoDefaultPowNode(nodes: _nodeSource)!;
|
||||
break;
|
||||
default:
|
||||
throw Exception('Unexpected wallet type: ${_appStore.wallet!.type}');
|
||||
}
|
||||
|
||||
await setAsCurrent(node);
|
||||
}
|
||||
|
||||
@action
|
||||
Future<void> delete(Node node) async => node.delete();
|
||||
|
||||
Future<void> setAsCurrent(Node node) async =>
|
||||
settingsStore.powNodes[_appStore.wallet!.type] = node;
|
||||
|
||||
@action
|
||||
void _bindNodes() {
|
||||
nodes.clear();
|
||||
_nodeSource.bindToList(
|
||||
nodes,
|
||||
filter: (val) => val.type == _appStore.wallet!.type,
|
||||
initialFire: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
import 'package:cake_wallet/core/wallet_change_listener_view_model.dart';
|
||||
import 'package:cake_wallet/entities/contact_record.dart';
|
||||
import 'package:cake_wallet/di.dart';
|
||||
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/nano/nano.dart';
|
||||
import 'package:cake_wallet/core/wallet_change_listener_view_model.dart';
|
||||
import 'package:cake_wallet/entities/contact_record.dart';
|
||||
import 'package:cake_wallet/entities/wallet_contact.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
import 'package:cake_wallet/view_model/contact_list/contact_list_view_model.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';
|
||||
@@ -16,7 +19,6 @@ import 'package:cake_wallet/core/address_validator.dart';
|
||||
import 'package:cake_wallet/core/amount_validator.dart';
|
||||
import 'package:cw_core/pending_transaction.dart';
|
||||
import 'package:cake_wallet/core/validator.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
import 'package:cake_wallet/core/execution_state.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cw_core/sync_status.dart';
|
||||
@@ -62,7 +64,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
|
||||
final priority = _settingsStore.priority[wallet.type];
|
||||
final priorities = priorityForWalletType(wallet.type);
|
||||
|
||||
if (!priorityForWalletType(wallet.type).contains(priority)) {
|
||||
if (!priorityForWalletType(wallet.type).contains(priority) && priorities.isNotEmpty) {
|
||||
_settingsStore.priority[wallet.type] = priorities.first;
|
||||
}
|
||||
|
||||
@@ -99,15 +101,15 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
|
||||
|
||||
@computed
|
||||
String get pendingTransactionFiatAmount {
|
||||
if (pendingTransaction == null) {
|
||||
return '0.00';
|
||||
}
|
||||
|
||||
try {
|
||||
if (pendingTransaction != null) {
|
||||
final fiat = calculateFiatAmount(
|
||||
price: _fiatConversationStore.prices[selectedCryptoCurrency]!,
|
||||
cryptoAmount: pendingTransaction!.amountFormatted);
|
||||
return fiat;
|
||||
} else {
|
||||
return '0.00';
|
||||
}
|
||||
final fiat = calculateFiatAmount(
|
||||
price: _fiatConversationStore.prices[selectedCryptoCurrency]!,
|
||||
cryptoAmount: pendingTransaction!.amountFormatted);
|
||||
return fiat;
|
||||
} catch (_) {
|
||||
return '0.00';
|
||||
}
|
||||
@@ -191,6 +193,9 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
|
||||
bool get isElectrumWallet =>
|
||||
wallet.type == WalletType.bitcoin || wallet.type == WalletType.litecoin;
|
||||
|
||||
@computed
|
||||
bool get hasFees => wallet.type != WalletType.nano && wallet.type != WalletType.banano;
|
||||
|
||||
@observable
|
||||
CryptoCurrency selectedCryptoCurrency;
|
||||
|
||||
@@ -316,6 +321,10 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
|
||||
state = TransactionCommitting();
|
||||
await pendingTransaction!.commit();
|
||||
|
||||
if (walletType == WalletType.nano) {
|
||||
nano!.updateTransactions(wallet);
|
||||
}
|
||||
|
||||
if (pendingTransaction!.id.isNotEmpty) {
|
||||
_settingsStore.shouldSaveRecipientAddress
|
||||
? await transactionDescriptionBox.add(TransactionDescription(
|
||||
@@ -380,6 +389,10 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
|
||||
|
||||
return ethereum!.createEthereumTransactionCredentials(outputs,
|
||||
priority: priority, currency: selectedCryptoCurrency);
|
||||
case WalletType.nano:
|
||||
return nano!.createNanoTransactionCredentials(
|
||||
outputs,
|
||||
);
|
||||
default:
|
||||
throw Exception('Unexpected wallet type: ${wallet.type}');
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ abstract class OtherSettingsViewModelBase with Store {
|
||||
final priority = _settingsStore.priority[_wallet.type];
|
||||
final priorities = priorityForWalletType(_wallet.type);
|
||||
|
||||
if (!priorities.contains(priority)) {
|
||||
if (!priorities.contains(priority) && priorities.isNotEmpty) {
|
||||
_settingsStore.priority[_wallet.type] = priorities.first;
|
||||
}
|
||||
}
|
||||
@@ -50,6 +50,14 @@ abstract class OtherSettingsViewModelBase with Store {
|
||||
}
|
||||
|
||||
@computed
|
||||
bool get changeRepresentativeEnabled {
|
||||
if (_wallet.type == WalletType.nano || _wallet.type == WalletType.banano) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
BuyProviderType get buyProviderType { return _settingsStore.defaultBuyProvider; }
|
||||
|
||||
String getDisplayPriority(dynamic priority) {
|
||||
|
||||
@@ -47,6 +47,9 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
case WalletType.ethereum:
|
||||
_addEthereumListItems(tx, dateFormat);
|
||||
break;
|
||||
case WalletType.nano:
|
||||
_addNanoListItems(tx, dateFormat);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -116,6 +119,10 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
return 'https://explorer.havenprotocol.org/search?value=${txId}';
|
||||
case WalletType.ethereum:
|
||||
return 'https://etherscan.io/tx/${txId}';
|
||||
case WalletType.nano:
|
||||
return 'https://nanolooker.com/block/${txId}';
|
||||
case WalletType.banano:
|
||||
return 'https://bananolooker.com/block/${txId}';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
@@ -133,6 +140,10 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
return S.current.view_transaction_on + 'explorer.havenprotocol.org';
|
||||
case WalletType.ethereum:
|
||||
return S.current.view_transaction_on + 'etherscan.io';
|
||||
case WalletType.nano:
|
||||
return S.current.view_transaction_on + 'nanolooker.com';
|
||||
case WalletType.banano:
|
||||
return S.current.view_transaction_on + 'bananolooker.com';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
@@ -221,4 +232,18 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
|
||||
items.addAll(_items);
|
||||
}
|
||||
|
||||
|
||||
void _addNanoListItems(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 > 0).toString()),
|
||||
StandartListItem(title: S.current.transaction_details_height, value: '${tx.height}'),
|
||||
StandartListItem(title: S.current.transaction_details_amount, value: tx.amountFormatted()),
|
||||
];
|
||||
|
||||
items.addAll(_items);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,6 +107,22 @@ class EthereumURI extends PaymentURI {
|
||||
}
|
||||
}
|
||||
|
||||
class NanoURI extends PaymentURI {
|
||||
NanoURI({required String amount, required String address})
|
||||
: super(amount: amount, address: address);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
var base = 'nano:' + address;
|
||||
|
||||
if (amount.isNotEmpty) {
|
||||
base += '?amount=${amount.replaceAll(',', '.')}';
|
||||
}
|
||||
|
||||
return base;
|
||||
}
|
||||
}
|
||||
|
||||
abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewModel with Store {
|
||||
WalletAddressListViewModelBase({
|
||||
required AppStore appStore,
|
||||
@@ -176,6 +192,10 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
|
||||
return EthereumURI(amount: amount, address: address.address);
|
||||
}
|
||||
|
||||
if (wallet.type == WalletType.nano) {
|
||||
return NanoURI(amount: amount, address: address.address);
|
||||
}
|
||||
|
||||
throw Exception('Unexpected type: ${type.toString()}');
|
||||
}
|
||||
|
||||
@@ -252,7 +272,11 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
|
||||
}
|
||||
|
||||
@computed
|
||||
bool get hasAddressList => wallet.type == WalletType.monero || wallet.type == WalletType.haven;
|
||||
bool get hasAddressList =>
|
||||
wallet.type == WalletType.monero ||
|
||||
wallet.type == WalletType.haven;/* ||
|
||||
wallet.type == WalletType.nano ||
|
||||
wallet.type == WalletType.banano;*/// TODO: nano accounts are disabled for now
|
||||
|
||||
@computed
|
||||
bool get showElectrumAddressDisclaimer =>
|
||||
@@ -269,11 +293,16 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
|
||||
void _init() {
|
||||
_baseItems = [];
|
||||
|
||||
if (wallet.type == WalletType.monero || wallet.type == WalletType.haven) {
|
||||
if (wallet.type == WalletType.monero ||
|
||||
wallet.type == WalletType.haven /*||
|
||||
wallet.type == WalletType.nano ||
|
||||
wallet.type == WalletType.banano*/) {
|
||||
_baseItems.add(WalletAccountListHeader());
|
||||
}
|
||||
|
||||
_baseItems.add(WalletAddressListHeader());
|
||||
if (wallet.type != WalletType.nano && wallet.type != WalletType.banano) {
|
||||
_baseItems.add(WalletAddressListHeader());
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
|
||||
@@ -35,18 +35,16 @@ abstract class WalletCreationVMBase with Store {
|
||||
final Box<WalletInfo> _walletInfoSource;
|
||||
final AppStore _appStore;
|
||||
|
||||
bool nameExists(String name)
|
||||
=> walletCreationService.exists(name);
|
||||
bool nameExists(String name) => walletCreationService.exists(name);
|
||||
|
||||
bool typeExists(WalletType type)
|
||||
=> walletCreationService.typeExists(type);
|
||||
bool typeExists(WalletType type) => walletCreationService.typeExists(type);
|
||||
|
||||
Future<void> create({dynamic options, RestoredWallet? restoreWallet}) async {
|
||||
final type = restoreWallet?.type ?? this.type;
|
||||
try {
|
||||
state = IsExecutingState();
|
||||
if (name.isEmpty) {
|
||||
name = await generateName();
|
||||
name = await generateName();
|
||||
}
|
||||
|
||||
walletCreationService.checkIfExists(name);
|
||||
@@ -55,17 +53,21 @@ abstract class WalletCreationVMBase with Store {
|
||||
final credentials = restoreWallet != null
|
||||
? getCredentialsFromRestoredWallet(options, restoreWallet)
|
||||
: getCredentials(options);
|
||||
|
||||
final walletInfo = WalletInfo.external(
|
||||
id: WalletBase.idFor(name, type),
|
||||
name: name,
|
||||
type: type,
|
||||
isRecovery: isRecovery,
|
||||
restoreHeight: credentials.height ?? 0,
|
||||
date: DateTime.now(),
|
||||
path: path,
|
||||
dirPath: dirPath,
|
||||
address: '',
|
||||
showIntroCakePayCard: (!walletCreationService.typeExists(type)) && type != WalletType.haven);
|
||||
id: WalletBase.idFor(name, type),
|
||||
name: name,
|
||||
type: type,
|
||||
isRecovery: isRecovery,
|
||||
restoreHeight: credentials.height ?? 0,
|
||||
date: DateTime.now(),
|
||||
path: path,
|
||||
dirPath: dirPath,
|
||||
address: '',
|
||||
showIntroCakePayCard: (!walletCreationService.typeExists(type)) && type != WalletType.haven,
|
||||
derivationPath: credentials.derivationPath,
|
||||
derivationType: credentials.derivationType,
|
||||
);
|
||||
credentials.walletInfo = walletInfo;
|
||||
final wallet = restoreWallet != null
|
||||
? await processFromRestoredWallet(credentials, restoreWallet)
|
||||
@@ -80,15 +82,16 @@ abstract class WalletCreationVMBase with Store {
|
||||
state = FailureState(e.toString());
|
||||
}
|
||||
}
|
||||
WalletCredentials getCredentials(dynamic options) =>
|
||||
|
||||
WalletCredentials getCredentials(dynamic options) => throw UnimplementedError();
|
||||
|
||||
Future<WalletBase> process(WalletCredentials credentials) => throw UnimplementedError();
|
||||
|
||||
WalletCredentials getCredentialsFromRestoredWallet(
|
||||
dynamic options, RestoredWallet restoreWallet) =>
|
||||
throw UnimplementedError();
|
||||
|
||||
Future<WalletBase> process(WalletCredentials credentials) =>
|
||||
throw UnimplementedError();
|
||||
|
||||
WalletCredentials getCredentialsFromRestoredWallet(dynamic options, RestoredWallet restoreWallet) =>
|
||||
throw UnimplementedError();
|
||||
|
||||
Future<WalletBase> processFromRestoredWallet(WalletCredentials credentials, RestoredWallet restoreWallet) =>
|
||||
Future<WalletBase> processFromRestoredWallet(
|
||||
WalletCredentials credentials, RestoredWallet restoreWallet) =>
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:cake_wallet/nano/nano.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
import 'package:cw_core/transaction_direction.dart';
|
||||
import 'package:cw_core/transaction_info.dart';
|
||||
@@ -104,6 +105,22 @@ abstract class WalletKeysViewModelBase with Store {
|
||||
StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
|
||||
]);
|
||||
}
|
||||
|
||||
if (_appStore.wallet!.type == WalletType.nano || _appStore.wallet!.type == WalletType.banano) {
|
||||
|
||||
// we don't necessarily have the seed phrase for nano / banano:
|
||||
if (_appStore.wallet!.seed != null) {
|
||||
items.addAll([
|
||||
StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
|
||||
]);
|
||||
}
|
||||
|
||||
// we always have the hex version of the seed:
|
||||
items.addAll([
|
||||
if (_appStore.wallet!.privateKey != null)
|
||||
StandartListItem(title: S.current.spend_key_private, value: _appStore.wallet!.privateKey!),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
Future<int?> _currentHeight() async {
|
||||
@@ -128,6 +145,10 @@ abstract class WalletKeysViewModelBase with Store {
|
||||
return 'haven-wallet';
|
||||
case WalletType.ethereum:
|
||||
return 'ethereum-wallet';
|
||||
case WalletType.nano:
|
||||
return 'nano-wallet';
|
||||
case WalletType.banano:
|
||||
return 'banano-wallet';
|
||||
default:
|
||||
throw Exception('Unexpected wallet type: ${_appStore.wallet!.toString()}');
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/nano/nano.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cake_wallet/core/wallet_creation_service.dart';
|
||||
@@ -45,6 +46,8 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
|
||||
name: name, language: options as String);
|
||||
case WalletType.ethereum:
|
||||
return ethereum!.createEthereumNewWalletCredentials(name: name);
|
||||
case WalletType.nano:
|
||||
return nano!.createNanoNewWalletCredentials(name: name);
|
||||
default:
|
||||
throw Exception('Unexpected type: ${type.toString()}');;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cake_wallet/view_model/restore/restore_mode.dart';
|
||||
|
||||
part 'wallet_restore_choose_derivation_view_model.g.dart';
|
||||
|
||||
class WalletRestoreChooseDerivationViewModel = WalletRestoreChooseDerivationViewModelBase
|
||||
with _$WalletRestoreChooseDerivationViewModel;
|
||||
|
||||
abstract class WalletRestoreChooseDerivationViewModelBase with Store {
|
||||
WalletRestoreChooseDerivationViewModelBase({required this.derivationInfos})
|
||||
: mode = WalletRestoreMode.seed {}
|
||||
|
||||
@observable
|
||||
List<DerivationInfo> derivationInfos;
|
||||
|
||||
Future<List<DerivationInfo>> get derivations async {
|
||||
return derivationInfos;
|
||||
}
|
||||
|
||||
@observable
|
||||
WalletRestoreMode mode;
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/nano/nano.dart';
|
||||
import 'package:cake_wallet/ethereum/ethereum.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
@@ -16,25 +18,34 @@ import 'package:cake_wallet/view_model/restore/restore_mode.dart';
|
||||
|
||||
part 'wallet_restore_view_model.g.dart';
|
||||
|
||||
class WalletRestoreViewModel = WalletRestoreViewModelBase
|
||||
with _$WalletRestoreViewModel;
|
||||
class WalletRestoreViewModel = WalletRestoreViewModelBase with _$WalletRestoreViewModel;
|
||||
|
||||
abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||
WalletRestoreViewModelBase(AppStore appStore, WalletCreationService walletCreationService,
|
||||
Box<WalletInfo> walletInfoSource,
|
||||
{required WalletType type})
|
||||
: availableModes =
|
||||
(type == WalletType.monero || type == WalletType.haven || type == WalletType.ethereum)
|
||||
? WalletRestoreMode.values
|
||||
: [WalletRestoreMode.seed],
|
||||
hasSeedLanguageSelector = type == WalletType.monero || type == WalletType.haven,
|
||||
: hasSeedLanguageSelector = type == WalletType.monero || type == WalletType.haven,
|
||||
hasBlockchainHeightLanguageSelector = type == WalletType.monero || type == WalletType.haven,
|
||||
hasRestoreFromPrivateKey = type == WalletType.ethereum,
|
||||
hasRestoreFromPrivateKey =
|
||||
type == WalletType.ethereum || type == WalletType.nano || type == WalletType.banano,
|
||||
isButtonEnabled = false,
|
||||
mode = WalletRestoreMode.seed,
|
||||
super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true) {
|
||||
isButtonEnabled =
|
||||
!hasSeedLanguageSelector && !hasBlockchainHeightLanguageSelector;
|
||||
switch (type) {
|
||||
case WalletType.monero:
|
||||
case WalletType.haven:
|
||||
case WalletType.ethereum:
|
||||
availableModes = WalletRestoreMode.values;
|
||||
break;
|
||||
case WalletType.nano:
|
||||
case WalletType.banano:
|
||||
availableModes = [WalletRestoreMode.seed, WalletRestoreMode.keys];
|
||||
break;
|
||||
default:
|
||||
availableModes = [WalletRestoreMode.seed];
|
||||
break;
|
||||
}
|
||||
isButtonEnabled = !hasSeedLanguageSelector && !hasBlockchainHeightLanguageSelector;
|
||||
walletCreationService.changeWalletType(type: type);
|
||||
}
|
||||
|
||||
@@ -42,7 +53,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||
static const electrumSeedMnemonicLength = 24;
|
||||
static const electrumShortSeedMnemonicLength = 12;
|
||||
|
||||
final List<WalletRestoreMode> availableModes;
|
||||
late List<WalletRestoreMode> availableModes;
|
||||
final bool hasSeedLanguageSelector;
|
||||
final bool hasBlockchainHeightLanguageSelector;
|
||||
final bool hasRestoreFromPrivateKey;
|
||||
@@ -58,38 +69,37 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||
final password = generateWalletPassword();
|
||||
final height = options['height'] as int? ?? 0;
|
||||
name = options['name'] as String;
|
||||
DerivationType? derivationType = options["derivationType"] as DerivationType?;
|
||||
String? derivationPath = options["derivationPath"] as String?;
|
||||
|
||||
if (mode == WalletRestoreMode.seed) {
|
||||
final seed = options['seed'] as String;
|
||||
|
||||
switch (type) {
|
||||
case WalletType.monero:
|
||||
return monero!.createMoneroRestoreWalletFromSeedCredentials(
|
||||
name: name,
|
||||
height: height,
|
||||
mnemonic: seed,
|
||||
password: password);
|
||||
name: name, height: height, mnemonic: seed, password: password);
|
||||
case WalletType.bitcoin:
|
||||
return bitcoin!.createBitcoinRestoreWalletFromSeedCredentials(
|
||||
name: name,
|
||||
mnemonic: seed,
|
||||
password: password);
|
||||
password: password,
|
||||
);
|
||||
case WalletType.litecoin:
|
||||
return bitcoin!.createBitcoinRestoreWalletFromSeedCredentials(
|
||||
name: name,
|
||||
mnemonic: seed,
|
||||
password: password);
|
||||
name: name, mnemonic: seed, password: password);
|
||||
case WalletType.haven:
|
||||
return haven!.createHavenRestoreWalletFromSeedCredentials(
|
||||
name: name,
|
||||
height: height,
|
||||
mnemonic: seed,
|
||||
password: password);
|
||||
name: name, height: height, mnemonic: seed, password: password);
|
||||
case WalletType.ethereum:
|
||||
return ethereum!.createEthereumRestoreWalletFromSeedCredentials(
|
||||
name: name,
|
||||
mnemonic: seed,
|
||||
password: password);
|
||||
name: name, mnemonic: seed, password: password);
|
||||
case WalletType.nano:
|
||||
return nano!.createNanoRestoreWalletFromSeedCredentials(
|
||||
name: name,
|
||||
mnemonic: seed,
|
||||
password: password,
|
||||
derivationType: derivationType,
|
||||
);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -100,40 +110,73 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||
final spendKey = options['spendKey'] as String?;
|
||||
final address = options['address'] as String?;
|
||||
|
||||
if (type == WalletType.monero) {
|
||||
return monero!.createMoneroRestoreWalletFromKeysCredentials(
|
||||
switch (type) {
|
||||
case WalletType.monero:
|
||||
return monero!.createMoneroRestoreWalletFromKeysCredentials(
|
||||
name: name,
|
||||
height: height,
|
||||
spendKey: spendKey!,
|
||||
viewKey: viewKey!,
|
||||
address: address!,
|
||||
password: password,
|
||||
language: 'English');
|
||||
}
|
||||
language: 'English',
|
||||
);
|
||||
|
||||
if (type == WalletType.haven) {
|
||||
return haven!.createHavenRestoreWalletFromKeysCredentials(
|
||||
case WalletType.haven:
|
||||
return haven!.createHavenRestoreWalletFromKeysCredentials(
|
||||
name: name,
|
||||
height: height,
|
||||
spendKey: spendKey!,
|
||||
viewKey: viewKey!,
|
||||
address: address!,
|
||||
password: password,
|
||||
language: 'English');
|
||||
}
|
||||
language: 'English',
|
||||
);
|
||||
|
||||
if (type == WalletType.ethereum) {
|
||||
return ethereum!.createEthereumRestoreWalletFromPrivateKey(
|
||||
name: name,
|
||||
privateKey: options['private_key'] as String,
|
||||
password: password,
|
||||
);
|
||||
case WalletType.ethereum:
|
||||
return ethereum!.createEthereumRestoreWalletFromPrivateKey(
|
||||
name: name,
|
||||
privateKey: options['private_key'] as String,
|
||||
password: password,
|
||||
);
|
||||
|
||||
case WalletType.nano:
|
||||
return nano!.createNanoRestoreWalletFromKeysCredentials(
|
||||
name: name,
|
||||
password: password,
|
||||
seedKey: options['private_key'] as String,
|
||||
derivationType: options["derivationType"] as DerivationType,
|
||||
);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
throw Exception('Unexpected type: ${type.toString()}');
|
||||
}
|
||||
|
||||
Future<List<DerivationType>> getDerivationTypes(dynamic options) async {
|
||||
final seedKey = options['private_key'] as String?;
|
||||
final mnemonic = options['seed'] as String?;
|
||||
WalletType walletType = options['walletType'] as WalletType;
|
||||
var appStore = getIt.get<AppStore>();
|
||||
var node = appStore.settingsStore.getCurrentNode(walletType);
|
||||
|
||||
switch (type) {
|
||||
case WalletType.nano:
|
||||
return nanoUtil!.compareDerivationMethods(
|
||||
mnemonic: mnemonic,
|
||||
privateKey: seedKey,
|
||||
node: node,
|
||||
);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// throw Exception('Unexpected type: ${type.toString()}');
|
||||
return [DerivationType.def];
|
||||
}
|
||||
|
||||
@override
|
||||
Future<WalletBase> process(WalletCredentials credentials) async {
|
||||
if (mode == WalletRestoreMode.keys) {
|
||||
|
||||
Reference in New Issue
Block a user