mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-11-18 02:07:37 +00:00
Merge pull request #157 from cake-tech/CAKE-343-subaddresses-for-contact-book
CAKE-343 | applied subaddresses for contact book; added addresses fie…
This commit is contained in:
commit
e0db3dedcb
26 changed files with 481 additions and 238 deletions
|
@ -1,12 +1,12 @@
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
|
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_snapshot.dart';
|
||||||
import 'package:cake_wallet/bitcoin/electrum_wallet.dart';
|
import 'package:cake_wallet/bitcoin/electrum_wallet.dart';
|
||||||
import 'package:cake_wallet/entities/wallet_info.dart';
|
import 'package:cake_wallet/entities/wallet_info.dart';
|
||||||
import 'package:cake_wallet/bitcoin/bitcoin_address_record.dart';
|
import 'package:cake_wallet/bitcoin/bitcoin_address_record.dart';
|
||||||
import 'package:cake_wallet/bitcoin/electrum_balance.dart';
|
import 'package:cake_wallet/bitcoin/electrum_balance.dart';
|
||||||
|
import 'package:cake_wallet/bitcoin/bitcoin_wallet_addresses.dart';
|
||||||
|
|
||||||
part 'bitcoin_wallet.g.dart';
|
part 'bitcoin_wallet.g.dart';
|
||||||
|
|
||||||
|
@ -26,8 +26,14 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
||||||
walletInfo: walletInfo,
|
walletInfo: walletInfo,
|
||||||
networkType: bitcoin.bitcoin,
|
networkType: bitcoin.bitcoin,
|
||||||
initialAddresses: initialAddresses,
|
initialAddresses: initialAddresses,
|
||||||
initialBalance: initialBalance,
|
initialBalance: initialBalance) {
|
||||||
accountIndex: accountIndex);
|
walletAddresses = BitcoinWalletAddresses(
|
||||||
|
walletInfo,
|
||||||
|
initialAddresses: initialAddresses,
|
||||||
|
accountIndex: accountIndex,
|
||||||
|
hd: hd,
|
||||||
|
networkType: networkType);
|
||||||
|
}
|
||||||
|
|
||||||
static Future<BitcoinWallet> open({
|
static Future<BitcoinWallet> open({
|
||||||
@required String name,
|
@required String name,
|
||||||
|
@ -44,8 +50,4 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
||||||
initialBalance: snp.balance,
|
initialBalance: snp.balance,
|
||||||
accountIndex: snp.accountIndex);
|
accountIndex: snp.accountIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
String getAddress({@required int index, @required bitcoin.HDWallet hd}) =>
|
|
||||||
generateP2WPKHAddress(hd: hd, index: index, networkType: networkType);
|
|
||||||
}
|
}
|
||||||
|
|
33
lib/bitcoin/bitcoin_wallet_addresses.dart
Normal file
33
lib/bitcoin/bitcoin_wallet_addresses.dart
Normal 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);
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
import 'package:cake_wallet/bitcoin/electrum_wallet_addresses.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:rxdart/subjects.dart';
|
import 'package:rxdart/subjects.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
@ -42,18 +43,14 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
||||||
@required this.networkType,
|
@required this.networkType,
|
||||||
@required this.mnemonic,
|
@required this.mnemonic,
|
||||||
ElectrumClient electrumClient,
|
ElectrumClient electrumClient,
|
||||||
int accountIndex = 0,
|
|
||||||
ElectrumBalance initialBalance})
|
ElectrumBalance initialBalance})
|
||||||
: balance = initialBalance ??
|
: balance = initialBalance ??
|
||||||
const ElectrumBalance(confirmed: 0, unconfirmed: 0),
|
const ElectrumBalance(confirmed: 0, unconfirmed: 0),
|
||||||
hd = bitcoin.HDWallet.fromSeed(mnemonicToSeedBytes(mnemonic),
|
hd = bitcoin.HDWallet.fromSeed(mnemonicToSeedBytes(mnemonic),
|
||||||
network: networkType)
|
network: networkType)
|
||||||
.derivePath("m/0'/0"),
|
.derivePath("m/0'/0"),
|
||||||
addresses = ObservableList<BitcoinAddressRecord>.of(
|
|
||||||
(initialAddresses ?? []).toSet()),
|
|
||||||
syncStatus = NotConnectedSyncStatus(),
|
syncStatus = NotConnectedSyncStatus(),
|
||||||
_password = password,
|
_password = password,
|
||||||
_accountIndex = accountIndex,
|
|
||||||
_feeRates = <int>[],
|
_feeRates = <int>[],
|
||||||
_isTransactionUpdating = false,
|
_isTransactionUpdating = false,
|
||||||
super(walletInfo) {
|
super(walletInfo) {
|
||||||
|
@ -74,8 +71,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
||||||
ElectrumClient electrumClient;
|
ElectrumClient electrumClient;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@observable
|
ElectrumWalletAddresses walletAddresses;
|
||||||
String address;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@observable
|
@observable
|
||||||
|
@ -85,9 +81,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
||||||
@observable
|
@observable
|
||||||
SyncStatus syncStatus;
|
SyncStatus syncStatus;
|
||||||
|
|
||||||
ObservableList<BitcoinAddressRecord> addresses;
|
List<String> get scriptHashes => walletAddresses.addresses
|
||||||
|
|
||||||
List<String> get scriptHashes => addresses
|
|
||||||
.map((addr) => scriptHash(addr.address, networkType: networkType))
|
.map((addr) => scriptHash(addr.address, networkType: networkType))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
|
@ -105,80 +99,21 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
||||||
final String _password;
|
final String _password;
|
||||||
List<BitcoinUnspent> _unspent;
|
List<BitcoinUnspent> _unspent;
|
||||||
List<int> _feeRates;
|
List<int> _feeRates;
|
||||||
int _accountIndex;
|
|
||||||
Map<String, BehaviorSubject<Object>> _scripthashesUpdateSubject;
|
Map<String, BehaviorSubject<Object>> _scripthashesUpdateSubject;
|
||||||
bool _isTransactionUpdating;
|
bool _isTransactionUpdating;
|
||||||
|
|
||||||
Future<void> init() async {
|
Future<void> init() async {
|
||||||
await generateAddresses();
|
await walletAddresses.init();
|
||||||
address = addresses[_accountIndex].address;
|
|
||||||
await transactionHistory.init();
|
await transactionHistory.init();
|
||||||
}
|
|
||||||
|
|
||||||
@action
|
|
||||||
Future<void> nextAddress() async {
|
|
||||||
_accountIndex += 1;
|
|
||||||
|
|
||||||
if (_accountIndex >= addresses.length) {
|
|
||||||
_accountIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
address = addresses[_accountIndex].address;
|
|
||||||
|
|
||||||
await save();
|
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
|
@action
|
||||||
@override
|
@override
|
||||||
Future<void> startSync() async {
|
Future<void> startSync() async {
|
||||||
try {
|
try {
|
||||||
syncStatus = StartingSyncStatus();
|
syncStatus = StartingSyncStatus();
|
||||||
updateTransactions();
|
await updateTransactions();
|
||||||
_subscribeForUpdates();
|
_subscribeForUpdates();
|
||||||
await _updateBalance();
|
await _updateBalance();
|
||||||
await _updateUnspent();
|
await _updateUnspent();
|
||||||
|
@ -230,7 +165,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
||||||
? allAmount
|
? allAmount
|
||||||
: credentialsAmount;
|
: credentialsAmount;
|
||||||
final txb = bitcoin.TransactionBuilder(network: networkType);
|
final txb = bitcoin.TransactionBuilder(network: networkType);
|
||||||
final changeAddress = address;
|
final changeAddress = walletAddresses.address;
|
||||||
var leftAmount = amount;
|
var leftAmount = amount;
|
||||||
var totalInputAmount = 0;
|
var totalInputAmount = 0;
|
||||||
|
|
||||||
|
@ -313,8 +248,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
||||||
|
|
||||||
String toJSON() => json.encode({
|
String toJSON() => json.encode({
|
||||||
'mnemonic': mnemonic,
|
'mnemonic': mnemonic,
|
||||||
'account_index': _accountIndex.toString(),
|
'account_index': walletAddresses.accountIndex.toString(),
|
||||||
'addresses': addresses.map((addr) => addr.toJSON()).toList(),
|
'addresses': walletAddresses.addresses.map((addr) => addr.toJSON()).toList(),
|
||||||
'balance': balance?.toJSON()
|
'balance': balance?.toJSON()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -377,13 +312,12 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
String getAddress({@required int index, @required bitcoin.HDWallet hd}) => '';
|
|
||||||
|
|
||||||
Future<String> makePath() async =>
|
Future<String> makePath() async =>
|
||||||
pathForWallet(name: walletInfo.name, type: walletInfo.type);
|
pathForWallet(name: walletInfo.name, type: walletInfo.type);
|
||||||
|
|
||||||
Future<void> _updateUnspent() async {
|
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)
|
.getListUnspentWithAddress(address.address, networkType)
|
||||||
.then((unspent) => unspent
|
.then((unspent) => unspent
|
||||||
.map((unspent) => BitcoinUnspent.fromJSON(address, unspent)))));
|
.map((unspent) => BitcoinUnspent.fromJSON(address, unspent)))));
|
||||||
|
@ -394,7 +328,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
||||||
{@required String hash, @required int height}) async {
|
{@required String hash, @required int height}) async {
|
||||||
final tx = await electrumClient.getTransactionExpanded(hash: hash);
|
final tx = await electrumClient.getTransactionExpanded(hash: hash);
|
||||||
return ElectrumTransactionInfo.fromElectrumVerbose(tx, walletInfo.type,
|
return ElectrumTransactionInfo.fromElectrumVerbose(tx, walletInfo.type,
|
||||||
height: height, addresses: addresses);
|
height: height, addresses: walletAddresses.addresses);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
111
lib/bitcoin/electrum_wallet_addresses.dart
Normal file
111
lib/bitcoin/electrum_wallet_addresses.dart
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
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_info.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:mobx/mobx.dart';
|
||||||
|
|
||||||
|
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
|
||||||
|
@observable
|
||||||
|
String address;
|
||||||
|
|
||||||
|
bitcoin.HDWallet hd;
|
||||||
|
|
||||||
|
ObservableList<BitcoinAddressRecord> addresses;
|
||||||
|
|
||||||
|
int accountIndex;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> init() async {
|
||||||
|
await generateAddresses();
|
||||||
|
address = addresses[accountIndex].address;
|
||||||
|
await updateAddressesInBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
Future<void> nextAddress() async {
|
||||||
|
accountIndex += 1;
|
||||||
|
|
||||||
|
if (accountIndex >= addresses.length) {
|
||||||
|
accountIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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/bitcoin_transaction_priority.dart';
|
||||||
|
import 'package:cake_wallet/bitcoin/litecoin_wallet_addresses.dart';
|
||||||
import 'package:cake_wallet/entities/transaction_priority.dart';
|
import 'package:cake_wallet/entities/transaction_priority.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:mobx/mobx.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/bitcoin_address_record.dart';
|
||||||
import 'package:cake_wallet/bitcoin/electrum_balance.dart';
|
import 'package:cake_wallet/bitcoin/electrum_balance.dart';
|
||||||
import 'package:cake_wallet/bitcoin/litecoin_network.dart';
|
import 'package:cake_wallet/bitcoin/litecoin_network.dart';
|
||||||
import 'package:cake_wallet/bitcoin/utils.dart';
|
|
||||||
|
|
||||||
part 'litecoin_wallet.g.dart';
|
part 'litecoin_wallet.g.dart';
|
||||||
|
|
||||||
|
@ -30,8 +28,15 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
walletInfo: walletInfo,
|
walletInfo: walletInfo,
|
||||||
networkType: litecoinNetwork,
|
networkType: litecoinNetwork,
|
||||||
initialAddresses: initialAddresses,
|
initialAddresses: initialAddresses,
|
||||||
initialBalance: initialBalance,
|
initialBalance: initialBalance) {
|
||||||
accountIndex: accountIndex);
|
walletAddresses = LitecoinWalletAddresses(
|
||||||
|
walletInfo,
|
||||||
|
initialAddresses: initialAddresses,
|
||||||
|
accountIndex: accountIndex,
|
||||||
|
hd: hd,
|
||||||
|
networkType: networkType,
|
||||||
|
mnemonic: mnemonic);
|
||||||
|
}
|
||||||
|
|
||||||
static Future<LitecoinWallet> open({
|
static Future<LitecoinWallet> open({
|
||||||
@required String name,
|
@required String name,
|
||||||
|
@ -49,27 +54,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
accountIndex: snp.accountIndex);
|
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
|
@override
|
||||||
int feeRate(TransactionPriority priority) {
|
int feeRate(TransactionPriority priority) {
|
||||||
if (priority is LitecoinTransactionPriority) {
|
if (priority is LitecoinTransactionPriority) {
|
||||||
|
|
54
lib/bitcoin/litecoin_wallet_addresses.dart
Normal file
54
lib/bitcoin/litecoin_wallet_addresses.dart
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,7 +15,7 @@ abstract class BuyProvider {
|
||||||
String get trackUrl;
|
String get trackUrl;
|
||||||
|
|
||||||
WalletType get walletType => wallet.type;
|
WalletType get walletType => wallet.type;
|
||||||
String get walletAddress => wallet.address;
|
String get walletAddress => wallet.walletAddresses.address;
|
||||||
String get walletId => wallet.id;
|
String get walletId => wallet.id;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import 'package:cake_wallet/entities/balance.dart';
|
import 'package:cake_wallet/entities/balance.dart';
|
||||||
import 'package:cake_wallet/entities/transaction_info.dart';
|
import 'package:cake_wallet/entities/transaction_info.dart';
|
||||||
import 'package:cake_wallet/entities/transaction_priority.dart';
|
import 'package:cake_wallet/entities/transaction_priority.dart';
|
||||||
|
import 'package:cake_wallet/entities/wallet_addresses.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:cake_wallet/entities/wallet_info.dart';
|
import 'package:cake_wallet/entities/wallet_info.dart';
|
||||||
import 'package:cake_wallet/core/pending_transaction.dart';
|
import 'package:cake_wallet/core/pending_transaction.dart';
|
||||||
import 'package:cake_wallet/core/transaction_history.dart';
|
import 'package:cake_wallet/core/transaction_history.dart';
|
||||||
import 'package:cake_wallet/entities/currency_for_wallet_type.dart';
|
import 'package:cake_wallet/entities/currency_for_wallet_type.dart';
|
||||||
import 'package:cake_wallet/entities/monero_transaction_priority.dart';
|
|
||||||
import 'package:cake_wallet/entities/crypto_currency.dart';
|
import 'package:cake_wallet/entities/crypto_currency.dart';
|
||||||
import 'package:cake_wallet/entities/sync_status.dart';
|
import 'package:cake_wallet/entities/sync_status.dart';
|
||||||
import 'package:cake_wallet/entities/node.dart';
|
import 'package:cake_wallet/entities/node.dart';
|
||||||
|
@ -31,9 +31,9 @@ abstract class WalletBase<
|
||||||
|
|
||||||
String get name => walletInfo.name;
|
String get name => walletInfo.name;
|
||||||
|
|
||||||
String get address;
|
//String get address;
|
||||||
|
|
||||||
set address(String address);
|
//set address(String address);
|
||||||
|
|
||||||
BalanceType get balance;
|
BalanceType get balance;
|
||||||
|
|
||||||
|
@ -45,6 +45,8 @@ abstract class WalletBase<
|
||||||
|
|
||||||
Object get keys;
|
Object get keys;
|
||||||
|
|
||||||
|
WalletAddresses get walletAddresses;
|
||||||
|
|
||||||
HistoryType transactionHistory;
|
HistoryType transactionHistory;
|
||||||
|
|
||||||
Future<void> connectToNode({@required Node node});
|
Future<void> connectToNode({@required Node node});
|
||||||
|
|
|
@ -361,7 +361,8 @@ Future setup(
|
||||||
getIt.registerFactoryParam<MoneroAccountEditOrCreateViewModel,
|
getIt.registerFactoryParam<MoneroAccountEditOrCreateViewModel,
|
||||||
AccountListItem, void>(
|
AccountListItem, void>(
|
||||||
(AccountListItem account, _) => MoneroAccountEditOrCreateViewModel(
|
(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));
|
accountListItem: account));
|
||||||
|
|
||||||
getIt.registerFactoryParam<MoneroAccountEditOrCreatePage, AccountListItem,
|
getIt.registerFactoryParam<MoneroAccountEditOrCreatePage, AccountListItem,
|
||||||
|
|
36
lib/entities/wallet_addresses.dart
Normal file
36
lib/entities/wallet_addresses.dart
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import 'package:cake_wallet/entities/wallet_info.dart';
|
||||||
|
|
||||||
|
abstract class WalletAddresses {
|
||||||
|
WalletAddresses(this.walletInfo) {
|
||||||
|
addressesMap = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
final WalletInfo walletInfo;
|
||||||
|
|
||||||
|
String get address;
|
||||||
|
|
||||||
|
set address(String address);
|
||||||
|
|
||||||
|
Map<String, String> addressesMap;
|
||||||
|
|
||||||
|
Future<void> init();
|
||||||
|
|
||||||
|
Future<void> updateAddressesInBox();
|
||||||
|
|
||||||
|
Future<void> saveAddressesInBox() async {
|
||||||
|
try {
|
||||||
|
if (walletInfo == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
walletInfo.address = address;
|
||||||
|
walletInfo.addresses = addressesMap;
|
||||||
|
|
||||||
|
if (walletInfo.isInBox) {
|
||||||
|
await walletInfo.save();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print(e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -53,5 +53,8 @@ class WalletInfo extends HiveObject {
|
||||||
@HiveField(8)
|
@HiveField(8)
|
||||||
String address;
|
String address;
|
||||||
|
|
||||||
|
@HiveField(10)
|
||||||
|
Map<String, String> addresses;
|
||||||
|
|
||||||
DateTime get date => DateTime.fromMillisecondsSinceEpoch(timestamp);
|
DateTime get date => DateTime.fromMillisecondsSinceEpoch(timestamp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'package:cake_wallet/entities/transaction_priority.dart';
|
||||||
import 'package:cake_wallet/monero/monero_amount_format.dart';
|
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_creation_exception.dart';
|
||||||
import 'package:cake_wallet/monero/monero_transaction_info.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_utils.dart';
|
import 'package:cake_wallet/monero/monero_wallet_utils.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
|
@ -16,10 +17,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_wallet_keys.dart';
|
||||||
import 'package:cake_wallet/monero/monero_balance.dart';
|
import 'package:cake_wallet/monero/monero_balance.dart';
|
||||||
import 'package:cake_wallet/monero/monero_transaction_history.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/account.dart';
|
||||||
import 'package:cake_wallet/monero/subaddress.dart';
|
|
||||||
import 'package:cake_wallet/core/pending_transaction.dart';
|
import 'package:cake_wallet/core/pending_transaction.dart';
|
||||||
import 'package:cake_wallet/core/wallet_base.dart';
|
import 'package:cake_wallet/core/wallet_base.dart';
|
||||||
import 'package:cake_wallet/entities/sync_status.dart';
|
import 'package:cake_wallet/entities/sync_status.dart';
|
||||||
|
@ -36,9 +34,7 @@ class MoneroWallet = MoneroWalletBase with _$MoneroWallet;
|
||||||
abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
MoneroTransactionHistory, MoneroTransactionInfo> with Store {
|
MoneroTransactionHistory, MoneroTransactionInfo> with Store {
|
||||||
MoneroWalletBase({WalletInfo walletInfo})
|
MoneroWalletBase({WalletInfo walletInfo})
|
||||||
: accountList = MoneroAccountList(),
|
: super(walletInfo) {
|
||||||
subaddressList = MoneroSubaddressList(),
|
|
||||||
super(walletInfo) {
|
|
||||||
transactionHistory = MoneroTransactionHistory();
|
transactionHistory = MoneroTransactionHistory();
|
||||||
balance = MoneroBalance(
|
balance = MoneroBalance(
|
||||||
fullBalance: monero_wallet.getFullBalance(accountIndex: 0),
|
fullBalance: monero_wallet.getFullBalance(accountIndex: 0),
|
||||||
|
@ -48,33 +44,26 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
_isSavingAfterSync = false;
|
_isSavingAfterSync = false;
|
||||||
_isSavingAfterNewTransaction = false;
|
_isSavingAfterNewTransaction = false;
|
||||||
_isTransactionUpdating = false;
|
_isTransactionUpdating = false;
|
||||||
_onAccountChangeReaction = reaction((_) => account, (Account account) {
|
walletAddresses = MoneroWalletAddresses(walletInfo);
|
||||||
|
_onAccountChangeReaction = reaction((_) => walletAddresses.account,
|
||||||
|
(Account account) {
|
||||||
balance = MoneroBalance(
|
balance = MoneroBalance(
|
||||||
fullBalance: monero_wallet.getFullBalance(accountIndex: account.id),
|
fullBalance: monero_wallet.getFullBalance(accountIndex: account.id),
|
||||||
unlockedBalance:
|
unlockedBalance:
|
||||||
monero_wallet.getUnlockedBalance(accountIndex: account.id));
|
monero_wallet.getUnlockedBalance(accountIndex: account.id));
|
||||||
subaddressList.update(accountIndex: account.id);
|
walletAddresses.updateSubaddressList(accountIndex: account.id);
|
||||||
subaddress = subaddressList.subaddresses.first;
|
|
||||||
address = subaddress.address;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static const int _autoAfterSyncSaveInterval = 60000;
|
static const int _autoAfterSyncSaveInterval = 60000;
|
||||||
|
|
||||||
@observable
|
@override
|
||||||
Account account;
|
MoneroWalletAddresses walletAddresses;
|
||||||
|
|
||||||
@observable
|
|
||||||
Subaddress subaddress;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@observable
|
@observable
|
||||||
SyncStatus syncStatus;
|
SyncStatus syncStatus;
|
||||||
|
|
||||||
@override
|
|
||||||
@observable
|
|
||||||
String address;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@observable
|
@observable
|
||||||
MoneroBalance balance;
|
MoneroBalance balance;
|
||||||
|
@ -89,10 +78,6 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
publicSpendKey: monero_wallet.getPublicSpendKey(),
|
publicSpendKey: monero_wallet.getPublicSpendKey(),
|
||||||
publicViewKey: monero_wallet.getPublicViewKey());
|
publicViewKey: monero_wallet.getPublicViewKey());
|
||||||
|
|
||||||
final MoneroSubaddressList subaddressList;
|
|
||||||
|
|
||||||
final MoneroAccountList accountList;
|
|
||||||
|
|
||||||
SyncListener _listener;
|
SyncListener _listener;
|
||||||
ReactionDisposer _onAccountChangeReaction;
|
ReactionDisposer _onAccountChangeReaction;
|
||||||
int _lastAutosaveTimestamp;
|
int _lastAutosaveTimestamp;
|
||||||
|
@ -102,15 +87,11 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
int _lastSaveTimestamp;
|
int _lastSaveTimestamp;
|
||||||
|
|
||||||
Future<void> init() async {
|
Future<void> init() async {
|
||||||
accountList.update();
|
await walletAddresses.init();
|
||||||
account = accountList.accounts.first;
|
|
||||||
subaddressList.update(accountIndex: account.id ?? 0);
|
|
||||||
subaddress = subaddressList.getAll().first;
|
|
||||||
balance = MoneroBalance(
|
balance = MoneroBalance(
|
||||||
fullBalance: monero_wallet.getFullBalance(accountIndex: account.id),
|
fullBalance: monero_wallet.getFullBalance(accountIndex: walletAddresses.account.id),
|
||||||
unlockedBalance:
|
unlockedBalance:
|
||||||
monero_wallet.getUnlockedBalance(accountIndex: account.id));
|
monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account.id));
|
||||||
address = subaddress.address;
|
|
||||||
_setListeners();
|
_setListeners();
|
||||||
await updateTransactions();
|
await updateTransactions();
|
||||||
|
|
||||||
|
@ -130,24 +111,6 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
_onAccountChangeReaction?.reaction?.dispose();
|
_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
|
@override
|
||||||
Future<void> connectToNode({@required Node node}) async {
|
Future<void> connectToNode({@required Node node}) async {
|
||||||
try {
|
try {
|
||||||
|
@ -190,7 +153,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
? moneroParseAmount(amount: _credentials.amount)
|
? moneroParseAmount(amount: _credentials.amount)
|
||||||
: null;
|
: null;
|
||||||
final unlockedBalance =
|
final unlockedBalance =
|
||||||
monero_wallet.getUnlockedBalance(accountIndex: account.id);
|
monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account.id);
|
||||||
|
|
||||||
if ((amount != null && unlockedBalance < amount) ||
|
if ((amount != null && unlockedBalance < amount) ||
|
||||||
(amount == null && unlockedBalance <= 0)) {
|
(amount == null && unlockedBalance <= 0)) {
|
||||||
|
@ -210,7 +173,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
paymentId: _credentials.paymentId,
|
paymentId: _credentials.paymentId,
|
||||||
amount: _credentials.amount,
|
amount: _credentials.amount,
|
||||||
priorityRaw: _credentials.priority.serialize(),
|
priorityRaw: _credentials.priority.serialize(),
|
||||||
accountIndex: account.id);
|
accountIndex: walletAddresses.account.id);
|
||||||
|
|
||||||
return PendingMoneroTransaction(pendingTransactionDescription);
|
return PendingMoneroTransaction(pendingTransactionDescription);
|
||||||
}
|
}
|
||||||
|
@ -239,6 +202,8 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> save() async {
|
Future<void> save() async {
|
||||||
|
await walletAddresses.updateAddressesInBox();
|
||||||
|
|
||||||
final now = DateTime.now().millisecondsSinceEpoch;
|
final now = DateTime.now().millisecondsSinceEpoch;
|
||||||
|
|
||||||
if (now - _lastSaveTimestamp < Duration(seconds: 10).inMilliseconds) {
|
if (now - _lastSaveTimestamp < Duration(seconds: 10).inMilliseconds) {
|
||||||
|
@ -267,7 +232,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
monero_wallet.rescanBlockchainAsync();
|
monero_wallet.rescanBlockchainAsync();
|
||||||
await startSync();
|
await startSync();
|
||||||
_askForUpdateBalance();
|
_askForUpdateBalance();
|
||||||
accountList.update();
|
walletAddresses.accountList.update();
|
||||||
await _askForUpdateTransactionHistory();
|
await _askForUpdateTransactionHistory();
|
||||||
await save();
|
await save();
|
||||||
await walletInfo.save();
|
await walletInfo.save();
|
||||||
|
@ -366,10 +331,10 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
await updateTransactions();
|
await updateTransactions();
|
||||||
|
|
||||||
int _getFullBalance() =>
|
int _getFullBalance() =>
|
||||||
monero_wallet.getFullBalance(accountIndex: account.id);
|
monero_wallet.getFullBalance(accountIndex: walletAddresses.account.id);
|
||||||
|
|
||||||
int _getUnlockedBalance() =>
|
int _getUnlockedBalance() =>
|
||||||
monero_wallet.getUnlockedBalance(accountIndex: account.id);
|
monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account.id);
|
||||||
|
|
||||||
Future<void> _afterSyncSave() async {
|
Future<void> _afterSyncSave() async {
|
||||||
try {
|
try {
|
||||||
|
@ -416,13 +381,13 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
if (walletInfo.isRecovery) {
|
if (walletInfo.isRecovery) {
|
||||||
await _askForUpdateTransactionHistory();
|
await _askForUpdateTransactionHistory();
|
||||||
_askForUpdateBalance();
|
_askForUpdateBalance();
|
||||||
accountList.update();
|
walletAddresses.accountList.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blocksLeft < 100) {
|
if (blocksLeft < 100) {
|
||||||
await _askForUpdateTransactionHistory();
|
await _askForUpdateTransactionHistory();
|
||||||
_askForUpdateBalance();
|
_askForUpdateBalance();
|
||||||
accountList.update();
|
walletAddresses.accountList.update();
|
||||||
syncStatus = SyncedSyncStatus();
|
syncStatus = SyncedSyncStatus();
|
||||||
await _afterSyncSave();
|
await _afterSyncSave();
|
||||||
|
|
||||||
|
|
85
lib/monero/monero_wallet_addresses.dart
Normal file
85
lib/monero/monero_wallet_addresses.dart
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
import 'package:cake_wallet/entities/wallet_addresses.dart';
|
||||||
|
import 'package:cake_wallet/entities/wallet_info.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';
|
||||||
|
|
||||||
|
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
|
||||||
|
@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 {
|
||||||
|
final _subaddressList = MoneroSubaddressList();
|
||||||
|
|
||||||
|
addressesMap.clear();
|
||||||
|
|
||||||
|
accountList.accounts.forEach((account) {
|
||||||
|
_subaddressList.update(accountIndex: account.id);
|
||||||
|
_subaddressList.subaddresses.forEach((subaddress) {
|
||||||
|
addressesMap[subaddress.address] = subaddress.label;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -109,7 +109,7 @@ class MoneroWalletService extends WalletService<
|
||||||
(info) => info.id == WalletBase.idFor(name, getType()),
|
(info) => info.id == WalletBase.idFor(name, getType()),
|
||||||
orElse: () => null);
|
orElse: () => null);
|
||||||
final wallet = MoneroWallet(walletInfo: walletInfo);
|
final wallet = MoneroWallet(walletInfo: walletInfo);
|
||||||
final isValid = wallet.validate();
|
final isValid = wallet.walletAddresses.validate();
|
||||||
|
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
await restoreOrResetWalletFiles(name);
|
await restoreOrResetWalletFiles(name);
|
||||||
|
|
|
@ -37,7 +37,7 @@ void startCurrentWalletChangeReaction(AppStore appStore,
|
||||||
await wallet.connectToNode(node: node);
|
await wallet.connectToNode(node: node);
|
||||||
|
|
||||||
if (wallet.walletInfo.address?.isEmpty ?? true) {
|
if (wallet.walletInfo.address?.isEmpty ?? true) {
|
||||||
wallet.walletInfo.address = wallet.address;
|
wallet.walletInfo.address = wallet.walletAddresses.address;
|
||||||
|
|
||||||
if (wallet.walletInfo.isInBox) {
|
if (wallet.walletInfo.isInBox) {
|
||||||
await wallet.walletInfo.save();
|
await wallet.walletInfo.save();
|
||||||
|
|
|
@ -151,7 +151,8 @@ class ContactListPage extends BasePage {
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
image ?? Offstage(),
|
image ?? Offstage(),
|
||||||
Padding(
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
padding: image != null
|
padding: image != null
|
||||||
? EdgeInsets.only(left: 12)
|
? EdgeInsets.only(left: 12)
|
||||||
: EdgeInsets.only(left: 0),
|
: EdgeInsets.only(left: 0),
|
||||||
|
@ -163,6 +164,7 @@ class ContactListPage extends BasePage {
|
||||||
color: Theme.of(context).primaryTextTheme.title.color),
|
color: Theme.of(context).primaryTextTheme.title.color),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -179,7 +179,7 @@ class ExchangePage extends BasePage {
|
||||||
initialAddress:
|
initialAddress:
|
||||||
exchangeViewModel.depositCurrency ==
|
exchangeViewModel.depositCurrency ==
|
||||||
exchangeViewModel.wallet.currency
|
exchangeViewModel.wallet.currency
|
||||||
? exchangeViewModel.wallet.address
|
? exchangeViewModel.wallet.walletAddresses.address
|
||||||
: exchangeViewModel.depositAddress,
|
: exchangeViewModel.depositAddress,
|
||||||
initialIsAmountEditable: true,
|
initialIsAmountEditable: true,
|
||||||
initialIsAddressEditable:
|
initialIsAddressEditable:
|
||||||
|
@ -240,7 +240,7 @@ class ExchangePage extends BasePage {
|
||||||
initialAddress: exchangeViewModel
|
initialAddress: exchangeViewModel
|
||||||
.receiveCurrency ==
|
.receiveCurrency ==
|
||||||
exchangeViewModel.wallet.currency
|
exchangeViewModel.wallet.currency
|
||||||
? exchangeViewModel.wallet.address
|
? exchangeViewModel.wallet.walletAddresses.address
|
||||||
: exchangeViewModel.receiveAddress,
|
: exchangeViewModel.receiveAddress,
|
||||||
initialIsAmountEditable: exchangeViewModel
|
initialIsAmountEditable: exchangeViewModel
|
||||||
.isReceiveAmountEditable,
|
.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) {
|
if (exchangeViewModel.depositCurrency == CryptoCurrency.xmr) {
|
||||||
depositKey.currentState.changeAddress(address: address);
|
depositKey.currentState.changeAddress(address: address);
|
||||||
}
|
}
|
||||||
|
@ -707,7 +708,8 @@ class ExchangePage extends BasePage {
|
||||||
isCurrentTypeWallet ? exchangeViewModel.wallet.name : null);
|
isCurrentTypeWallet ? exchangeViewModel.wallet.name : null);
|
||||||
|
|
||||||
key.currentState.changeAddress(
|
key.currentState.changeAddress(
|
||||||
address: isCurrentTypeWallet ? exchangeViewModel.wallet.address : '');
|
address: isCurrentTypeWallet
|
||||||
|
? exchangeViewModel.wallet.walletAddresses.address : '');
|
||||||
|
|
||||||
key.currentState.changeAmount(amount: '');
|
key.currentState.changeAmount(amount: '');
|
||||||
}
|
}
|
||||||
|
@ -719,9 +721,9 @@ class ExchangePage extends BasePage {
|
||||||
if (isCurrentTypeWallet) {
|
if (isCurrentTypeWallet) {
|
||||||
key.currentState.changeWalletName(exchangeViewModel.wallet.name);
|
key.currentState.changeWalletName(exchangeViewModel.wallet.name);
|
||||||
key.currentState.addressController.text =
|
key.currentState.addressController.text =
|
||||||
exchangeViewModel.wallet.address;
|
exchangeViewModel.wallet.walletAddresses.address;
|
||||||
} else if (key.currentState.addressController.text ==
|
} else if (key.currentState.addressController.text ==
|
||||||
exchangeViewModel.wallet.address) {
|
exchangeViewModel.wallet.walletAddresses.address) {
|
||||||
key.currentState.changeWalletName(null);
|
key.currentState.changeWalletName(null);
|
||||||
key.currentState.addressController.text = null;
|
key.currentState.addressController.text = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,7 +129,7 @@ class ExchangeTemplatePage extends BasePage {
|
||||||
initialAddress: exchangeViewModel
|
initialAddress: exchangeViewModel
|
||||||
.depositCurrency ==
|
.depositCurrency ==
|
||||||
exchangeViewModel.wallet.currency
|
exchangeViewModel.wallet.currency
|
||||||
? exchangeViewModel.wallet.address
|
? exchangeViewModel.wallet.walletAddresses.address
|
||||||
: exchangeViewModel.depositAddress,
|
: exchangeViewModel.depositAddress,
|
||||||
initialIsAmountEditable: true,
|
initialIsAmountEditable: true,
|
||||||
initialIsAddressEditable: exchangeViewModel
|
initialIsAddressEditable: exchangeViewModel
|
||||||
|
@ -168,7 +168,7 @@ class ExchangeTemplatePage extends BasePage {
|
||||||
initialAddress:
|
initialAddress:
|
||||||
exchangeViewModel.receiveCurrency ==
|
exchangeViewModel.receiveCurrency ==
|
||||||
exchangeViewModel.wallet.currency
|
exchangeViewModel.wallet.currency
|
||||||
? exchangeViewModel.wallet.address
|
? exchangeViewModel.wallet.walletAddresses.address
|
||||||
: exchangeViewModel.receiveAddress,
|
: exchangeViewModel.receiveAddress,
|
||||||
initialIsAmountEditable:
|
initialIsAmountEditable:
|
||||||
exchangeViewModel.provider is
|
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) {
|
if (exchangeViewModel.depositCurrency == CryptoCurrency.xmr) {
|
||||||
depositKey.currentState.changeAddress(address: address);
|
depositKey.currentState.changeAddress(address: address);
|
||||||
}
|
}
|
||||||
|
@ -405,7 +406,8 @@ class ExchangeTemplatePage extends BasePage {
|
||||||
isCurrentTypeWallet ? exchangeViewModel.wallet.name : null);
|
isCurrentTypeWallet ? exchangeViewModel.wallet.name : null);
|
||||||
|
|
||||||
key.currentState.changeAddress(
|
key.currentState.changeAddress(
|
||||||
address: isCurrentTypeWallet ? exchangeViewModel.wallet.address : '');
|
address: isCurrentTypeWallet
|
||||||
|
? exchangeViewModel.wallet.walletAddresses.address : '');
|
||||||
|
|
||||||
key.currentState.changeAmount(amount: '');
|
key.currentState.changeAmount(amount: '');
|
||||||
}
|
}
|
||||||
|
@ -417,9 +419,9 @@ class ExchangeTemplatePage extends BasePage {
|
||||||
if (isCurrentTypeWallet) {
|
if (isCurrentTypeWallet) {
|
||||||
key.currentState.changeWalletName(exchangeViewModel.wallet.name);
|
key.currentState.changeWalletName(exchangeViewModel.wallet.name);
|
||||||
key.currentState.addressController.text =
|
key.currentState.addressController.text =
|
||||||
exchangeViewModel.wallet.address;
|
exchangeViewModel.wallet.walletAddresses.address;
|
||||||
} else if (key.currentState.addressController.text ==
|
} else if (key.currentState.addressController.text ==
|
||||||
exchangeViewModel.wallet.address) {
|
exchangeViewModel.wallet.walletAddresses.address) {
|
||||||
key.currentState.changeWalletName(null);
|
key.currentState.changeWalletName(null);
|
||||||
key.currentState.addressController.text = null;
|
key.currentState.addressController.text = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,22 @@ class ContactListViewModel = ContactListViewModelBase
|
||||||
abstract class ContactListViewModelBase with Store {
|
abstract class ContactListViewModelBase with Store {
|
||||||
ContactListViewModelBase(this.contactSource, this.walletInfoSource)
|
ContactListViewModelBase(this.contactSource, this.walletInfoSource)
|
||||||
: contacts = ObservableList<ContactRecord>(),
|
: contacts = ObservableList<ContactRecord>(),
|
||||||
walletContacts = walletInfoSource.values
|
walletContacts = [] {
|
||||||
.where((info) => info.address?.isNotEmpty ?? false)
|
walletInfoSource.values.forEach((info) {
|
||||||
.map((info) => WalletContact(
|
if (info.addresses?.isNotEmpty ?? false) {
|
||||||
info.address, info.name, walletTypeToCryptoCurrency(info.type)))
|
info.addresses?.forEach((address, label) {
|
||||||
.toList() {
|
final name = label.isNotEmpty
|
||||||
|
? info.name + ' ($label)'
|
||||||
|
: info.name;
|
||||||
|
|
||||||
|
walletContacts.add(WalletContact(
|
||||||
|
address,
|
||||||
|
name,
|
||||||
|
walletTypeToCryptoCurrency(info.type)));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
_subscription = contactSource.bindToListWithTransform(
|
_subscription = contactSource.bindToListWithTransform(
|
||||||
contacts, (Contact contact) => ContactRecord(contactSource, contact),
|
contacts, (Contact contact) => ContactRecord(contactSource, contact),
|
||||||
initialFire: true);
|
initialFire: true);
|
||||||
|
|
|
@ -92,17 +92,17 @@ abstract class DashboardViewModelBase with Store {
|
||||||
final _wallet = wallet;
|
final _wallet = wallet;
|
||||||
|
|
||||||
if (_wallet is MoneroWallet) {
|
if (_wallet is MoneroWallet) {
|
||||||
subname = _wallet.account?.label;
|
subname = _wallet.walletAddresses.account?.label;
|
||||||
|
|
||||||
_onMoneroAccountChangeReaction = reaction((_) => _wallet.account,
|
_onMoneroAccountChangeReaction = reaction((_) => _wallet.walletAddresses
|
||||||
(Account account) => _onMoneroAccountChange(_wallet));
|
.account, (Account account) => _onMoneroAccountChange(_wallet));
|
||||||
|
|
||||||
_onMoneroBalanceChangeReaction = reaction((_) => _wallet.balance,
|
_onMoneroBalanceChangeReaction = reaction((_) => _wallet.balance,
|
||||||
(MoneroBalance balance) => _onMoneroTransactionsUpdate(_wallet));
|
(MoneroBalance balance) => _onMoneroTransactionsUpdate(_wallet));
|
||||||
|
|
||||||
final _accountTransactions = _wallet
|
final _accountTransactions = _wallet
|
||||||
.transactionHistory.transactions.values
|
.transactionHistory.transactions.values
|
||||||
.where((tx) => tx.accountIndex == _wallet.account.id)
|
.where((tx) => tx.accountIndex == _wallet.walletAddresses.account.id)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
transactions = ObservableList.of(_accountTransactions.map((transaction) =>
|
transactions = ObservableList.of(_accountTransactions.map((transaction) =>
|
||||||
|
@ -131,7 +131,7 @@ abstract class DashboardViewModelBase with Store {
|
||||||
filter: (TransactionInfo tx) {
|
filter: (TransactionInfo tx) {
|
||||||
final wallet = _wallet;
|
final wallet = _wallet;
|
||||||
if (tx is MoneroTransactionInfo && wallet is MoneroWallet) {
|
if (tx is MoneroTransactionInfo && wallet is MoneroWallet) {
|
||||||
return tx.accountIndex == wallet.account.id;
|
return tx.accountIndex == wallet.walletAddresses.account.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -153,7 +153,7 @@ abstract class DashboardViewModelBase with Store {
|
||||||
String subname;
|
String subname;
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
String get address => wallet.address;
|
String get address => wallet.walletAddresses.address;
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
SyncStatus get status => wallet.syncStatus;
|
SyncStatus get status => wallet.syncStatus;
|
||||||
|
@ -251,13 +251,13 @@ abstract class DashboardViewModelBase with Store {
|
||||||
wallet.type == WalletType.bitcoin && wallet.seed.split(' ').length < 24;
|
wallet.type == WalletType.bitcoin && wallet.seed.split(' ').length < 24;
|
||||||
|
|
||||||
if (wallet is MoneroWallet) {
|
if (wallet is MoneroWallet) {
|
||||||
subname = wallet.account?.label;
|
subname = wallet.walletAddresses.account?.label;
|
||||||
|
|
||||||
_onMoneroAccountChangeReaction?.reaction?.dispose();
|
_onMoneroAccountChangeReaction?.reaction?.dispose();
|
||||||
_onMoneroBalanceChangeReaction?.reaction?.dispose();
|
_onMoneroBalanceChangeReaction?.reaction?.dispose();
|
||||||
|
|
||||||
_onMoneroAccountChangeReaction = reaction((_) => wallet.account,
|
_onMoneroAccountChangeReaction = reaction((_) => wallet.walletAddresses
|
||||||
(Account account) => _onMoneroAccountChange(wallet));
|
.account, (Account account) => _onMoneroAccountChange(wallet));
|
||||||
|
|
||||||
_onMoneroBalanceChangeReaction = reaction((_) => wallet.balance,
|
_onMoneroBalanceChangeReaction = reaction((_) => wallet.balance,
|
||||||
(MoneroBalance balance) => _onMoneroTransactionsUpdate(wallet));
|
(MoneroBalance balance) => _onMoneroTransactionsUpdate(wallet));
|
||||||
|
@ -284,7 +284,7 @@ abstract class DashboardViewModelBase with Store {
|
||||||
settingsStore: appStore.settingsStore),
|
settingsStore: appStore.settingsStore),
|
||||||
filter: (TransactionInfo tx) {
|
filter: (TransactionInfo tx) {
|
||||||
if (tx is MoneroTransactionInfo && wallet is MoneroWallet) {
|
if (tx is MoneroTransactionInfo && wallet is MoneroWallet) {
|
||||||
return tx.accountIndex == wallet.account.id;
|
return tx.accountIndex == wallet.walletAddresses.account.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -293,7 +293,7 @@ abstract class DashboardViewModelBase with Store {
|
||||||
|
|
||||||
@action
|
@action
|
||||||
void _onMoneroAccountChange(MoneroWallet wallet) {
|
void _onMoneroAccountChange(MoneroWallet wallet) {
|
||||||
subname = wallet.account?.label;
|
subname = wallet.walletAddresses.account?.label;
|
||||||
_onMoneroTransactionsUpdate(wallet);
|
_onMoneroTransactionsUpdate(wallet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,7 +302,7 @@ abstract class DashboardViewModelBase with Store {
|
||||||
transactions.clear();
|
transactions.clear();
|
||||||
|
|
||||||
final _accountTransactions = wallet.transactionHistory.transactions.values
|
final _accountTransactions = wallet.transactionHistory.transactions.values
|
||||||
.where((tx) => tx.accountIndex == wallet.account.id)
|
.where((tx) => tx.accountIndex == wallet.walletAddresses.account.id)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
transactions.addAll(_accountTransactions.map((transaction) =>
|
transactions.addAll(_accountTransactions.map((transaction) =>
|
||||||
|
|
|
@ -41,7 +41,8 @@ abstract class ExchangeViewModelBase with Store {
|
||||||
depositAmount = '';
|
depositAmount = '';
|
||||||
receiveAmount = '';
|
receiveAmount = '';
|
||||||
receiveAddress = '';
|
receiveAddress = '';
|
||||||
depositAddress = depositCurrency == wallet.currency ? wallet.address : '';
|
depositAddress = depositCurrency == wallet.currency
|
||||||
|
? wallet.walletAddresses.address : '';
|
||||||
limitsState = LimitsInitialState();
|
limitsState = LimitsInitialState();
|
||||||
tradeState = ExchangeTradeStateInitial();
|
tradeState = ExchangeTradeStateInitial();
|
||||||
_cryptoNumberFormat = NumberFormat()..maximumFractionDigits = 12;
|
_cryptoNumberFormat = NumberFormat()..maximumFractionDigits = 12;
|
||||||
|
@ -308,8 +309,10 @@ abstract class ExchangeViewModelBase with Store {
|
||||||
isReceiveAmountEntered = false;
|
isReceiveAmountEntered = false;
|
||||||
depositAmount = '';
|
depositAmount = '';
|
||||||
receiveAmount = '';
|
receiveAmount = '';
|
||||||
depositAddress = depositCurrency == wallet.currency ? wallet.address : '';
|
depositAddress = depositCurrency == wallet.currency
|
||||||
receiveAddress = receiveCurrency == wallet.currency ? wallet.address : '';
|
? wallet.walletAddresses.address : '';
|
||||||
|
receiveAddress = receiveCurrency == wallet.currency
|
||||||
|
? wallet.walletAddresses.address : '';
|
||||||
isDepositAddressEnabled = !(depositCurrency == wallet.currency);
|
isDepositAddressEnabled = !(depositCurrency == wallet.currency);
|
||||||
isReceiveAddressEnabled = !(receiveCurrency == wallet.currency);
|
isReceiveAddressEnabled = !(receiveCurrency == wallet.currency);
|
||||||
isFixedRateMode = false;
|
isFixedRateMode = false;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'package:cake_wallet/core/wallet_base.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:cake_wallet/core/execution_state.dart';
|
import 'package:cake_wallet/core/execution_state.dart';
|
||||||
import 'package:cake_wallet/monero/monero_account_list.dart';
|
import 'package:cake_wallet/monero/monero_account_list.dart';
|
||||||
|
@ -10,11 +12,12 @@ class MoneroAccountEditOrCreateViewModel = MoneroAccountEditOrCreateViewModelBas
|
||||||
|
|
||||||
abstract class MoneroAccountEditOrCreateViewModelBase with Store {
|
abstract class MoneroAccountEditOrCreateViewModelBase with Store {
|
||||||
MoneroAccountEditOrCreateViewModelBase(this._moneroAccountList,
|
MoneroAccountEditOrCreateViewModelBase(this._moneroAccountList,
|
||||||
{AccountListItem accountListItem})
|
{@required WalletBase wallet, AccountListItem accountListItem})
|
||||||
: state = InitialExecutionState(),
|
: state = InitialExecutionState(),
|
||||||
isEdit = accountListItem != null,
|
isEdit = accountListItem != null,
|
||||||
label = accountListItem?.label??'',
|
label = accountListItem?.label??'',
|
||||||
_accountListItem = accountListItem;
|
_accountListItem = accountListItem,
|
||||||
|
_wallet = wallet;
|
||||||
|
|
||||||
final bool isEdit;
|
final bool isEdit;
|
||||||
|
|
||||||
|
@ -26,6 +29,7 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store {
|
||||||
|
|
||||||
final MoneroAccountList _moneroAccountList;
|
final MoneroAccountList _moneroAccountList;
|
||||||
final AccountListItem _accountListItem;
|
final AccountListItem _accountListItem;
|
||||||
|
final WalletBase _wallet;
|
||||||
|
|
||||||
Future<void> save() async {
|
Future<void> save() async {
|
||||||
try {
|
try {
|
||||||
|
@ -38,6 +42,7 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store {
|
||||||
await _moneroAccountList.addAccount(label: label);
|
await _moneroAccountList.addAccount(label: label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await _wallet.save();
|
||||||
state = ExecutedSuccessfullyState();
|
state = ExecutedSuccessfullyState();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
state = FailureState(e.toString());
|
state = FailureState(e.toString());
|
||||||
|
|
|
@ -20,15 +20,16 @@ abstract class MoneroAccountListViewModelBase with Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
List<AccountListItem> get accounts => _moneroWallet.accountList.accounts
|
List<AccountListItem> get accounts => _moneroWallet.walletAddresses
|
||||||
.map((acc) => AccountListItem(
|
.accountList.accounts.map((acc) => AccountListItem(
|
||||||
label: acc.label,
|
label: acc.label,
|
||||||
id: acc.id,
|
id: acc.id,
|
||||||
isSelected: acc.id == _moneroWallet.account.id))
|
isSelected: acc.id == _moneroWallet.walletAddresses.account.id))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
final MoneroWallet _moneroWallet;
|
final MoneroWallet _moneroWallet;
|
||||||
|
|
||||||
void select(AccountListItem item) =>
|
void select(AccountListItem item) =>
|
||||||
_moneroWallet.account = Account(id: item.id, label: item.label);
|
_moneroWallet.walletAddresses.account =
|
||||||
|
Account(id: item.id, label: item.label);
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,12 +64,15 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
|
||||||
final wallet = _wallet;
|
final wallet = _wallet;
|
||||||
|
|
||||||
if (wallet is ElectrumWallet) {
|
if (wallet is ElectrumWallet) {
|
||||||
await wallet.generateNewAddress();
|
await wallet.walletAddresses.generateNewAddress();
|
||||||
|
await wallet.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wallet is MoneroWallet) {
|
if (wallet is MoneroWallet) {
|
||||||
await wallet.subaddressList
|
await wallet.walletAddresses.subaddressList
|
||||||
.addSubaddress(accountIndex: wallet.account.id, label: label);
|
.addSubaddress(
|
||||||
|
accountIndex: wallet.walletAddresses.account.id,
|
||||||
|
label: label);
|
||||||
await wallet.save();
|
await wallet.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,13 +80,14 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
|
||||||
Future<void> _update() async {
|
Future<void> _update() async {
|
||||||
final wallet = _wallet;
|
final wallet = _wallet;
|
||||||
|
|
||||||
if (wallet is BitcoinWallet) {
|
/*if (wallet is BitcoinWallet) {
|
||||||
await wallet.updateAddress(_item.address as String);
|
await wallet.walletAddresses.updateAddress(_item.address as String);
|
||||||
}
|
await wallet.save();
|
||||||
|
}*/
|
||||||
|
|
||||||
if (wallet is MoneroWallet) {
|
if (wallet is MoneroWallet) {
|
||||||
await wallet.subaddressList.setLabelSubaddress(
|
await wallet.walletAddresses.subaddressList.setLabelSubaddress(
|
||||||
accountIndex: wallet.account.id,
|
accountIndex: wallet.walletAddresses.account.id,
|
||||||
addressIndex: _item.id as int,
|
addressIndex: _item.id as int,
|
||||||
label: label);
|
label: label);
|
||||||
await wallet.save();
|
await wallet.save();
|
||||||
|
|
|
@ -80,7 +80,7 @@ abstract class WalletAddressListViewModelBase with Store {
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
WalletAddressListItem get address =>
|
WalletAddressListItem get address =>
|
||||||
WalletAddressListItem(address: _wallet.address);
|
WalletAddressListItem(address: _wallet.walletAddresses.address);
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
PaymentURI get uri {
|
PaymentURI get uri {
|
||||||
|
@ -105,8 +105,10 @@ abstract class WalletAddressListViewModelBase with Store {
|
||||||
final addressList = ObservableList<ListItem>();
|
final addressList = ObservableList<ListItem>();
|
||||||
|
|
||||||
if (wallet is MoneroWallet) {
|
if (wallet is MoneroWallet) {
|
||||||
final primaryAddress = wallet.subaddressList.subaddresses.first;
|
final primaryAddress =
|
||||||
addressList.addAll(wallet.subaddressList.subaddresses.map((subaddress) {
|
wallet.walletAddresses.subaddressList.subaddresses.first;
|
||||||
|
addressList.addAll(wallet.walletAddresses.subaddressList.subaddresses
|
||||||
|
.map((subaddress) {
|
||||||
final isPrimary = subaddress == primaryAddress;
|
final isPrimary = subaddress == primaryAddress;
|
||||||
|
|
||||||
return WalletAddressListItem(
|
return WalletAddressListItem(
|
||||||
|
@ -118,8 +120,8 @@ abstract class WalletAddressListViewModelBase with Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wallet is BitcoinWallet) {
|
if (wallet is BitcoinWallet) {
|
||||||
final primaryAddress = wallet.addresses.first;
|
final primaryAddress = wallet.walletAddresses.addresses.first;
|
||||||
final bitcoinAddresses = wallet.addresses.map((addr) {
|
final bitcoinAddresses = wallet.walletAddresses.addresses.map((addr) {
|
||||||
final isPrimary = addr == primaryAddress;
|
final isPrimary = addr == primaryAddress;
|
||||||
|
|
||||||
return WalletAddressListItem(
|
return WalletAddressListItem(
|
||||||
|
@ -139,7 +141,7 @@ abstract class WalletAddressListViewModelBase with Store {
|
||||||
final wallet = _wallet;
|
final wallet = _wallet;
|
||||||
|
|
||||||
if (wallet is MoneroWallet) {
|
if (wallet is MoneroWallet) {
|
||||||
return wallet.account.label;
|
return wallet.walletAddresses.account.label;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -160,7 +162,7 @@ abstract class WalletAddressListViewModelBase with Store {
|
||||||
|
|
||||||
@action
|
@action
|
||||||
void setAddress(WalletAddressListItem address) =>
|
void setAddress(WalletAddressListItem address) =>
|
||||||
_wallet.address = address.address;
|
_wallet.walletAddresses.address = address.address;
|
||||||
|
|
||||||
void _init() {
|
void _init() {
|
||||||
_baseItems = [];
|
_baseItems = [];
|
||||||
|
@ -177,7 +179,8 @@ abstract class WalletAddressListViewModelBase with Store {
|
||||||
final wallet = _wallet;
|
final wallet = _wallet;
|
||||||
|
|
||||||
if (wallet is ElectrumWallet) {
|
if (wallet is ElectrumWallet) {
|
||||||
wallet.nextAddress();
|
wallet.walletAddresses.nextAddress();
|
||||||
|
wallet.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ abstract class WalletCreationVMBase with Store {
|
||||||
dirPath: dirPath);
|
dirPath: dirPath);
|
||||||
credentials.walletInfo = walletInfo;
|
credentials.walletInfo = walletInfo;
|
||||||
final wallet = await process(credentials);
|
final wallet = await process(credentials);
|
||||||
walletInfo.address = wallet.address;
|
walletInfo.address = wallet.walletAddresses.address;
|
||||||
await _walletInfoSource.add(walletInfo);
|
await _walletInfoSource.add(walletInfo);
|
||||||
_appStore.changeCurrentWallet(wallet);
|
_appStore.changeCurrentWallet(wallet);
|
||||||
_appStore.authenticationStore.allowed();
|
_appStore.authenticationStore.allowed();
|
||||||
|
|
Loading…
Reference in a new issue