CW-681 Add address and account list to Wownero (#1538)
Some checks failed
Cache Dependencies / test (push) Has been cancelled

This commit is contained in:
cyan 2024-07-21 02:58:17 +02:00 committed by GitHub
parent 311fff2c44
commit 649305acc3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 171 additions and 33 deletions

View file

@ -678,7 +678,7 @@ Future<void> setup({
getIt.registerFactory<MoneroAccountListViewModel>(() { getIt.registerFactory<MoneroAccountListViewModel>(() {
final wallet = getIt.get<AppStore>().wallet!; final wallet = getIt.get<AppStore>().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); return MoneroAccountListViewModel(wallet);
} }
throw Exception( throw Exception(
@ -709,6 +709,7 @@ Future<void> setup({
getIt.registerFactoryParam<MoneroAccountEditOrCreateViewModel, AccountListItem?, void>( getIt.registerFactoryParam<MoneroAccountEditOrCreateViewModel, AccountListItem?, void>(
(AccountListItem? account, _) => MoneroAccountEditOrCreateViewModel( (AccountListItem? account, _) => MoneroAccountEditOrCreateViewModel(
monero!.getAccountList(getIt.get<AppStore>().wallet!), monero!.getAccountList(getIt.get<AppStore>().wallet!),
wownero?.getAccountList(getIt.get<AppStore>().wallet!),
haven?.getAccountList(getIt.get<AppStore>().wallet!), haven?.getAccountList(getIt.get<AppStore>().wallet!),
wallet: getIt.get<AppStore>().wallet!, wallet: getIt.get<AppStore>().wallet!,
accountListItem: account)); accountListItem: account));

View file

@ -139,6 +139,7 @@ class ReceivePage extends BasePage {
walletAddressListViewModel: addressListViewModel, walletAddressListViewModel: addressListViewModel,
trailingButtonTap: () async { trailingButtonTap: () async {
if (addressListViewModel.type == WalletType.monero || if (addressListViewModel.type == WalletType.monero ||
addressListViewModel.type == WalletType.wownero ||
addressListViewModel.type == WalletType.haven) { addressListViewModel.type == WalletType.haven) {
await showPopUp<void>( await showPopUp<void>(
context: context, context: context,

View file

@ -88,7 +88,7 @@ abstract class BalanceViewModelBase with Store {
wallet.type == WalletType.tron; wallet.type == WalletType.tron;
@computed @computed
bool get hasAccounts => wallet.type == WalletType.monero; bool get hasAccounts => wallet.type == WalletType.monero || wallet.type == WalletType.wownero;
@computed @computed
SortBalanceBy get sortBalanceBy => settingsStore.sortBalanceBy; SortBalanceBy get sortBalanceBy => settingsStore.sortBalanceBy;

View file

@ -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/dashboard/transaction_list_item.dart';
import 'package:cake_wallet/view_model/settings/sync_mode.dart'; import 'package:cake_wallet/view_model/settings/sync_mode.dart';
import 'package:cake_wallet/wallet_type_utils.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:cryptography/cryptography.dart';
import 'package:cw_core/balance.dart'; import 'package:cw_core/balance.dart';
import 'package:cw_core/cake_hive.dart'; import 'package:cw_core/cake_hive.dart';
@ -163,6 +164,29 @@ abstract class DashboardViewModelBase with Store {
final sortedTransactions = [..._accountTransactions]; final sortedTransactions = [..._accountTransactions];
sortedTransactions.sort((a, b) => a.date.compareTo(b.date)); 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( transactions = ObservableList.of(sortedTransactions.map((transaction) => TransactionListItem(
transaction: transaction, transaction: transaction,
balanceViewModel: balanceViewModel, balanceViewModel: balanceViewModel,
@ -200,6 +224,10 @@ abstract class DashboardViewModelBase with Store {
return monero!.getTransactionInfoAccountId(transaction) == return monero!.getTransactionInfoAccountId(transaction) ==
monero!.getCurrentAccount(wallet).id; monero!.getCurrentAccount(wallet).id;
} }
if (wallet.type == WalletType.wownero) {
return wow.wownero!.getTransactionInfoAccountId(transaction) ==
wow.wownero!.getCurrentAccount(wallet).id;
}
return true; return true;
}); });
@ -459,6 +487,21 @@ abstract class DashboardViewModelBase with Store {
(_) => monero!.getMoneroWalletDetails(wallet).balance, (_) => monero!.getMoneroWalletDetails(wallet).balance,
(MoneroBalance balance) => _onMoneroTransactionsUpdate(wallet)); (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); _onMoneroTransactionsUpdate(wallet);
} else { } else {
// FIX-ME: Check for side effects // FIX-ME: Check for side effects
@ -489,20 +532,28 @@ abstract class DashboardViewModelBase with Store {
return monero!.getTransactionInfoAccountId(tx) == monero!.getCurrentAccount(wallet).id; 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; return true;
}); });
} }
@action @action
void _onMoneroAccountChange(WalletBase wallet) { void _onMoneroAccountChange(WalletBase wallet) {
if (wallet.type == WalletType.monero) {
subname = monero!.getCurrentAccount(wallet).label; subname = monero!.getCurrentAccount(wallet).label;
} else if (wallet.type == WalletType.wownero) {
subname = wow.wownero!.getCurrentAccount(wallet).label;
}
_onMoneroTransactionsUpdate(wallet); _onMoneroTransactionsUpdate(wallet);
} }
@action @action
void _onMoneroTransactionsUpdate(WalletBase wallet) { void _onMoneroTransactionsUpdate(WalletBase wallet) {
transactions.clear(); transactions.clear();
if (wallet.type == WalletType.monero) {
final _accountTransactions = monero! final _accountTransactions = monero!
.getTransactionHistory(wallet) .getTransactionHistory(wallet)
.transactions .transactions
@ -515,6 +566,20 @@ abstract class DashboardViewModelBase with Store {
transaction: transaction, transaction: transaction,
balanceViewModel: balanceViewModel, balanceViewModel: balanceViewModel,
settingsStore: appStore.settingsStore))); 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)));
}
} }
void updateActions() { void updateActions() {

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/wownero/wownero.dart';
import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -13,7 +14,7 @@ class MoneroAccountEditOrCreateViewModel = MoneroAccountEditOrCreateViewModelBas
with _$MoneroAccountEditOrCreateViewModel; with _$MoneroAccountEditOrCreateViewModel;
abstract class MoneroAccountEditOrCreateViewModelBase with Store { abstract class MoneroAccountEditOrCreateViewModelBase with Store {
MoneroAccountEditOrCreateViewModelBase(this._moneroAccountList, this._havenAccountList, MoneroAccountEditOrCreateViewModelBase(this._moneroAccountList, this._wowneroAccountList, this._havenAccountList,
{required WalletBase wallet, AccountListItem? accountListItem}) {required WalletBase wallet, AccountListItem? accountListItem})
: state = InitialExecutionState(), : state = InitialExecutionState(),
isEdit = accountListItem != null, isEdit = accountListItem != null,
@ -30,6 +31,7 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store {
String label; String label;
final MoneroAccountList _moneroAccountList; final MoneroAccountList _moneroAccountList;
final WowneroAccountList? _wowneroAccountList;
final HavenAccountList? _havenAccountList; final HavenAccountList? _havenAccountList;
final AccountListItem? _accountListItem; final AccountListItem? _accountListItem;
final WalletBase _wallet; final WalletBase _wallet;
@ -42,6 +44,10 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store {
if (_wallet.type == WalletType.haven) { if (_wallet.type == WalletType.haven) {
await saveHaven(); await saveHaven();
} }
if (_wallet.type == WalletType.wownero) {
await saveWownero();
}
} }
Future<void> saveMonero() async { Future<void> saveMonero() async {
@ -91,4 +97,27 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store {
state = FailureState(e.toString()); state = FailureState(e.toString());
} }
} }
Future<void> 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());
}
}
} }

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/wownero/wownero.dart';
import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
@ -47,6 +48,17 @@ abstract class MoneroAccountListViewModelBase with Store {
.toList(); .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}'); 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) { if (_wallet.type == WalletType.haven) {
haven!.setCurrentAccount( haven!.setCurrentAccount(
_wallet, _wallet,

View file

@ -65,7 +65,7 @@ abstract class NodeCreateOrEditViewModelBase with Store {
bool get isReady => address.isNotEmpty && port.isNotEmpty; bool get isReady => address.isNotEmpty && port.isNotEmpty;
bool get hasAuthCredentials => bool get hasAuthCredentials =>
_walletType == WalletType.monero || _walletType == WalletType.haven; _walletType == WalletType.monero || _walletType == WalletType.wownero || _walletType == WalletType.haven;
bool get hasTestnetSupport => _walletType == WalletType.bitcoin; bool get hasTestnetSupport => _walletType == WalletType.bitcoin;

View file

@ -1,4 +1,5 @@
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_item.dart'; 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:mobx/mobx.dart';
import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_base.dart';
import 'package:cake_wallet/bitcoin/bitcoin.dart'; import 'package:cake_wallet/bitcoin/bitcoin.dart';
@ -80,6 +81,16 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
await wallet.save(); 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) { if (wallet.type == WalletType.haven) {
await haven await haven
!.getSubaddressList(wallet) !.getSubaddressList(wallet)
@ -103,6 +114,11 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
accountIndex: monero!.getCurrentAccount(wallet).id, addressIndex: index, label: label); accountIndex: monero!.getCurrentAccount(wallet).id, addressIndex: index, label: label);
await wallet.save(); 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) { if (wallet.type == WalletType.haven) {
await haven!.getSubaddressList(wallet).setLabelSubaddress(wallet, await haven!.getSubaddressList(wallet).setLabelSubaddress(wallet,
accountIndex: haven!.getCurrentAccount(wallet).id, accountIndex: haven!.getCurrentAccount(wallet).id,

View file

@ -217,7 +217,7 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
selectedCurrency = walletTypeToCryptoCurrency(appStore.wallet!.type), selectedCurrency = walletTypeToCryptoCurrency(appStore.wallet!.type),
_cryptoNumberFormat = NumberFormat(_cryptoNumberPattern), _cryptoNumberFormat = NumberFormat(_cryptoNumberPattern),
hasAccounts = 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 = '', amount = '',
_settingsStore = appStore.settingsStore, _settingsStore = appStore.settingsStore,
super(appStore: appStore) { super(appStore: appStore) {
@ -229,7 +229,7 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
_init(); _init();
selectedCurrency = walletTypeToCryptoCurrency(wallet.type); 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'; static const String _cryptoNumberPattern = '0.00000000';
@ -340,6 +340,20 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
addressList.addAll(addressItems); 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) { if (wallet.type == WalletType.haven) {
final primaryAddress = haven!.getSubaddressList(wallet).subaddresses.first; final primaryAddress = haven!.getSubaddressList(wallet).subaddresses.first;
final addressItems = haven!.getSubaddressList(wallet).subaddresses.map((subaddress) { 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)); 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) { if (searchText.isNotEmpty) {
return ObservableList.of(addressList.where((item) { return ObservableList.of(addressList.where((item) {
if (item is WalletAddressListItem) { if (item is WalletAddressListItem) {
@ -465,6 +465,10 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
return monero!.getCurrentAccount(wallet).label; return monero!.getCurrentAccount(wallet).label;
} }
if (wallet.type == WalletType.wownero) {
return wownero!.getCurrentAccount(wallet).label;
}
if (wallet.type == WalletType.haven) { if (wallet.type == WalletType.haven) {
return haven!.getCurrentAccount(wallet).label; return haven!.getCurrentAccount(wallet).label;
} }
@ -475,6 +479,7 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
@computed @computed
bool get hasAddressList => bool get hasAddressList =>
wallet.type == WalletType.monero || wallet.type == WalletType.monero ||
wallet.type == WalletType.wownero ||
wallet.type == WalletType.haven || wallet.type == WalletType.haven ||
wallet.type == WalletType.bitcoinCash || wallet.type == WalletType.bitcoinCash ||
wallet.type == WalletType.bitcoin || wallet.type == WalletType.bitcoin ||
@ -513,7 +518,7 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
void _init() { void _init() {
_baseItems = []; _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()); _baseItems.add(WalletAccountListHeader());
} }