diff --git a/lib/di.dart b/lib/di.dart index 9136260e5..1462370fc 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -678,7 +678,7 @@ Future setup({ getIt.registerFactory(() { final wallet = getIt.get().wallet!; - if (wallet.type == WalletType.monero || wallet.type == WalletType.haven) { + if (wallet.type == WalletType.monero || wallet.type == WalletType.wownero || wallet.type == WalletType.haven) { return MoneroAccountListViewModel(wallet); } throw Exception( @@ -709,6 +709,7 @@ Future setup({ getIt.registerFactoryParam( (AccountListItem? account, _) => MoneroAccountEditOrCreateViewModel( monero!.getAccountList(getIt.get().wallet!), + wownero?.getAccountList(getIt.get().wallet!), haven?.getAccountList(getIt.get().wallet!), wallet: getIt.get().wallet!, accountListItem: account)); diff --git a/lib/src/screens/receive/receive_page.dart b/lib/src/screens/receive/receive_page.dart index 789fb42bf..03524ef79 100644 --- a/lib/src/screens/receive/receive_page.dart +++ b/lib/src/screens/receive/receive_page.dart @@ -139,6 +139,7 @@ class ReceivePage extends BasePage { walletAddressListViewModel: addressListViewModel, trailingButtonTap: () async { if (addressListViewModel.type == WalletType.monero || + addressListViewModel.type == WalletType.wownero || addressListViewModel.type == WalletType.haven) { await showPopUp( context: context, diff --git a/lib/view_model/dashboard/balance_view_model.dart b/lib/view_model/dashboard/balance_view_model.dart index 8deb3b27c..045b55261 100644 --- a/lib/view_model/dashboard/balance_view_model.dart +++ b/lib/view_model/dashboard/balance_view_model.dart @@ -88,7 +88,7 @@ abstract class BalanceViewModelBase with Store { wallet.type == WalletType.tron; @computed - bool get hasAccounts => wallet.type == WalletType.monero; + bool get hasAccounts => wallet.type == WalletType.monero || wallet.type == WalletType.wownero; @computed SortBalanceBy get sortBalanceBy => settingsStore.sortBalanceBy; diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart index cc9cf1b7a..5b5353e06 100644 --- a/lib/view_model/dashboard/dashboard_view_model.dart +++ b/lib/view_model/dashboard/dashboard_view_model.dart @@ -31,6 +31,7 @@ import 'package:cake_wallet/view_model/dashboard/trade_list_item.dart'; import 'package:cake_wallet/view_model/dashboard/transaction_list_item.dart'; import 'package:cake_wallet/view_model/settings/sync_mode.dart'; import 'package:cake_wallet/wallet_type_utils.dart'; +import 'package:cake_wallet/wownero/wownero.dart' as wow; import 'package:cryptography/cryptography.dart'; import 'package:cw_core/balance.dart'; import 'package:cw_core/cake_hive.dart'; @@ -163,6 +164,29 @@ abstract class DashboardViewModelBase with Store { final sortedTransactions = [..._accountTransactions]; sortedTransactions.sort((a, b) => a.date.compareTo(b.date)); + transactions = ObservableList.of(sortedTransactions.map((transaction) => TransactionListItem( + transaction: transaction, + balanceViewModel: balanceViewModel, + settingsStore: appStore.settingsStore))); + } else if (_wallet.type == WalletType.wownero) { + subname = wow.wownero!.getCurrentAccount(_wallet).label; + + _onMoneroAccountChangeReaction = reaction( + (_) => wow.wownero!.getWowneroWalletDetails(wallet).account, + (wow.Account account) => _onMoneroAccountChange(_wallet)); + + _onMoneroBalanceChangeReaction = reaction( + (_) => wow.wownero!.getWowneroWalletDetails(wallet).balance, + (wow.WowneroBalance balance) => _onMoneroTransactionsUpdate(_wallet)); + + final _accountTransactions = _wallet.transactionHistory.transactions.values + .where((tx) => + wow.wownero!.getTransactionInfoAccountId(tx) == wow.wownero!.getCurrentAccount(wallet).id) + .toList(); + + final sortedTransactions = [..._accountTransactions]; + sortedTransactions.sort((a, b) => a.date.compareTo(b.date)); + transactions = ObservableList.of(sortedTransactions.map((transaction) => TransactionListItem( transaction: transaction, balanceViewModel: balanceViewModel, @@ -200,6 +224,10 @@ abstract class DashboardViewModelBase with Store { return monero!.getTransactionInfoAccountId(transaction) == monero!.getCurrentAccount(wallet).id; } + if (wallet.type == WalletType.wownero) { + return wow.wownero!.getTransactionInfoAccountId(transaction) == + wow.wownero!.getCurrentAccount(wallet).id; + } return true; }); @@ -459,6 +487,21 @@ abstract class DashboardViewModelBase with Store { (_) => monero!.getMoneroWalletDetails(wallet).balance, (MoneroBalance balance) => _onMoneroTransactionsUpdate(wallet)); + _onMoneroTransactionsUpdate(wallet); + } else if (wallet.type == WalletType.wownero) { + subname = wow.wownero!.getCurrentAccount(wallet).label; + + _onMoneroAccountChangeReaction?.reaction.dispose(); + _onMoneroBalanceChangeReaction?.reaction.dispose(); + + _onMoneroAccountChangeReaction = reaction( + (_) => wow.wownero!.getWowneroWalletDetails(wallet).account, + (wow.Account account) => _onMoneroAccountChange(wallet)); + + _onMoneroBalanceChangeReaction = reaction( + (_) => wow.wownero!.getWowneroWalletDetails(wallet).balance, + (wow.WowneroBalance balance) => _onMoneroTransactionsUpdate(wallet)); + _onMoneroTransactionsUpdate(wallet); } else { // FIX-ME: Check for side effects @@ -489,32 +532,54 @@ abstract class DashboardViewModelBase with Store { return monero!.getTransactionInfoAccountId(tx) == monero!.getCurrentAccount(wallet).id; } + if (wallet.type == WalletType.wownero) { + return wow.wownero!.getTransactionInfoAccountId(tx) == wow.wownero!.getCurrentAccount(wallet).id; + } + return true; }); } @action void _onMoneroAccountChange(WalletBase wallet) { - subname = monero!.getCurrentAccount(wallet).label; + if (wallet.type == WalletType.monero) { + subname = monero!.getCurrentAccount(wallet).label; + } else if (wallet.type == WalletType.wownero) { + subname = wow.wownero!.getCurrentAccount(wallet).label; + } _onMoneroTransactionsUpdate(wallet); } @action void _onMoneroTransactionsUpdate(WalletBase wallet) { transactions.clear(); + if (wallet.type == WalletType.monero) { + final _accountTransactions = monero! + .getTransactionHistory(wallet) + .transactions + .values + .where( + (tx) => monero!.getTransactionInfoAccountId(tx) == monero!.getCurrentAccount(wallet).id) + .toList(); - final _accountTransactions = monero! - .getTransactionHistory(wallet) - .transactions - .values - .where( - (tx) => monero!.getTransactionInfoAccountId(tx) == monero!.getCurrentAccount(wallet).id) - .toList(); + transactions.addAll(_accountTransactions.map((transaction) => TransactionListItem( + transaction: transaction, + balanceViewModel: balanceViewModel, + settingsStore: appStore.settingsStore))); + } else if (wallet.type == WalletType.wownero) { + final _accountTransactions = wow.wownero! + .getTransactionHistory(wallet) + .transactions + .values + .where( + (tx) => wow.wownero!.getTransactionInfoAccountId(tx) == wow.wownero!.getCurrentAccount(wallet).id) + .toList(); - transactions.addAll(_accountTransactions.map((transaction) => TransactionListItem( - transaction: transaction, - balanceViewModel: balanceViewModel, - settingsStore: appStore.settingsStore))); + transactions.addAll(_accountTransactions.map((transaction) => TransactionListItem( + transaction: transaction, + balanceViewModel: balanceViewModel, + settingsStore: appStore.settingsStore))); + } } void updateActions() { diff --git a/lib/view_model/monero_account_list/monero_account_edit_or_create_view_model.dart b/lib/view_model/monero_account_list/monero_account_edit_or_create_view_model.dart index 2f707c9ec..8d626e258 100644 --- a/lib/view_model/monero_account_list/monero_account_edit_or_create_view_model.dart +++ b/lib/view_model/monero_account_list/monero_account_edit_or_create_view_model.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/wownero/wownero.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_type.dart'; import 'package:flutter/foundation.dart'; @@ -13,7 +14,7 @@ class MoneroAccountEditOrCreateViewModel = MoneroAccountEditOrCreateViewModelBas with _$MoneroAccountEditOrCreateViewModel; abstract class MoneroAccountEditOrCreateViewModelBase with Store { - MoneroAccountEditOrCreateViewModelBase(this._moneroAccountList, this._havenAccountList, + MoneroAccountEditOrCreateViewModelBase(this._moneroAccountList, this._wowneroAccountList, this._havenAccountList, {required WalletBase wallet, AccountListItem? accountListItem}) : state = InitialExecutionState(), isEdit = accountListItem != null, @@ -30,6 +31,7 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store { String label; final MoneroAccountList _moneroAccountList; + final WowneroAccountList? _wowneroAccountList; final HavenAccountList? _havenAccountList; final AccountListItem? _accountListItem; final WalletBase _wallet; @@ -42,6 +44,10 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store { if (_wallet.type == WalletType.haven) { await saveHaven(); } + + if (_wallet.type == WalletType.wownero) { + await saveWownero(); + } } Future saveMonero() async { @@ -91,4 +97,27 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store { state = FailureState(e.toString()); } } + + Future saveWownero() async { + try { + state = IsExecutingState(); + + if (_accountListItem != null) { + await _wowneroAccountList?.setLabelAccount( + _wallet, + accountIndex: _accountListItem!.id, + label: label); + } else { + await _wowneroAccountList?.addAccount( + _wallet, + label: label); + } + + await _wallet.save(); + state = ExecutedSuccessfullyState(); + } catch (e) { + state = FailureState(e.toString()); + } + } + } diff --git a/lib/view_model/monero_account_list/monero_account_list_view_model.dart b/lib/view_model/monero_account_list/monero_account_list_view_model.dart index 4cbf95bab..448106779 100644 --- a/lib/view_model/monero_account_list/monero_account_list_view_model.dart +++ b/lib/view_model/monero_account_list/monero_account_list_view_model.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/wownero/wownero.dart'; import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/wallet_type.dart'; import 'package:mobx/mobx.dart'; @@ -47,6 +48,17 @@ abstract class MoneroAccountListViewModelBase with Store { .toList(); } + if (_wallet.type == WalletType.wownero) { + return wownero + !.getAccountList(_wallet) + .accounts.map((acc) => AccountListItem( + label: acc.label, + id: acc.id, + balance: acc.balance, + isSelected: acc.id == wownero!.getCurrentAccount(_wallet).id)) + .toList(); + } + throw Exception('Unexpected wallet type: ${_wallet.type}'); } @@ -62,6 +74,15 @@ abstract class MoneroAccountListViewModelBase with Store { ); } + if (_wallet.type == WalletType.wownero) { + wownero!.setCurrentAccount( + _wallet, + item.id, + item.label, + item.balance, + ); + } + if (_wallet.type == WalletType.haven) { haven!.setCurrentAccount( _wallet, diff --git a/lib/view_model/node_list/node_create_or_edit_view_model.dart b/lib/view_model/node_list/node_create_or_edit_view_model.dart index 850e248f2..86ceb654c 100644 --- a/lib/view_model/node_list/node_create_or_edit_view_model.dart +++ b/lib/view_model/node_list/node_create_or_edit_view_model.dart @@ -65,7 +65,7 @@ abstract class NodeCreateOrEditViewModelBase with Store { bool get isReady => address.isNotEmpty && port.isNotEmpty; bool get hasAuthCredentials => - _walletType == WalletType.monero || _walletType == WalletType.haven; + _walletType == WalletType.monero || _walletType == WalletType.wownero || _walletType == WalletType.haven; bool get hasTestnetSupport => _walletType == WalletType.bitcoin; diff --git a/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart b/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart index 0b4f969cb..2edda3d29 100644 --- a/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart +++ b/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart @@ -1,4 +1,5 @@ import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_item.dart'; +import 'package:cake_wallet/wownero/wownero.dart'; import 'package:mobx/mobx.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:cake_wallet/bitcoin/bitcoin.dart'; @@ -80,6 +81,16 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store { await wallet.save(); } + if (wallet.type == WalletType.wownero) { + await wownero + !.getSubaddressList(wallet) + .addSubaddress( + wallet, + accountIndex: wownero!.getCurrentAccount(wallet).id, + label: label); + await wallet.save(); + } + if (wallet.type == WalletType.haven) { await haven !.getSubaddressList(wallet) @@ -103,6 +114,11 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store { accountIndex: monero!.getCurrentAccount(wallet).id, addressIndex: index, label: label); await wallet.save(); } + if (wallet.type == WalletType.wownero) { + await wownero!.getSubaddressList(wallet).setLabelSubaddress(wallet, + accountIndex: wownero!.getCurrentAccount(wallet).id, addressIndex: index, label: label); + await wallet.save(); + } if (wallet.type == WalletType.haven) { await haven!.getSubaddressList(wallet).setLabelSubaddress(wallet, accountIndex: haven!.getCurrentAccount(wallet).id, diff --git a/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart b/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart index dd7f02407..6c274bb7b 100644 --- a/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart +++ b/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart @@ -217,7 +217,7 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo selectedCurrency = walletTypeToCryptoCurrency(appStore.wallet!.type), _cryptoNumberFormat = NumberFormat(_cryptoNumberPattern), hasAccounts = - appStore.wallet!.type == WalletType.monero || appStore.wallet!.type == WalletType.haven, + appStore.wallet!.type == WalletType.monero || appStore.wallet!.type == WalletType.wownero || appStore.wallet!.type == WalletType.haven, amount = '', _settingsStore = appStore.settingsStore, super(appStore: appStore) { @@ -229,7 +229,7 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo _init(); selectedCurrency = walletTypeToCryptoCurrency(wallet.type); - hasAccounts = wallet.type == WalletType.monero || wallet.type == WalletType.haven; + hasAccounts = wallet.type == WalletType.monero || wallet.type == WalletType.wownero || wallet.type == WalletType.haven; } static const String _cryptoNumberPattern = '0.00000000'; @@ -340,6 +340,20 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo addressList.addAll(addressItems); } + if (wallet.type == WalletType.wownero) { + final primaryAddress = wownero!.getSubaddressList(wallet).subaddresses.first; + final addressItems = wownero!.getSubaddressList(wallet).subaddresses.map((subaddress) { + final isPrimary = subaddress == primaryAddress; + + return WalletAddressListItem( + id: subaddress.id, + isPrimary: isPrimary, + name: subaddress.label, + address: subaddress.address); + }); + addressList.addAll(addressItems); + } + if (wallet.type == WalletType.haven) { final primaryAddress = haven!.getSubaddressList(wallet).subaddresses.first; final addressItems = haven!.getSubaddressList(wallet).subaddresses.map((subaddress) { @@ -430,20 +444,6 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo addressList.add(WalletAddressListItem(isPrimary: true, name: null, address: primaryAddress)); } - if (wallet.type == WalletType.wownero) { - final primaryAddress = wownero!.getSubaddressList(wallet).subaddresses.first; - final addressItems = wownero!.getSubaddressList(wallet).subaddresses.map((subaddress) { - final isPrimary = subaddress == primaryAddress; - - return WalletAddressListItem( - id: subaddress.id, - isPrimary: isPrimary, - name: subaddress.label, - address: subaddress.address); - }); - addressList.addAll(addressItems); - } - if (searchText.isNotEmpty) { return ObservableList.of(addressList.where((item) { if (item is WalletAddressListItem) { @@ -465,6 +465,10 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo return monero!.getCurrentAccount(wallet).label; } + if (wallet.type == WalletType.wownero) { + return wownero!.getCurrentAccount(wallet).label; + } + if (wallet.type == WalletType.haven) { return haven!.getCurrentAccount(wallet).label; } @@ -475,6 +479,7 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo @computed bool get hasAddressList => wallet.type == WalletType.monero || + wallet.type == WalletType.wownero || wallet.type == WalletType.haven || wallet.type == WalletType.bitcoinCash || wallet.type == WalletType.bitcoin || @@ -513,7 +518,7 @@ 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.wownero || wallet.type == WalletType.haven) { _baseItems.add(WalletAccountListHeader()); }