CAKE-343 | added bitcoin_wallet_addresses.dart and litecoin_wallet_addresses.dart tj the app; moved addresses from wallets to wallet addresses classes; deleted wallet addresses credentials

This commit is contained in:
OleksandrSobol 2021-07-13 08:46:34 +03:00
parent e03f0ce4d3
commit 0d367c4b45
25 changed files with 384 additions and 312 deletions

View file

@ -1,12 +1,12 @@
import 'package:mobx/mobx.dart';
import 'package:flutter/foundation.dart';
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
import 'package:cake_wallet/bitcoin/utils.dart';
import 'package:cake_wallet/bitcoin/electrum_wallet_snapshot.dart';
import 'package:cake_wallet/bitcoin/electrum_wallet.dart';
import 'package:cake_wallet/entities/wallet_info.dart';
import 'package:cake_wallet/bitcoin/bitcoin_address_record.dart';
import 'package:cake_wallet/bitcoin/electrum_balance.dart';
import 'package:cake_wallet/bitcoin/bitcoin_wallet_addresses.dart';
part 'bitcoin_wallet.g.dart';
@ -26,8 +26,14 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
walletInfo: walletInfo,
networkType: bitcoin.bitcoin,
initialAddresses: initialAddresses,
initialBalance: initialBalance,
accountIndex: accountIndex);
initialBalance: initialBalance) {
walletAddresses = BitcoinWalletAddresses(
walletInfo,
initialAddresses: initialAddresses,
accountIndex: accountIndex,
hd: hd,
networkType: networkType);
}
static Future<BitcoinWallet> open({
@required String name,
@ -44,8 +50,4 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
initialBalance: snp.balance,
accountIndex: snp.accountIndex);
}
@override
String getAddress({@required int index, @required bitcoin.HDWallet hd}) =>
generateP2WPKHAddress(hd: hd, index: index, networkType: networkType);
}

View file

@ -0,0 +1,33 @@
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
import 'package:cake_wallet/bitcoin/utils.dart';
import 'package:cake_wallet/bitcoin/bitcoin_address_record.dart';
import 'package:cake_wallet/bitcoin/electrum_wallet_addresses.dart';
import 'package:cake_wallet/entities/wallet_info.dart';
import 'package:flutter/foundation.dart';
import 'package:mobx/mobx.dart';
part 'bitcoin_wallet_addresses.g.dart';
class BitcoinWalletAddresses = BitcoinWalletAddressesBase
with _$BitcoinWalletAddresses;
abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses
with Store {
BitcoinWalletAddressesBase(
WalletInfo walletInfo,
{@required List<BitcoinAddressRecord> initialAddresses,
int accountIndex = 0,
@required bitcoin.HDWallet hd,
@required this.networkType})
: super(
walletInfo,
initialAddresses: initialAddresses,
accountIndex: accountIndex,
hd: hd);
bitcoin.NetworkType networkType;
@override
String getAddress({@required int index, @required bitcoin.HDWallet hd}) =>
generateP2WPKHAddress(hd: hd, index: index, networkType: networkType);
}

View file

@ -1,7 +1,6 @@
import 'dart:async';
import 'dart:convert';
import 'package:cake_wallet/bitcoin/electrum_wallet_addresses.dart';
import 'package:cake_wallet/bitcoin/electrum_wallet_addresses_credentials.dart';
import 'package:mobx/mobx.dart';
import 'package:rxdart/subjects.dart';
import 'package:flutter/foundation.dart';
@ -44,18 +43,14 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
@required this.networkType,
@required this.mnemonic,
ElectrumClient electrumClient,
int accountIndex = 0,
ElectrumBalance initialBalance})
: balance = initialBalance ??
const ElectrumBalance(confirmed: 0, unconfirmed: 0),
hd = bitcoin.HDWallet.fromSeed(mnemonicToSeedBytes(mnemonic),
network: networkType)
.derivePath("m/0'/0"),
addresses = ObservableList<BitcoinAddressRecord>.of(
(initialAddresses ?? []).toSet()),
syncStatus = NotConnectedSyncStatus(),
_password = password,
_accountIndex = accountIndex,
_feeRates = <int>[],
_isTransactionUpdating = false,
super(walletInfo) {
@ -65,8 +60,6 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
ElectrumTransactionHistory(walletInfo: walletInfo, password: password);
_unspent = [];
_scripthashesUpdateSubject = {};
_walletAddressInBox = ElectrumWalletAddresses(walletInfo);
_walletAddressInBoxCredentials = ElectrumWalletAddressesCredentials();
}
static int estimatedTransactionSize(int inputsCount, int outputsCounts) =>
@ -78,8 +71,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
ElectrumClient electrumClient;
@override
@observable
String address;
ElectrumWalletAddresses walletAddresses;
@override
@observable
@ -89,17 +81,12 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
@observable
SyncStatus syncStatus;
ObservableList<BitcoinAddressRecord> addresses;
List<String> get scriptHashes => addresses
List<String> get scriptHashes => walletAddresses.addresses
.map((addr) => scriptHash(addr.address, networkType: networkType))
.toList();
String get xpub => hd.base58;
ElectrumWalletAddresses _walletAddressInBox;
ElectrumWalletAddressesCredentials _walletAddressInBoxCredentials;
@override
String get seed => mnemonic;
@ -112,81 +99,21 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
final String _password;
List<BitcoinUnspent> _unspent;
List<int> _feeRates;
int _accountIndex;
Map<String, BehaviorSubject<Object>> _scripthashesUpdateSubject;
bool _isTransactionUpdating;
Future<void> init() async {
await generateAddresses();
address = addresses[_accountIndex].address;
await walletAddresses.init();
await transactionHistory.init();
await _updateWalletAddressInBox();
}
@action
Future<void> nextAddress() async {
_accountIndex += 1;
if (_accountIndex >= addresses.length) {
_accountIndex = 0;
}
address = addresses[_accountIndex].address;
await save();
}
Future<void> generateAddresses() async {
if (addresses.length < 33) {
final addressesCount = 33 - addresses.length;
await generateNewAddresses(addressesCount,
startIndex: addresses.length, hd: hd);
}
}
Future<BitcoinAddressRecord> generateNewAddress(
{bool isHidden = false, bitcoin.HDWallet hd}) async {
_accountIndex += 1;
final _hd = hd ?? this.hd;
final address = BitcoinAddressRecord(
getAddress(index: _accountIndex, hd: _hd),
index: _accountIndex,
isHidden: isHidden);
addresses.add(address);
await save();
return address;
}
Future<List<BitcoinAddressRecord>> generateNewAddresses(int count,
{int startIndex = 0, bitcoin.HDWallet hd, bool isHidden = false}) async {
final list = <BitcoinAddressRecord>[];
for (var i = startIndex; i < count + startIndex; i++) {
final address = BitcoinAddressRecord(getAddress(index: i, hd: hd),
index: i, isHidden: isHidden);
list.add(address);
}
addresses.addAll(list);
await save();
return list;
}
Future<void> updateAddress(String address) async {
for (final addr in addresses) {
if (addr.address == address) {
await save();
break;
}
}
}
@action
@override
Future<void> startSync() async {
try {
syncStatus = StartingSyncStatus();
updateTransactions();
await updateTransactions();
_subscribeForUpdates();
await _updateBalance();
await _updateUnspent();
@ -238,7 +165,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
? allAmount
: credentialsAmount;
final txb = bitcoin.TransactionBuilder(network: networkType);
final changeAddress = address;
final changeAddress = walletAddresses.address;
var leftAmount = amount;
var totalInputAmount = 0;
@ -321,8 +248,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
String toJSON() => json.encode({
'mnemonic': mnemonic,
'account_index': _accountIndex.toString(),
'addresses': addresses.map((addr) => addr.toJSON()).toList(),
'account_index': walletAddresses.accountIndex.toString(),
'addresses': walletAddresses.addresses.map((addr) => addr.toJSON()).toList(),
'balance': balance?.toJSON()
});
@ -370,7 +297,6 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
final path = await makePath();
await write(path: path, password: _password, data: toJSON());
await transactionHistory.save();
await _updateWalletAddressInBox();
}
bitcoin.ECPair keyPairFor({@required int index}) =>
@ -386,13 +312,12 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
} catch (_) {}
}
String getAddress({@required int index, @required bitcoin.HDWallet hd}) => '';
Future<String> makePath() async =>
pathForWallet(name: walletInfo.name, type: walletInfo.type);
Future<void> _updateUnspent() async {
final unspent = await Future.wait(addresses.map((address) => electrumClient
final unspent = await Future.wait(walletAddresses
.addresses.map((address) => electrumClient
.getListUnspentWithAddress(address.address, networkType)
.then((unspent) => unspent
.map((unspent) => BitcoinUnspent.fromJSON(address, unspent)))));
@ -403,7 +328,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
{@required String hash, @required int height}) async {
final tx = await electrumClient.getTransactionExpanded(hash: hash);
return ElectrumTransactionInfo.fromElectrumVerbose(tx, walletInfo.type,
height: height, addresses: addresses);
height: height, addresses: walletAddresses.addresses);
}
@override
@ -473,9 +398,4 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
balance = await _fetchBalances();
await save();
}
Future<void> _updateWalletAddressInBox() async {
_walletAddressInBoxCredentials.address = address;
await _walletAddressInBox.update(_walletAddressInBoxCredentials);
}
}

View file

@ -1,30 +1,109 @@
import 'package:cake_wallet/bitcoin/electrum_wallet_addresses_credentials.dart';
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
import 'package:cake_wallet/bitcoin/bitcoin_address_record.dart';
import 'package:cake_wallet/entities/wallet_addresses.dart';
import 'package:cake_wallet/entities/wallet_addresses_credentials.dart';
import 'package:cake_wallet/entities/wallet_info.dart';
import 'package:flutter/foundation.dart';
import 'package:mobx/mobx.dart';
class ElectrumWalletAddresses extends WalletAddresses {
ElectrumWalletAddresses(WalletInfo walletInfo) : super(walletInfo);
part 'electrum_wallet_addresses.g.dart';
class ElectrumWalletAddresses = ElectrumWalletAddressesBase
with _$ElectrumWalletAddresses;
abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
ElectrumWalletAddressesBase(WalletInfo walletInfo,
{@required List<BitcoinAddressRecord> initialAddresses,
int accountIndex = 0,
@required bitcoin.HDWallet hd})
: super(walletInfo) {
this.hd = hd;
this.accountIndex = accountIndex;
addresses = ObservableList<BitcoinAddressRecord>.of(
(initialAddresses ?? []).toSet());
}
@override
Future<void> update(WalletAddressesCredentials credentials) async {
try {
if (credentials == null) {
return;
@observable
String address;
bitcoin.HDWallet hd;
ObservableList<BitcoinAddressRecord> addresses;
int accountIndex;
@override
Future<void> init() async {
await generateAddresses();
address = addresses[accountIndex].address;
await updateAddressesInBox();
}
final _credentials = credentials as ElectrumWalletAddressesCredentials;
final _address = _credentials.address;
final _label = '';
@action
Future<void> nextAddress() async {
accountIndex += 1;
if (_address == null || _address.isEmpty) {
return;
if (accountIndex >= addresses.length) {
accountIndex = 0;
}
addresses.clear();
addresses[_address] = _label;
address = addresses[accountIndex].address;
await updateAddressesInBox();
}
Future<void> generateAddresses() async {
if (addresses.length < 33) {
final addressesCount = 33 - addresses.length;
await generateNewAddresses(addressesCount,
startIndex: addresses.length, hd: hd);
}
}
Future<BitcoinAddressRecord> generateNewAddress(
{bool isHidden = false, bitcoin.HDWallet hd}) async {
accountIndex += 1;
final _hd = hd ?? this.hd;
final address = BitcoinAddressRecord(
getAddress(index: accountIndex, hd: _hd),
index: accountIndex,
isHidden: isHidden);
addresses.add(address);
return address;
}
Future<List<BitcoinAddressRecord>> generateNewAddresses(int count,
{int startIndex = 0, bitcoin.HDWallet hd, bool isHidden = false}) async {
final list = <BitcoinAddressRecord>[];
for (var i = startIndex; i < count + startIndex; i++) {
final address = BitcoinAddressRecord(getAddress(index: i, hd: hd),
index: i, isHidden: isHidden);
list.add(address);
}
addresses.addAll(list);
return list;
}
/*Future<void> updateAddress(String address) async {
for (final addr in addresses) {
if (addr.address == address) {
await save();
break;
}
}
}*/
String getAddress({@required int index, @required bitcoin.HDWallet hd}) => '';
@override
Future<void> updateAddressesInBox() async {
try {
addressesMap.clear();
addressesMap[address] = '';
await saveAddressesInBox();
} catch (e) {
print(e.toString());
}

View file

@ -1,7 +0,0 @@
import 'package:cake_wallet/entities/wallet_addresses_credentials.dart';
class ElectrumWalletAddressesCredentials extends WalletAddressesCredentials {
ElectrumWalletAddressesCredentials();
String address;
}

View file

@ -1,6 +1,5 @@
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
import 'package:cake_wallet/bitcoin/bitcoin_mnemonic.dart';
import 'package:cake_wallet/bitcoin/bitcoin_transaction_priority.dart';
import 'package:cake_wallet/bitcoin/litecoin_wallet_addresses.dart';
import 'package:cake_wallet/entities/transaction_priority.dart';
import 'package:flutter/foundation.dart';
import 'package:mobx/mobx.dart';
@ -10,7 +9,6 @@ import 'package:cake_wallet/bitcoin/electrum_wallet.dart';
import 'package:cake_wallet/bitcoin/bitcoin_address_record.dart';
import 'package:cake_wallet/bitcoin/electrum_balance.dart';
import 'package:cake_wallet/bitcoin/litecoin_network.dart';
import 'package:cake_wallet/bitcoin/utils.dart';
part 'litecoin_wallet.g.dart';
@ -30,8 +28,15 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
walletInfo: walletInfo,
networkType: litecoinNetwork,
initialAddresses: initialAddresses,
initialBalance: initialBalance,
accountIndex: accountIndex);
initialBalance: initialBalance) {
walletAddresses = LitecoinWalletAddresses(
walletInfo,
initialAddresses: initialAddresses,
accountIndex: accountIndex,
hd: hd,
networkType: networkType,
mnemonic: mnemonic);
}
static Future<LitecoinWallet> open({
@required String name,
@ -49,27 +54,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
accountIndex: snp.accountIndex);
}
@override
String getAddress({@required int index, @required bitcoin.HDWallet hd}) =>
generateP2WPKHAddress(hd: hd, index: index, networkType: networkType);
@override
Future<void> generateAddresses() async {
if (addresses.length < 33) {
final addressesCount = 22 - addresses.length;
await generateNewAddresses(addressesCount,
hd: hd, startIndex: addresses.length);
final changeRoot = bitcoin.HDWallet.fromSeed(
mnemonicToSeedBytes(mnemonic),
network: networkType)
.derivePath("m/0'/1");
await generateNewAddresses(11,
startIndex: 0, hd: changeRoot, isHidden: true);
}
}
@override
int feeRate(TransactionPriority priority) {
if (priority is LitecoinTransactionPriority) {

View file

@ -0,0 +1,54 @@
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
import 'package:cake_wallet/bitcoin/bitcoin_mnemonic.dart';
import 'package:cake_wallet/bitcoin/utils.dart';
import 'package:cake_wallet/bitcoin/bitcoin_address_record.dart';
import 'package:cake_wallet/bitcoin/electrum_wallet_addresses.dart';
import 'package:cake_wallet/entities/wallet_info.dart';
import 'package:flutter/foundation.dart';
import 'package:mobx/mobx.dart';
part 'litecoin_wallet_addresses.g.dart';
class LitecoinWalletAddresses = LitecoinWalletAddressesBase
with _$LitecoinWalletAddresses;
abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses
with Store {
LitecoinWalletAddressesBase(
WalletInfo walletInfo,
{@required List<BitcoinAddressRecord> initialAddresses,
int accountIndex = 0,
@required bitcoin.HDWallet hd,
@required this.networkType,
@required this.mnemonic})
: super(
walletInfo,
initialAddresses: initialAddresses,
accountIndex: accountIndex,
hd: hd);
bitcoin.NetworkType networkType;
final String mnemonic;
@override
String getAddress({@required int index, @required bitcoin.HDWallet hd}) =>
generateP2WPKHAddress(hd: hd, index: index, networkType: networkType);
@override
Future<void> generateAddresses() async {
if (addresses.length < 33) {
final addressesCount = 22 - addresses.length;
await generateNewAddresses(addressesCount,
hd: hd, startIndex: addresses.length);
final changeRoot = bitcoin.HDWallet.fromSeed(
mnemonicToSeedBytes(mnemonic),
network: networkType)
.derivePath("m/0'/1");
await generateNewAddresses(11,
startIndex: 0, hd: changeRoot, isHidden: true);
}
}
}

View file

@ -15,7 +15,7 @@ abstract class BuyProvider {
String get trackUrl;
WalletType get walletType => wallet.type;
String get walletAddress => wallet.address;
String get walletAddress => wallet.walletAddresses.address;
String get walletId => wallet.id;
@override

View file

@ -1,6 +1,7 @@
import 'package:cake_wallet/entities/balance.dart';
import 'package:cake_wallet/entities/transaction_info.dart';
import 'package:cake_wallet/entities/transaction_priority.dart';
import 'package:cake_wallet/entities/wallet_addresses.dart';
import 'package:flutter/foundation.dart';
import 'package:cake_wallet/entities/wallet_info.dart';
import 'package:cake_wallet/core/pending_transaction.dart';
@ -30,9 +31,9 @@ abstract class WalletBase<
String get name => walletInfo.name;
String get address;
//String get address;
set address(String address);
//set address(String address);
BalanceType get balance;
@ -44,6 +45,8 @@ abstract class WalletBase<
Object get keys;
WalletAddresses get walletAddresses;
HistoryType transactionHistory;
Future<void> connectToNode({@required Node node});

View file

@ -361,7 +361,7 @@ Future setup(
getIt.registerFactoryParam<MoneroAccountEditOrCreateViewModel,
AccountListItem, void>(
(AccountListItem account, _) => MoneroAccountEditOrCreateViewModel(
(getIt.get<AppStore>().wallet as MoneroWallet).accountList,
(getIt.get<AppStore>().wallet as MoneroWallet).walletAddresses.accountList,
wallet: getIt.get<AppStore>().wallet,
accountListItem: account));

View file

@ -1,24 +1,30 @@
import 'package:cake_wallet/entities/wallet_addresses_credentials.dart';
import 'package:cake_wallet/entities/wallet_info.dart';
abstract class WalletAddresses {
WalletAddresses(this.walletInfo) {
addresses = walletInfo?.addresses ?? {};
addressesMap = {};
}
final WalletInfo walletInfo;
Map<String, String> addresses;
String get address;
Future<void> update(WalletAddressesCredentials credentials);
set address(String address);
Future<void> save() async {
Map<String, String> addressesMap;
Future<void> init();
Future<void> updateAddressesInBox();
Future<void> saveAddressesInBox() async {
try {
if (walletInfo == null) {
return;
}
walletInfo.addresses = addresses;
walletInfo.address = address;
walletInfo.addresses = addressesMap;
if (walletInfo.isInBox) {
await walletInfo.save();

View file

@ -1 +0,0 @@
abstract class WalletAddressesCredentials {}

View file

@ -4,7 +4,6 @@ import 'package:cake_wallet/monero/monero_amount_format.dart';
import 'package:cake_wallet/monero/monero_transaction_creation_exception.dart';
import 'package:cake_wallet/monero/monero_transaction_info.dart';
import 'package:cake_wallet/monero/monero_wallet_addresses.dart';
import 'package:cake_wallet/monero/monero_wallet_addresses_credentials.dart';
import 'package:flutter/foundation.dart';
import 'package:mobx/mobx.dart';
import 'package:cw_monero/transaction_history.dart'
@ -17,10 +16,7 @@ import 'package:cake_wallet/monero/pending_monero_transaction.dart';
import 'package:cake_wallet/monero/monero_wallet_keys.dart';
import 'package:cake_wallet/monero/monero_balance.dart';
import 'package:cake_wallet/monero/monero_transaction_history.dart';
import 'package:cake_wallet/monero/monero_subaddress_list.dart';
import 'package:cake_wallet/monero/monero_account_list.dart';
import 'package:cake_wallet/monero/account.dart';
import 'package:cake_wallet/monero/subaddress.dart';
import 'package:cake_wallet/core/pending_transaction.dart';
import 'package:cake_wallet/core/wallet_base.dart';
import 'package:cake_wallet/entities/sync_status.dart';
@ -37,9 +33,7 @@ class MoneroWallet = MoneroWalletBase with _$MoneroWallet;
abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
MoneroTransactionHistory, MoneroTransactionInfo> with Store {
MoneroWalletBase({WalletInfo walletInfo})
: accountList = MoneroAccountList(),
subaddressList = MoneroSubaddressList(),
super(walletInfo) {
: super(walletInfo) {
transactionHistory = MoneroTransactionHistory();
balance = MoneroBalance(
fullBalance: monero_wallet.getFullBalance(accountIndex: 0),
@ -49,35 +43,26 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
_isSavingAfterSync = false;
_isSavingAfterNewTransaction = false;
_isTransactionUpdating = false;
_walletAllAddresses = MoneroWalletAddresses(walletInfo);
_walletAddressesCredentials = MoneroWalletAddressesCredentials();
_onAccountChangeReaction = reaction((_) => account, (Account account) {
walletAddresses = MoneroWalletAddresses(walletInfo);
_onAccountChangeReaction = reaction((_) => walletAddresses.account,
(Account account) {
balance = MoneroBalance(
fullBalance: monero_wallet.getFullBalance(accountIndex: account.id),
unlockedBalance:
monero_wallet.getUnlockedBalance(accountIndex: account.id));
subaddressList.update(accountIndex: account.id);
subaddress = subaddressList.subaddresses.first;
address = subaddress.address;
walletAddresses.updateSubaddressList(accountIndex: account.id);
});
}
static const int _autoAfterSyncSaveInterval = 60000;
@observable
Account account;
@observable
Subaddress subaddress;
@override
MoneroWalletAddresses walletAddresses;
@override
@observable
SyncStatus syncStatus;
@override
@observable
String address;
@override
@observable
MoneroBalance balance;
@ -92,10 +77,6 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
publicSpendKey: monero_wallet.getPublicSpendKey(),
publicViewKey: monero_wallet.getPublicViewKey());
final MoneroSubaddressList subaddressList;
final MoneroAccountList accountList;
SyncListener _listener;
ReactionDisposer _onAccountChangeReaction;
int _lastAutosaveTimestamp;
@ -103,20 +84,13 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
bool _isSavingAfterNewTransaction;
bool _isTransactionUpdating;
int _lastSaveTimestamp;
MoneroWalletAddresses _walletAllAddresses;
MoneroWalletAddressesCredentials _walletAddressesCredentials;
Future<void> init() async {
accountList.update();
account = accountList.accounts.first;
subaddressList.update(accountIndex: account.id ?? 0);
subaddress = subaddressList.getAll().first;
await walletAddresses.init();
balance = MoneroBalance(
fullBalance: monero_wallet.getFullBalance(accountIndex: account.id),
fullBalance: monero_wallet.getFullBalance(accountIndex: walletAddresses.account.id),
unlockedBalance:
monero_wallet.getUnlockedBalance(accountIndex: account.id));
address = subaddress.address;
await _updateWalletAllAddressesInBox();
monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account.id));
_setListeners();
await updateTransactions();
@ -136,24 +110,6 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
_onAccountChangeReaction?.reaction?.dispose();
}
bool validate() {
accountList.update();
final accountListLength = accountList.accounts?.length ?? 0;
if (accountListLength <= 0) {
return false;
}
subaddressList.update(accountIndex: accountList.accounts.first.id);
final subaddressListLength = subaddressList.subaddresses?.length ?? 0;
if (subaddressListLength <= 0) {
return false;
}
return true;
}
@override
Future<void> connectToNode({@required Node node}) async {
try {
@ -196,7 +152,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
? moneroParseAmount(amount: _credentials.amount)
: null;
final unlockedBalance =
monero_wallet.getUnlockedBalance(accountIndex: account.id);
monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account.id);
if ((amount != null && unlockedBalance < amount) ||
(amount == null && unlockedBalance <= 0)) {
@ -216,7 +172,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
paymentId: _credentials.paymentId,
amount: _credentials.amount,
priorityRaw: _credentials.priority.serialize(),
accountIndex: account.id);
accountIndex: walletAddresses.account.id);
return PendingMoneroTransaction(pendingTransactionDescription);
}
@ -245,7 +201,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
@override
Future<void> save() async {
await _updateWalletAllAddressesInBox();
await walletAddresses.updateAddressesInBox();
final now = DateTime.now().millisecondsSinceEpoch;
@ -274,7 +230,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
monero_wallet.rescanBlockchainAsync();
await startSync();
_askForUpdateBalance();
accountList.update();
walletAddresses.accountList.update();
await _askForUpdateTransactionHistory();
await save();
await walletInfo.save();
@ -373,10 +329,10 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
await updateTransactions();
int _getFullBalance() =>
monero_wallet.getFullBalance(accountIndex: account.id);
monero_wallet.getFullBalance(accountIndex: walletAddresses.account.id);
int _getUnlockedBalance() =>
monero_wallet.getUnlockedBalance(accountIndex: account.id);
monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account.id);
Future<void> _afterSyncSave() async {
try {
@ -423,13 +379,13 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
if (walletInfo.isRecovery) {
await _askForUpdateTransactionHistory();
_askForUpdateBalance();
accountList.update();
walletAddresses.accountList.update();
}
if (blocksLeft < 100) {
await _askForUpdateTransactionHistory();
_askForUpdateBalance();
accountList.update();
walletAddresses.accountList.update();
syncStatus = SyncedSyncStatus();
await _afterSyncSave();
@ -454,14 +410,4 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
print(e.toString());
}
}
Future<void> _updateWalletAllAddressesInBox() async {
_walletAddressesCredentials
..accountList = accountList
..subaddressList = subaddressList;
await _walletAllAddresses.update(_walletAddressesCredentials);
subaddressList.update(accountIndex: account.id ?? 0);
subaddress = subaddressList.subaddresses.first;
address = subaddress.address;
}
}

View file

@ -1,38 +1,85 @@
import 'package:cake_wallet/entities/wallet_addresses.dart';
import 'package:cake_wallet/entities/wallet_addresses_credentials.dart';
import 'package:cake_wallet/entities/wallet_info.dart';
import 'monero_wallet_addresses_credentials.dart';
import 'package:cake_wallet/monero/account.dart';
import 'package:cake_wallet/monero/monero_account_list.dart';
import 'package:cake_wallet/monero/monero_subaddress_list.dart';
import 'package:cake_wallet/monero/subaddress.dart';
import 'package:mobx/mobx.dart';
class MoneroWalletAddresses extends WalletAddresses {
MoneroWalletAddresses(WalletInfo walletInfo) : super(walletInfo);
part 'monero_wallet_addresses.g.dart';
class MoneroWalletAddresses = MoneroWalletAddressesBase
with _$MoneroWalletAddresses;
abstract class MoneroWalletAddressesBase extends WalletAddresses with Store {
MoneroWalletAddressesBase(WalletInfo walletInfo) : super(walletInfo) {
accountList = MoneroAccountList();
subaddressList = MoneroSubaddressList();
}
@override
Future<void> update(WalletAddressesCredentials credentials) async {
@observable
String address;
@observable
Account account;
@observable
Subaddress subaddress;
MoneroSubaddressList subaddressList;
MoneroAccountList accountList;
@override
Future<void> init() async {
accountList.update();
account = accountList.accounts.first;
updateSubaddressList(accountIndex: account.id ?? 0);
await updateAddressesInBox();
}
@override
Future<void> updateAddressesInBox() async {
try {
if (credentials == null) {
return;
}
final _subaddressList = MoneroSubaddressList();
final _credentials = credentials as MoneroWalletAddressesCredentials;
final _accountList = _credentials.accountList;
final _subaddressList = _credentials.subaddressList;
addressesMap.clear();
if (_accountList == null || _subaddressList == null) {
return;
}
addresses.clear();
_accountList.accounts.forEach((account) {
accountList.accounts.forEach((account) {
_subaddressList.update(accountIndex: account.id);
_subaddressList.subaddresses.forEach((subaddress) {
addresses[subaddress.address] = subaddress.label;
addressesMap[subaddress.address] = subaddress.label;
});
});
await save();
await saveAddressesInBox();
} catch (e) {
print(e.toString());
}
}
bool validate() {
accountList.update();
final accountListLength = accountList.accounts?.length ?? 0;
if (accountListLength <= 0) {
return false;
}
subaddressList.update(accountIndex: accountList.accounts.first.id);
final subaddressListLength = subaddressList.subaddresses?.length ?? 0;
if (subaddressListLength <= 0) {
return false;
}
return true;
}
void updateSubaddressList({int accountIndex}) {
subaddressList.update(accountIndex: accountIndex);
subaddress = subaddressList.subaddresses.first;
address = subaddress.address;
}
}

View file

@ -1,9 +0,0 @@
import 'package:cake_wallet/entities/wallet_addresses_credentials.dart';
import 'package:cake_wallet/monero/monero_account_list.dart';
import 'package:cake_wallet/monero/monero_subaddress_list.dart';
class MoneroWalletAddressesCredentials extends WalletAddressesCredentials {
MoneroAccountList accountList;
MoneroSubaddressList subaddressList;
}

View file

@ -117,7 +117,7 @@ class MoneroWalletService extends WalletService<
(info) => info.id == WalletBase.idFor(name, getType()),
orElse: () => null);
final wallet = MoneroWallet(walletInfo: walletInfo);
final isValid = wallet.validate();
final isValid = wallet.walletAddresses.validate();
if (!isValid) {
await _removeCache(name);

View file

@ -37,7 +37,7 @@ void startCurrentWalletChangeReaction(AppStore appStore,
await wallet.connectToNode(node: node);
if (wallet.walletInfo.address?.isEmpty ?? true) {
wallet.walletInfo.address = wallet.address;
wallet.walletInfo.address = wallet.walletAddresses.address;
if (wallet.walletInfo.isInBox) {
await wallet.walletInfo.save();

View file

@ -179,7 +179,7 @@ class ExchangePage extends BasePage {
initialAddress:
exchangeViewModel.depositCurrency ==
exchangeViewModel.wallet.currency
? exchangeViewModel.wallet.address
? exchangeViewModel.wallet.walletAddresses.address
: exchangeViewModel.depositAddress,
initialIsAmountEditable: true,
initialIsAddressEditable:
@ -240,7 +240,7 @@ class ExchangePage extends BasePage {
initialAddress: exchangeViewModel
.receiveCurrency ==
exchangeViewModel.wallet.currency
? exchangeViewModel.wallet.address
? exchangeViewModel.wallet.walletAddresses.address
: exchangeViewModel.receiveAddress,
initialIsAmountEditable: exchangeViewModel
.isReceiveAmountEditable,
@ -646,7 +646,8 @@ class ExchangePage extends BasePage {
}
});
reaction((_) => exchangeViewModel.wallet.address, (String address) {
reaction((_) => exchangeViewModel.wallet.walletAddresses.address,
(String address) {
if (exchangeViewModel.depositCurrency == CryptoCurrency.xmr) {
depositKey.currentState.changeAddress(address: address);
}
@ -707,7 +708,8 @@ class ExchangePage extends BasePage {
isCurrentTypeWallet ? exchangeViewModel.wallet.name : null);
key.currentState.changeAddress(
address: isCurrentTypeWallet ? exchangeViewModel.wallet.address : '');
address: isCurrentTypeWallet
? exchangeViewModel.wallet.walletAddresses.address : '');
key.currentState.changeAmount(amount: '');
}
@ -719,9 +721,9 @@ class ExchangePage extends BasePage {
if (isCurrentTypeWallet) {
key.currentState.changeWalletName(exchangeViewModel.wallet.name);
key.currentState.addressController.text =
exchangeViewModel.wallet.address;
exchangeViewModel.wallet.walletAddresses.address;
} else if (key.currentState.addressController.text ==
exchangeViewModel.wallet.address) {
exchangeViewModel.wallet.walletAddresses.address) {
key.currentState.changeWalletName(null);
key.currentState.addressController.text = null;
}

View file

@ -129,7 +129,7 @@ class ExchangeTemplatePage extends BasePage {
initialAddress: exchangeViewModel
.depositCurrency ==
exchangeViewModel.wallet.currency
? exchangeViewModel.wallet.address
? exchangeViewModel.wallet.walletAddresses.address
: exchangeViewModel.depositAddress,
initialIsAmountEditable: true,
initialIsAddressEditable: exchangeViewModel
@ -168,7 +168,7 @@ class ExchangeTemplatePage extends BasePage {
initialAddress:
exchangeViewModel.receiveCurrency ==
exchangeViewModel.wallet.currency
? exchangeViewModel.wallet.address
? exchangeViewModel.wallet.walletAddresses.address
: exchangeViewModel.receiveAddress,
initialIsAmountEditable:
exchangeViewModel.provider is
@ -383,7 +383,8 @@ class ExchangeTemplatePage extends BasePage {
}
});
reaction((_) => exchangeViewModel.wallet.address, (String address) {
reaction((_) => exchangeViewModel.wallet.walletAddresses.address,
(String address) {
if (exchangeViewModel.depositCurrency == CryptoCurrency.xmr) {
depositKey.currentState.changeAddress(address: address);
}
@ -405,7 +406,8 @@ class ExchangeTemplatePage extends BasePage {
isCurrentTypeWallet ? exchangeViewModel.wallet.name : null);
key.currentState.changeAddress(
address: isCurrentTypeWallet ? exchangeViewModel.wallet.address : '');
address: isCurrentTypeWallet
? exchangeViewModel.wallet.walletAddresses.address : '');
key.currentState.changeAmount(amount: '');
}
@ -417,9 +419,9 @@ class ExchangeTemplatePage extends BasePage {
if (isCurrentTypeWallet) {
key.currentState.changeWalletName(exchangeViewModel.wallet.name);
key.currentState.addressController.text =
exchangeViewModel.wallet.address;
exchangeViewModel.wallet.walletAddresses.address;
} else if (key.currentState.addressController.text ==
exchangeViewModel.wallet.address) {
exchangeViewModel.wallet.walletAddresses.address) {
key.currentState.changeWalletName(null);
key.currentState.addressController.text = null;
}

View file

@ -92,17 +92,17 @@ abstract class DashboardViewModelBase with Store {
final _wallet = wallet;
if (_wallet is MoneroWallet) {
subname = _wallet.account?.label;
subname = _wallet.walletAddresses.account?.label;
_onMoneroAccountChangeReaction = reaction((_) => _wallet.account,
(Account account) => _onMoneroAccountChange(_wallet));
_onMoneroAccountChangeReaction = reaction((_) => _wallet.walletAddresses
.account, (Account account) => _onMoneroAccountChange(_wallet));
_onMoneroBalanceChangeReaction = reaction((_) => _wallet.balance,
(MoneroBalance balance) => _onMoneroTransactionsUpdate(_wallet));
final _accountTransactions = _wallet
.transactionHistory.transactions.values
.where((tx) => tx.accountIndex == _wallet.account.id)
.where((tx) => tx.accountIndex == _wallet.walletAddresses.account.id)
.toList();
transactions = ObservableList.of(_accountTransactions.map((transaction) =>
@ -131,7 +131,7 @@ abstract class DashboardViewModelBase with Store {
filter: (TransactionInfo tx) {
final wallet = _wallet;
if (tx is MoneroTransactionInfo && wallet is MoneroWallet) {
return tx.accountIndex == wallet.account.id;
return tx.accountIndex == wallet.walletAddresses.account.id;
}
return true;
@ -153,7 +153,7 @@ abstract class DashboardViewModelBase with Store {
String subname;
@computed
String get address => wallet.address;
String get address => wallet.walletAddresses.address;
@computed
SyncStatus get status => wallet.syncStatus;
@ -251,13 +251,13 @@ abstract class DashboardViewModelBase with Store {
wallet.type == WalletType.bitcoin && wallet.seed.split(' ').length < 24;
if (wallet is MoneroWallet) {
subname = wallet.account?.label;
subname = wallet.walletAddresses.account?.label;
_onMoneroAccountChangeReaction?.reaction?.dispose();
_onMoneroBalanceChangeReaction?.reaction?.dispose();
_onMoneroAccountChangeReaction = reaction((_) => wallet.account,
(Account account) => _onMoneroAccountChange(wallet));
_onMoneroAccountChangeReaction = reaction((_) => wallet.walletAddresses
.account, (Account account) => _onMoneroAccountChange(wallet));
_onMoneroBalanceChangeReaction = reaction((_) => wallet.balance,
(MoneroBalance balance) => _onMoneroTransactionsUpdate(wallet));
@ -284,7 +284,7 @@ abstract class DashboardViewModelBase with Store {
settingsStore: appStore.settingsStore),
filter: (TransactionInfo tx) {
if (tx is MoneroTransactionInfo && wallet is MoneroWallet) {
return tx.accountIndex == wallet.account.id;
return tx.accountIndex == wallet.walletAddresses.account.id;
}
return true;
@ -293,7 +293,7 @@ abstract class DashboardViewModelBase with Store {
@action
void _onMoneroAccountChange(MoneroWallet wallet) {
subname = wallet.account?.label;
subname = wallet.walletAddresses.account?.label;
_onMoneroTransactionsUpdate(wallet);
}
@ -302,7 +302,7 @@ abstract class DashboardViewModelBase with Store {
transactions.clear();
final _accountTransactions = wallet.transactionHistory.transactions.values
.where((tx) => tx.accountIndex == wallet.account.id)
.where((tx) => tx.accountIndex == wallet.walletAddresses.account.id)
.toList();
transactions.addAll(_accountTransactions.map((transaction) =>

View file

@ -41,7 +41,8 @@ abstract class ExchangeViewModelBase with Store {
depositAmount = '';
receiveAmount = '';
receiveAddress = '';
depositAddress = depositCurrency == wallet.currency ? wallet.address : '';
depositAddress = depositCurrency == wallet.currency
? wallet.walletAddresses.address : '';
limitsState = LimitsInitialState();
tradeState = ExchangeTradeStateInitial();
_cryptoNumberFormat = NumberFormat()..maximumFractionDigits = 12;
@ -308,8 +309,10 @@ abstract class ExchangeViewModelBase with Store {
isReceiveAmountEntered = false;
depositAmount = '';
receiveAmount = '';
depositAddress = depositCurrency == wallet.currency ? wallet.address : '';
receiveAddress = receiveCurrency == wallet.currency ? wallet.address : '';
depositAddress = depositCurrency == wallet.currency
? wallet.walletAddresses.address : '';
receiveAddress = receiveCurrency == wallet.currency
? wallet.walletAddresses.address : '';
isDepositAddressEnabled = !(depositCurrency == wallet.currency);
isReceiveAddressEnabled = !(receiveCurrency == wallet.currency);
isFixedRateMode = false;

View file

@ -20,15 +20,16 @@ abstract class MoneroAccountListViewModelBase with Store {
}
@computed
List<AccountListItem> get accounts => _moneroWallet.accountList.accounts
.map((acc) => AccountListItem(
List<AccountListItem> get accounts => _moneroWallet.walletAddresses
.accountList.accounts.map((acc) => AccountListItem(
label: acc.label,
id: acc.id,
isSelected: acc.id == _moneroWallet.account.id))
isSelected: acc.id == _moneroWallet.walletAddresses.account.id))
.toList();
final MoneroWallet _moneroWallet;
void select(AccountListItem item) =>
_moneroWallet.account = Account(id: item.id, label: item.label);
_moneroWallet.walletAddresses.account =
Account(id: item.id, label: item.label);
}

View file

@ -64,12 +64,15 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
final wallet = _wallet;
if (wallet is ElectrumWallet) {
await wallet.generateNewAddress();
await wallet.walletAddresses.generateNewAddress();
await wallet.save();
}
if (wallet is MoneroWallet) {
await wallet.subaddressList
.addSubaddress(accountIndex: wallet.account.id, label: label);
await wallet.walletAddresses.subaddressList
.addSubaddress(
accountIndex: wallet.walletAddresses.account.id,
label: label);
await wallet.save();
}
}
@ -77,13 +80,14 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
Future<void> _update() async {
final wallet = _wallet;
if (wallet is BitcoinWallet) {
await wallet.updateAddress(_item.address as String);
}
/*if (wallet is BitcoinWallet) {
await wallet.walletAddresses.updateAddress(_item.address as String);
await wallet.save();
}*/
if (wallet is MoneroWallet) {
await wallet.subaddressList.setLabelSubaddress(
accountIndex: wallet.account.id,
await wallet.walletAddresses.subaddressList.setLabelSubaddress(
accountIndex: wallet.walletAddresses.account.id,
addressIndex: _item.id as int,
label: label);
await wallet.save();

View file

@ -80,7 +80,7 @@ abstract class WalletAddressListViewModelBase with Store {
@computed
WalletAddressListItem get address =>
WalletAddressListItem(address: _wallet.address);
WalletAddressListItem(address: _wallet.walletAddresses.address);
@computed
PaymentURI get uri {
@ -105,8 +105,10 @@ abstract class WalletAddressListViewModelBase with Store {
final addressList = ObservableList<ListItem>();
if (wallet is MoneroWallet) {
final primaryAddress = wallet.subaddressList.subaddresses.first;
addressList.addAll(wallet.subaddressList.subaddresses.map((subaddress) {
final primaryAddress =
wallet.walletAddresses.subaddressList.subaddresses.first;
addressList.addAll(wallet.walletAddresses.subaddressList.subaddresses
.map((subaddress) {
final isPrimary = subaddress == primaryAddress;
return WalletAddressListItem(
@ -118,8 +120,8 @@ abstract class WalletAddressListViewModelBase with Store {
}
if (wallet is BitcoinWallet) {
final primaryAddress = wallet.addresses.first;
final bitcoinAddresses = wallet.addresses.map((addr) {
final primaryAddress = wallet.walletAddresses.addresses.first;
final bitcoinAddresses = wallet.walletAddresses.addresses.map((addr) {
final isPrimary = addr == primaryAddress;
return WalletAddressListItem(
@ -139,7 +141,7 @@ abstract class WalletAddressListViewModelBase with Store {
final wallet = _wallet;
if (wallet is MoneroWallet) {
return wallet.account.label;
return wallet.walletAddresses.account.label;
}
return null;
@ -160,7 +162,7 @@ abstract class WalletAddressListViewModelBase with Store {
@action
void setAddress(WalletAddressListItem address) =>
_wallet.address = address.address;
_wallet.walletAddresses.address = address.address;
void _init() {
_baseItems = [];
@ -177,7 +179,8 @@ abstract class WalletAddressListViewModelBase with Store {
final wallet = _wallet;
if (wallet is ElectrumWallet) {
wallet.nextAddress();
wallet.walletAddresses.nextAddress();
wallet.save();
}
}
}

View file

@ -50,7 +50,7 @@ abstract class WalletCreationVMBase with Store {
dirPath: dirPath);
credentials.walletInfo = walletInfo;
final wallet = await process(credentials);
walletInfo.address = wallet.address;
walletInfo.address = wallet.walletAddresses.address;
await _walletInfoSource.add(walletInfo);
_appStore.changeCurrentWallet(wallet);
_appStore.authenticationStore.allowed();