TMP 1

M committed Jun 1, 2020 at 21:13 UTC 957ca8cd587330c38d946c70fcb342546f9aa826
23 files changed +1084 -442
cw_monero/ios/Classes/monero_api.cpp
+23 -5
@@ -14,6 +14,7 @@ using namespace std::chrono_literals;
14 extern "C"
15 {
16 #endif
17 + const uint64_t MONERO_BLOCK_SIZE = 1000;
18
19 struct Utf8Box
20 {
@@ -173,6 +174,8 @@ extern "C"
174 Monero::Subaddress *m_subaddress;
175 Monero::SubaddressAccount *m_account;
176 uint64_t m_last_known_wallet_height;
177 + uint64_t m_cached_syncing_blockchain_height = 0;
178 +
179
180 void change_current_wallet(Monero::Wallet *wallet)
181 {
@@ -481,20 +484,34 @@ extern "C"
484 return committed;
485 }
486
487 + uint64_t get_node_height_or_update(uint64_t base_eight)
488 + {
489 + if (m_cached_syncing_blockchain_height < base_eight) {
490 + m_cached_syncing_blockchain_height = base_eight;
491 + }
492 +
493 + return m_cached_syncing_blockchain_height;
494 + }
495 +
496 uint64_t get_syncing_height()
497 {
498 if (m_listener == nullptr) {
499 return 0;
500 }
501
490 - uint64_t _height = m_listener->height();
502 + uint64_t height = m_listener->height();
503 + uint64_t node_height = get_node_height_or_update(height);
504 +
505 + if (height <= 1 || node_height <= 0) {
506 + return 0;
507 + }
508
492 - if (_height != m_last_known_wallet_height)
509 + if (height != m_last_known_wallet_height)
510 {
494 - m_last_known_wallet_height = _height;
511 + m_last_known_wallet_height = height;
512 }
513
497 - return _height;
514 + return height;
515 }
516
517 uint64_t is_needed_to_refresh()
@@ -504,8 +521,9 @@ extern "C"
521 }
522
523 bool should_refresh = m_listener->isNeedToRefresh();
524 + uint64_t node_height = get_node_height_or_update(m_last_known_wallet_height);
525
508 - if (should_refresh)
526 + if (should_refresh || (node_height - m_last_known_wallet_height < MONERO_BLOCK_SIZE))
527 {
528 m_listener->resetNeedToRefresh();
529 }
cw_monero/lib/wallet.dart
+59 -26
@@ -209,41 +209,74 @@ String getSecretSpendKey() =>
209 String getPublicSpendKey() =>
210 convertUTF8ToString(pointer: getPublicSpendKeyNative());
211
212 -Timer _updateSyncInfoTimer;
212 +class SyncListner {
213 + SyncListner({this.onNewBlock, this.onNeedToRefresh, this.onNewTransaction});
214
214 -int _lastKnownBlockHeight = 0;
215 + void Function(int, int, double) onNewBlock;
216 + void Function() onNeedToRefresh;
217 + void Function() onNewTransaction;
218
216 -void setListeners(Future Function(int) onNewBlock,
217 - Future Function() onNeedToRefresh, Future Function() onNewTransaction) {
218 - if (_updateSyncInfoTimer != null) {
219 - _updateSyncInfoTimer.cancel();
219 + Timer _updateSyncInfoTimer;
220 + int _cachedBlockchainHeight = 0;
221 + int _lastKnownBlockHeight = 0;
222 + int _initialSyncHeight = 0;
223 +
224 + Future<int> getNodeHeightOrUpdate(int baseHeight) async {
225 + if (_cachedBlockchainHeight < baseHeight) {
226 + _cachedBlockchainHeight = await getNodeHeight();
227 + }
228 +
229 + return _cachedBlockchainHeight;
230 }
231
222 - _updateSyncInfoTimer = Timer.periodic(Duration(milliseconds: 200), (_) async {
223 - final syncHeight = getSyncingHeight();
224 - final needToRefresh = isNeededToRefresh();
225 - final newTransactionExist = isNewTransactionExist();
232 + void start() {
233 + _cachedBlockchainHeight = 0;
234 + _lastKnownBlockHeight = 0;
235 + _initialSyncHeight = 0;
236 + _updateSyncInfoTimer ??=
237 + Timer.periodic(Duration(milliseconds: 200), (_) async {
238 + final syncHeight = getSyncingHeight();
239 + final needToRefresh = isNeededToRefresh();
240 + final newTransactionExist = isNewTransactionExist();
241 + final bchHeight = await getNodeHeightOrUpdate(syncHeight);
242 +
243 + if (_lastKnownBlockHeight != syncHeight && syncHeight != null) {
244 + if (_initialSyncHeight <= 0) {
245 + _initialSyncHeight = syncHeight;
246 + }
247 +
248 + _lastKnownBlockHeight = syncHeight;
249 + final line = bchHeight - _initialSyncHeight;
250 + final diff = line - (bchHeight - syncHeight);
251 + final ptc = diff <= 0 ? 0.0 : diff / line;
252 + final left = bchHeight - syncHeight;
253 + // 1. Actual new height; 2. Blocks left to finish; 3. Progress in percents;
254 + onNewBlock(syncHeight, left, ptc);
255 + }
256 +
257 + if (newTransactionExist && onNewTransaction != null) {
258 + onNewTransaction();
259 + }
260 +
261 + if (needToRefresh && onNeedToRefresh != null) {
262 + onNeedToRefresh();
263 + }
264 + });
265 + }
266
227 - if (_lastKnownBlockHeight != syncHeight && syncHeight != null) {
228 - _lastKnownBlockHeight = syncHeight;
229 - await onNewBlock(syncHeight);
230 - }
267 + void stop() => _updateSyncInfoTimer?.cancel();
268 +}
269
232 - if (newTransactionExist && onNewTransaction != null) {
233 - await onNewTransaction();
234 - }
270 +SyncListner setListeners(void Function(int, int, double) onNewBlock,
271 + void Function() onNeedToRefresh, void Function() onNewTransaction) {
272 + final listener = SyncListner(
273 + onNewBlock: onNewBlock,
274 + onNeedToRefresh: onNeedToRefresh,
275 + onNewTransaction: onNewTransaction);
276
236 - if (needToRefresh && onNeedToRefresh != null) {
237 - await onNeedToRefresh();
238 - }
239 - });
277 setListenerNative();
241 -}
278
243 -void closeListeners() {
244 - if (_updateSyncInfoTimer != null) {
245 - _updateSyncInfoTimer.cancel();
246 - }
279 + return listener;
280 }
281
282 void onStartup() => onStartupNative();
lib/core/auth_service.dart new
+21
@@ -0,0 +1,21 @@
1 +import 'package:flutter/foundation.dart';
2 +import 'package:mobx/mobx.dart';
3 +import 'package:cake_wallet/core/setup_pin_code_state.dart';
4 +
5 +part 'auth_service.g.dart';
6 +
7 +class AuthService = AuthServiceBase with _$AuthService;
8 +
9 +abstract class AuthServiceBase with Store {
10 + @observable
11 + SetupPinCodeState setupPinCodeState;
12 +
13 + Future<void> setupPinCode({@required String pin}) async {}
14 +
15 + Future<bool> authenticate({@required String pin}) async {
16 + return false;
17 + }
18 +
19 + void resetSetupPinCodeState() =>
20 + setupPinCodeState = InitialSetupPinCodeState();
21 +}
lib/core/bitcoin_transaction_history.dart new
+121
@@ -0,0 +1,121 @@
1 +import 'dart:convert';
2 +import 'package:flutter/foundation.dart';
3 +import 'package:mobx/mobx.dart';
4 +import 'package:cake_wallet/core/transaction_history.dart';
5 +import 'package:cake_wallet/core/bitcoin_wallet.dart';
6 +import 'package:cake_wallet/bitcoin/bitcoin_transaction_info.dart';
7 +import 'package:cake_wallet/bitcoin/electrum.dart';
8 +import 'package:cake_wallet/src/domain/common/transaction_info.dart';
9 +import 'package:cake_wallet/bitcoin/file.dart';
10 +
11 +part 'bitcoin_transaction_history.g.dart';
12 +
13 +// TODO: Think about another transaction store for bitcoin transaction history..
14 +
15 +const _transactionsHistoryFileName = 'transactions.json';
16 +
17 +class BitcoinTransactionHistory = BitcoinTransactionHistoryBase
18 + with _$BitcoinTransactionHistory;
19 +
20 +abstract class BitcoinTransactionHistoryBase
21 + extends TranasctionHistoryBase<BitcoinTransactionInfo> with Store {
22 + BitcoinTransactionHistoryBase(
23 + {this.eclient, String dirPath, @required String password})
24 + : path = '$dirPath/$_transactionsHistoryFileName',
25 + _password = password,
26 + _height = 0;
27 +
28 + BitcoinWallet wallet;
29 + final ElectrumClient eclient;
30 + final String path;
31 + final String _password;
32 + int _height;
33 +
34 + Future<void> init() async {
35 + // TODO: throw exeption if wallet is null;
36 + final info = await _read();
37 + _height = (info['height'] as int) ?? _height;
38 + transactions = info['transactions'] as List<BitcoinTransactionInfo>;
39 + }
40 +
41 + @override
42 + Future update() async {
43 + await super.update();
44 + _updateHeight();
45 + }
46 +
47 + @override
48 + Future<List<BitcoinTransactionInfo>> fetchTransactions() async {
49 + final addresses = wallet.getAddresses();
50 + final histories =
51 + addresses.map((address) => eclient.getHistory(address: address));
52 + final _historiesWithDetails = await Future.wait(histories)
53 + .then((histories) => histories
54 + .map((h) => h.where((tx) => (tx['height'] as int) > _height))
55 + .expand((i) => i)
56 + .toList())
57 + .then((histories) => histories.map((tx) => fetchTransactionInfo(
58 + hash: tx['tx_hash'] as String, height: tx['height'] as int)));
59 + final historiesWithDetails = await Future.wait(_historiesWithDetails);
60 +
61 + return historiesWithDetails
62 + .map((info) => BitcoinTransactionInfo.fromHexAndHeader(
63 + info['raw'] as String, info['header'] as Map<String, Object>,
64 + addresses: addresses))
65 + .toList();
66 + }
67 +
68 + Future<Map<String, Object>> fetchTransactionInfo(
69 + {@required String hash, @required int height}) async {
70 + final rawFetching = eclient.getTransactionRaw(hash: hash);
71 + final headerFetching = eclient.getHeader(height: height);
72 + final result = await Future.wait([rawFetching, headerFetching]);
73 + final raw = result.first as String;
74 + final header = result[1] as Map<String, Object>;
75 +
76 + return {'raw': raw, 'header': header};
77 + }
78 +
79 + Future<void> add(List<BitcoinTransactionInfo> transactions) async {
80 + this.transactions.addAll(transactions);
81 + await save();
82 + }
83 +
84 + Future<void> addOne(BitcoinTransactionInfo tx) async {
85 + transactions.add(tx);
86 + await save();
87 + }
88 +
89 + Future<void> save() async => writeData(
90 + path: path,
91 + password: _password,
92 + data: json.encode({'height': _height, 'transactions': transactions}));
93 +
94 + Future<Map<String, Object>> _read() async {
95 + try {
96 + final content = await read(path: path, password: _password);
97 + final jsoned = json.decode(content) as Map<String, Object>;
98 + final height = jsoned['height'] as int;
99 + final transactions = (jsoned['transactions'] as List<dynamic>)
100 + .map((dynamic row) {
101 + if (row is Map<String, Object>) {
102 + return BitcoinTransactionInfo.fromJson(row);
103 + }
104 +
105 + return null;
106 + })
107 + .where((el) => el != null)
108 + .toList();
109 +
110 + return {'transactions': transactions, 'height': height};
111 + } catch (_) {
112 + return {'transactions': <TransactionInfo>[], 'height': 0};
113 + }
114 + }
115 +
116 + void _updateHeight() {
117 + final newHeight = transactions.fold(
118 + 0, (int acc, val) => val.height > acc ? val.height : acc);
119 + _height = newHeight > _height ? newHeight : _height;
120 + }
121 +}
lib/core/bitcoin_wallet.dart new
+149
@@ -0,0 +1,149 @@
1 +import 'dart:convert';
2 +import 'dart:typed_data';
3 +import 'package:cake_wallet/core/bitcoin_transaction_history.dart';
4 +import 'package:cake_wallet/core/transaction_history.dart';
5 +import 'package:mobx/mobx.dart';
6 +import 'package:bip39/bip39.dart' as bip39;
7 +import 'package:flutter/foundation.dart';
8 +import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
9 +import 'package:bitcoin_flutter/src/payments/index.dart' show PaymentData;
10 +import 'package:cake_wallet/bitcoin/file.dart';
11 +import 'package:cake_wallet/src/domain/common/pathForWallet.dart';
12 +import 'package:cake_wallet/src/domain/common/wallet_type.dart';
13 +import 'package:cake_wallet/bitcoin/electrum.dart';
14 +import 'package:cake_wallet/bitcoin/bitcoin_balance.dart';
15 +import 'package:cake_wallet/src/domain/common/node.dart';
16 +import 'wallet_base.dart';
17 +
18 +part 'bitcoin_wallet.g.dart';
19 +
20 +/* TODO: Save balance to a wallet file.
21 + Load balance from the wallet file in `init` method.
22 +*/
23 +
24 +class BitcoinWallet = BitcoinWalletBase with _$BitcoinWallet;
25 +
26 +abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
27 + static Future<BitcoinWallet> load(
28 + {@required String name, @required String password}) async {
29 + final walletDirPath =
30 + await pathForWalletDir(name: name, type: WalletType.bitcoin);
31 + final walletPath = '$walletDirPath/$name';
32 + final walletJSONRaw = await read(path: walletPath, password: password);
33 + final jsoned = json.decode(walletJSONRaw) as Map<String, Object>;
34 + final mnemonic = jsoned['mnemonic'] as String;
35 + final accountIndex =
36 + (jsoned['account_index'] == "null" || jsoned['account_index'] == null)
37 + ? 0
38 + : int.parse(jsoned['account_index'] as String);
39 +
40 + return BitcoinWallet.build(
41 + mnemonic: mnemonic,
42 + password: password,
43 + name: name,
44 + accountIndex: accountIndex);
45 + }
46 +
47 + factory BitcoinWalletBase.build(
48 + {@required String mnemonic,
49 + @required String password,
50 + @required String name,
51 + @required String dirPath,
52 + int accountIndex = 0}) {
53 + final walletPath = '$dirPath/$name';
54 + final eclient = ElectrumClient();
55 + final history = BitcoinTransactionHistory(
56 + eclient: eclient, dirPath: dirPath, password: password);
57 +
58 + return BitcoinWallet._internal(
59 + eclient: eclient,
60 + path: walletPath,
61 + mnemonic: mnemonic,
62 + password: password,
63 + accountIndex: accountIndex,
64 + transactionHistory: history);
65 + }
66 +
67 + BitcoinWalletBase._internal(
68 + {@required this.eclient,
69 + @required this.path,
70 + @required String password,
71 + int accountIndex = 0,
72 + this.transactionHistory,
73 + this.mnemonic}) {
74 + hd = bitcoin.HDWallet.fromSeed(bip39.mnemonicToSeed(mnemonic),
75 + network: bitcoin.bitcoin);
76 + _password = password;
77 + _accountIndex = accountIndex;
78 + }
79 +
80 + final BitcoinTransactionHistory transactionHistory;
81 + final String path;
82 + bitcoin.HDWallet hd;
83 + final ElectrumClient eclient;
84 + final String mnemonic;
85 + int _accountIndex;
86 + String _password;
87 +
88 + @override
89 + String get name => path.split('/').last ?? '';
90 +
91 + @override
92 + String get filename => hd.address;
93 +
94 + String get xpub => hd.base58;
95 +
96 + List<String> getAddresses() => _accountIndex == 0
97 + ? [address]
98 + : List<String>.generate(
99 + _accountIndex, (i) => _getAddress(hd: hd, index: i));
100 +
101 + Future<void> init() async {
102 + await transactionHistory.init();
103 + }
104 +
105 + Future<String> newAddress() async {
106 + _accountIndex += 1;
107 + final address = _getAddress(hd: hd, index: _accountIndex);
108 + await save();
109 +
110 + return address;
111 + }
112 +
113 + @override
114 + Future<void> startSync() async {}
115 +
116 + @override
117 + Future<void> connectToNode({@required Node node}) async {}
118 +
119 + @override
120 + Future<void> createTransaction(Object credentials) async {}
121 +
122 + @override
123 + Future<void> save() async => await write(
124 + path: path,
125 + password: _password,
126 + obj: {'mnemonic': mnemonic, 'account_index': _accountIndex.toString()});
127 +
128 + String _getAddress({bitcoin.HDWallet hd, int index}) => bitcoin
129 + .P2PKH(
130 + data: PaymentData(
131 + pubkey: Uint8List.fromList(hd.derive(index).pubKey.codeUnits)))
132 + .data
133 + .address;
134 +
135 + Future<Map<String, int>> _fetchBalances() async {
136 + final balances = await Future.wait(
137 + getAddresses().map((address) => eclient.getBalance(address: address)));
138 + final balance = balances.fold(<String, int>{}, (Map<String, int> acc, val) {
139 + acc['confirmed'] =
140 + (val['confirmed'] as int ?? 0) + (acc['confirmed'] ?? 0);
141 + acc['unconfirmed'] =
142 + (val['unconfirmed'] as int ?? 0) + (acc['unconfirmed'] ?? 0);
143 +
144 + return acc;
145 + });
146 +
147 + return balance;
148 + }
149 +}
lib/core/bitcoin_wallet_list_service.dart new
+103
@@ -0,0 +1,103 @@
1 +import 'dart:io';
2 +import 'package:bip39/bip39.dart' as bip39;
3 +import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart';
4 +import 'package:cake_wallet/core/wallet_credentials.dart';
5 +import 'package:cake_wallet/core/wallet_list_service.dart';
6 +import 'package:cake_wallet/core/bitcoin_wallet.dart';
7 +import 'package:cake_wallet/src/domain/common/pathForWallet.dart';
8 +import 'package:cake_wallet/src/domain/common/wallet.dart';
9 +import 'package:cake_wallet/src/domain/common/wallet_description.dart';
10 +import 'package:cake_wallet/src/domain/common/wallet_type.dart';
11 +import 'package:cake_wallet/src/domain/common/wallets_manager.dart';
12 +/*
13 +*
14 +* BitcoinRestoreWalletFromSeedCredentials
15 +*
16 +* */
17 +
18 +class BitcoinNewWalletCredentials extends WalletCredentials {}
19 +
20 +/*
21 +*
22 +* BitcoinRestoreWalletFromSeedCredentials
23 +*
24 +* */
25 +
26 +class BitcoinRestoreWalletFromSeedCredentials extends WalletCredentials {
27 + const BitcoinRestoreWalletFromSeedCredentials(
28 + {String name, String password, this.mnemonic})
29 + : super(name: name, password: password);
30 +
31 + final String mnemonic;
32 +}
33 +
34 +/*
35 +*
36 +* BitcoinRestoreWalletFromWIFCredentials
37 +*
38 +* */
39 +
40 +class BitcoinRestoreWalletFromWIFCredentials extends WalletCredentials {
41 + const BitcoinRestoreWalletFromWIFCredentials(
42 + {String name, String password, this.wif})
43 + : super(name: name, password: password);
44 +
45 + final String wif;
46 +}
47 +
48 +/*
49 +*
50 +* BitcoinWalletListService
51 +*
52 +* */
53 +
54 +class BitcoinWalletListService extends WalletListService<
55 + BitcoinNewWalletCredentials,
56 + BitcoinRestoreWalletFromSeedCredentials,
57 + BitcoinRestoreWalletFromWIFCredentials> {
58 + @override
59 + Future<void> create(BitcoinNewWalletCredentials credentials) async {
60 + final wallet = await BitcoinWalletBase.build(
61 + mnemonic: bip39.generateMnemonic(),
62 + password: credentials.password,
63 + name: credentials.name);
64 + await wallet.save();
65 +
66 + return wallet;
67 + }
68 +
69 + @override
70 + Future<bool> isWalletExit(String name) async =>
71 + File(await pathForWallet(name: name, type: WalletType.bitcoin))
72 + .existsSync();
73 +
74 + @override
75 + Future<void> openWallet(String name, String password) async {
76 + // TODO: implement openWallet
77 + throw UnimplementedError();
78 + }
79 +
80 + Future<void> remove(String wallet) {
81 + // TODO: implement remove
82 + throw UnimplementedError();
83 + }
84 +
85 + @override
86 + Future<void> restoreFromKeys(
87 + BitcoinRestoreWalletFromWIFCredentials credentials) async {
88 + // TODO: implement restoreFromKeys
89 + throw UnimplementedError();
90 + }
91 +
92 + @override
93 + Future<void> restoreFromSeed(
94 + BitcoinRestoreWalletFromSeedCredentials credentials) async {
95 + final wallet = await BitcoinWalletBase.build(
96 + name: credentials.name,
97 + password: credentials.password,
98 + mnemonic: credentials.mnemonic);
99 + await wallet.save();
100 +
101 + return wallet;
102 + }
103 +}
lib/core/monero_balance.dart new
+20
@@ -0,0 +1,20 @@
1 +import 'package:flutter/foundation.dart';
2 +import 'package:cake_wallet/src/domain/monero/monero_amount_format.dart';
3 +
4 +class MoneroBalance {
5 + MoneroBalance({@required this.fullBalance, @required this.unlockedBalance})
6 + : formattedFullBalance = moneroAmountToString(amount: fullBalance),
7 + formattedUnlockedBalance =
8 + moneroAmountToString(amount: unlockedBalance);
9 +
10 + MoneroBalance.fromString(
11 + {@required this.formattedFullBalance,
12 + @required this.formattedUnlockedBalance})
13 + : fullBalance = moneroParseAmount(amount: formattedFullBalance),
14 + unlockedBalance = moneroParseAmount(amount: formattedUnlockedBalance);
15 +
16 + final int fullBalance;
17 + final int unlockedBalance;
18 + final String formattedFullBalance;
19 + final String formattedUnlockedBalance;
20 +}
\ No newline at end of file
lib/core/monero_transaction_history.dart new
+27
@@ -0,0 +1,27 @@
1 +import 'dart:core';
2 +import 'package:mobx/mobx.dart';
3 +import 'package:cw_monero/transaction_history.dart'
4 + as monero_transaction_history;
5 +import 'package:cake_wallet/core/transaction_history.dart';
6 +import 'package:cake_wallet/src/domain/common/transaction_info.dart';
7 +import 'package:cake_wallet/src/domain/monero/monero_transaction_info.dart';
8 +
9 +part 'monero_transaction_history.g.dart';
10 +
11 +List<TransactionInfo> _getAllTransactions(dynamic _) =>
12 + monero_transaction_history
13 + .getAllTransations()
14 + .map((row) => MoneroTransactionInfo.fromRow(row))
15 + .toList();
16 +
17 +class MoneroTransactionHistory = MoneroTransactionHistoryBase
18 + with _$MoneroTransactionHistory;
19 +
20 +abstract class MoneroTransactionHistoryBase
21 + extends TranasctionHistoryBase<TransactionInfo> with Store {
22 + @override
23 + Future<List<TransactionInfo>> fetchTransactions() async {
24 + monero_transaction_history.refreshTransactions();
25 + return _getAllTransactions(null);
26 + }
27 +}
lib/core/monero_wallet.dart new
+186
@@ -0,0 +1,186 @@
1 +import 'package:cake_wallet/core/monero_balance.dart';
2 +import 'package:cake_wallet/core/monero_transaction_history.dart';
3 +import 'package:cake_wallet/src/domain/common/sync_status.dart';
4 +import 'package:cake_wallet/src/domain/monero/account.dart';
5 +import 'package:cake_wallet/src/domain/monero/account_list.dart';
6 +import 'package:cake_wallet/src/domain/monero/subaddress.dart';
7 +import 'package:cake_wallet/src/domain/monero/subaddress_list.dart';
8 +import 'package:cw_monero/wallet.dart';
9 +import 'package:flutter/foundation.dart';
10 +import 'package:mobx/mobx.dart';
11 +import 'package:cake_wallet/src/domain/common/node.dart';
12 +import 'package:cw_monero/wallet.dart' as monero_wallet;
13 +import 'wallet_base.dart';
14 +
15 +part 'monero_wallet.g.dart';
16 +
17 +class MoneroWallet = MoneroWalletBase with _$MoneroWallet;
18 +
19 +abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
20 + MoneroWalletBase({String filename, this.isRecovery = false}) {
21 + transactionHistory = MoneroTransactionHistory();
22 + _filename = filename;
23 + accountList = AccountList();
24 + subaddressList = SubaddressList();
25 + balance = MoneroBalance(
26 + fullBalance: monero_wallet.getFullBalance(accountIndex: 0),
27 + unlockedBalance: monero_wallet.getFullBalance(accountIndex: 0));
28 + }
29 +
30 + MoneroTransactionHistory transactionHistory;
31 + SubaddressList subaddressList;
32 + AccountList accountList;
33 +
34 + @observable
35 + Account account;
36 +
37 + @observable
38 + Subaddress subaddress;
39 +
40 + @observable
41 + SyncStatus syncStatus;
42 +
43 + @override
44 + String get name => filename.split('/').last;
45 +
46 + @override
47 + String get filename => _filename;
48 +
49 + String _filename;
50 +
51 + bool isRecovery;
52 +
53 + SyncListner _listner;
54 +
55 + void init() {
56 + account = accountList.getAll().first;
57 + subaddressList.refresh(accountIndex: account.id ?? 0);
58 + subaddress = subaddressList.getAll().first;
59 + balance = MoneroBalance(
60 + fullBalance: monero_wallet.getFullBalance(accountIndex: account.id),
61 + unlockedBalance:
62 + monero_wallet.getFullBalance(accountIndex: account.id));
63 + _setListeners();
64 + }
65 +
66 + void close() {
67 + _listner?.stop();
68 + }
69 +
70 + @override
71 + Future<void> connectToNode({@required Node node}) async {
72 + try {
73 + syncStatus = ConnectingSyncStatus();
74 + await monero_wallet.setupNode(
75 + address: node.uri,
76 + login: node.login,
77 + password: node.password,
78 + useSSL: false,
79 + // FIXME: hardcoded value
80 + isLightWallet: false); // FIXME: hardcoded value
81 + syncStatus = ConnectedSyncStatus();
82 + } catch (e) {
83 + syncStatus = FailedSyncStatus();
84 + print(e);
85 + }
86 + }
87 +
88 + @override
89 + Future<void> startSync() async {
90 + try {
91 + syncStatus = StartingSyncStatus();
92 + monero_wallet.startRefresh();
93 + } catch (e) {
94 + syncStatus = FailedSyncStatus();
95 + print(e);
96 + rethrow;
97 + }
98 + }
99 +
100 + @override
101 + Future<void> createTransaction(Object credentials) async {
102 +// final _credentials = credentials as MoneroTransactionCreationCredentials;
103 +// final transactionDescription = await transaction_history.createTransaction(
104 +// address: _credentials.address,
105 +// paymentId: _credentials.paymentId,
106 +// amount: _credentials.amount,
107 +// priorityRaw: _credentials.priority.serialize(),
108 +// accountIndex: _account.value.id);
109 +//
110 +// return PendingTransaction.fromTransactionDescription(
111 +// transactionDescription);
112 + }
113 +
114 + @override
115 + Future<void> save() async {
116 +// if (_isSaving) {
117 +// return;
118 +// }
119 +
120 + try {
121 +// _isSaving = true;
122 + await monero_wallet.store();
123 +// _isSaving = false;
124 + } catch (e) {
125 + print(e);
126 +// _isSaving = false;
127 + rethrow;
128 + }
129 + }
130 +
131 + Future<int> getNodeHeight() async => monero_wallet.getNodeHeight();
132 +
133 + Future<bool> isConnected() async => monero_wallet.isConnected();
134 +
135 + void _setListeners() {
136 + _listner?.stop();
137 + _listner = monero_wallet.setListeners(
138 + _onNewBlock, _onNeedToRefresh, _onNewTransaction);
139 + }
140 +
141 + void _askForUpdateBalance() {
142 + final fullBalance = _getFullBalance();
143 + final unlockedBalance = _getUnlockedBalance();
144 +
145 + if (balance.fullBalance != fullBalance ||
146 + balance.unlockedBalance != unlockedBalance) {
147 + balance = MoneroBalance(
148 + fullBalance: fullBalance, unlockedBalance: unlockedBalance);
149 + }
150 + }
151 +
152 + void _askForUpdateTransactionHistory() =>
153 + null; // await getHistory().update();
154 +
155 + int _getFullBalance() =>
156 + monero_wallet.getFullBalance(accountIndex: account.id);
157 +
158 + int _getUnlockedBalance() =>
159 + monero_wallet.getUnlockedBalance(accountIndex: account.id);
160 +
161 + void _onNewBlock(int height, int blocksLeft, double ptc) =>
162 + syncStatus = SyncingSyncStatus(blocksLeft, ptc);
163 +
164 + Future _onNeedToRefresh() async {
165 + if (syncStatus is FailedSyncStatus) {
166 + return;
167 + }
168 +
169 + syncStatus = SyncedSyncStatus();
170 +
171 + if (isRecovery) {
172 + _askForUpdateTransactionHistory();
173 + }
174 +
175 +// if (isRecovery && (nodeHeight - currentHeight < moneroBlockSize)) {
176 +// await setAsRecovered();
177 +// }
178 +
179 + await save();
180 + }
181 +
182 + void _onNewTransaction() {
183 + _askForUpdateBalance();
184 + _askForUpdateTransactionHistory();
185 + }
186 +}
lib/core/monero_wallet_list_service.dart new
+146
@@ -0,0 +1,146 @@
1 +import 'package:cake_wallet/core/monero_wallet.dart';
2 +import 'package:cake_wallet/core/wallet_credentials.dart';
3 +import 'package:cake_wallet/core/wallet_list_service.dart';
4 +import 'package:cake_wallet/src/domain/common/pathForWallet.dart';
5 +import 'package:cake_wallet/src/domain/common/wallet_type.dart';
6 +import 'package:cw_monero/wallet_manager.dart' as monero_wallet_manager;
7 +import 'package:cw_monero/wallet.dart' as monero_wallet;
8 +
9 +class MoneroNewWalletCredentials extends WalletCredentials {
10 + const MoneroNewWalletCredentials(
11 + {String name, String password, this.language})
12 + : super(name: name, password: password);
13 +
14 + final String language;
15 +}
16 +
17 +class MoneroRestoreWalletFromSeedCredentials extends WalletCredentials {
18 + const MoneroRestoreWalletFromSeedCredentials(
19 + {String name, String password, this.mnemonic, this.height})
20 + : super(name: name, password: password);
21 +
22 + final String mnemonic;
23 + final int height;
24 +}
25 +
26 +class MoneroRestoreWalletFromKeysCredentials extends WalletCredentials {
27 + const MoneroRestoreWalletFromKeysCredentials(
28 + {String name,
29 + String password,
30 + this.language,
31 + this.address,
32 + this.viewKey,
33 + this.spendKey,
34 + this.height})
35 + : super(name: name, password: password);
36 +
37 + final String language;
38 + final String address;
39 + final String viewKey;
40 + final String spendKey;
41 + final int height;
42 +}
43 +
44 +class MoneroWalletListService extends WalletListService<
45 + MoneroNewWalletCredentials,
46 + MoneroRestoreWalletFromSeedCredentials,
47 + MoneroRestoreWalletFromKeysCredentials> {
48 + @override
49 + Future<void> create(MoneroNewWalletCredentials credentials) async {
50 + try {
51 + final path =
52 + await pathForWallet(name: credentials.name, type: WalletType.monero);
53 +
54 + await monero_wallet_manager.createWallet(
55 + path: path,
56 + password: credentials.password,
57 + language: credentials.language);
58 +
59 + return MoneroWallet(filename: monero_wallet.getFilename())..init();
60 + } catch (e) {
61 + // TODO: Implement Exception fop wallet list service.
62 + print('MoneroWalletsManager Error: $e');
63 + rethrow;
64 + }
65 + }
66 +
67 + @override
68 + Future<bool> isWalletExit(String name) async {
69 + try {
70 + final path = await pathForWallet(name: name, type: WalletType.monero);
71 + return monero_wallet_manager.isWalletExist(path: path);
72 + } catch (e) {
73 + // TODO: Implement Exception fop wallet list service.
74 + print('MoneroWalletsManager Error: $e');
75 + rethrow;
76 + }
77 + }
78 +
79 + @override
80 + Future<void> openWallet(String name, String password) async {
81 + try {
82 + final path = await pathForWallet(name: name, type: WalletType.monero);
83 + monero_wallet_manager.openWallet(path: path, password: password);
84 +
85 +// final id = walletTypeToString(WalletType.monero).toLowerCase() + '_' + name;
86 +// final walletInfo = walletInfoSource.values
87 +// .firstWhere((info) => info.id == id, orElse: () => null);
88 +
89 + return MoneroWallet(filename: monero_wallet.getFilename())..init();
90 + } catch (e) {
91 + // TODO: Implement Exception fop wallet list service.
92 + print('MoneroWalletsManager Error: $e');
93 + rethrow;
94 + }
95 + }
96 +
97 + Future<void> remove(String wallet) async {
98 + // TODO: implement remove
99 + throw UnimplementedError();
100 + }
101 +
102 + @override
103 + Future<void> restoreFromKeys(
104 + MoneroRestoreWalletFromKeysCredentials credentials) async {
105 + try {
106 + final path =
107 + await pathForWallet(name: credentials.name, type: WalletType.monero);
108 +
109 + await monero_wallet_manager.restoreFromKeys(
110 + path: path,
111 + password: credentials.password,
112 + language: credentials.language,
113 + restoreHeight: credentials.height,
114 + address: credentials.address,
115 + viewKey: credentials.viewKey,
116 + spendKey: credentials.spendKey);
117 +
118 + return MoneroWallet(filename: monero_wallet.getFilename())..init();
119 + } catch (e) {
120 + // TODO: Implement Exception fop wallet list service.
121 + print('MoneroWalletsManager Error: $e');
122 + rethrow;
123 + }
124 + }
125 +
126 + @override
127 + Future<void> restoreFromSeed(
128 + MoneroRestoreWalletFromSeedCredentials credentials) async {
129 + try {
130 + final path =
131 + await pathForWallet(name: credentials.name, type: WalletType.monero);
132 +
133 + await monero_wallet_manager.restoreFromSeed(
134 + path: path,
135 + password: credentials.password,
136 + seed: credentials.mnemonic,
137 + restoreHeight: credentials.height);
138 +
139 + return MoneroWallet(filename: monero_wallet.getFilename())..init();
140 + } catch (e) {
141 + // TODO: Implement Exception fop wallet list service.
142 + print('MoneroWalletsManager Error: $e');
143 + rethrow;
144 + }
145 + }
146 +}
lib/core/monero_wallet_store.dart deleted
-20
@@ -1,20 +0,0 @@
1 -import 'dart:async';
2 -import 'package:cake_wallet/src/domain/common/node.dart';
3 -import 'package:cake_wallet/src/domain/common/wallet_type.dart';
4 -import 'package:mobx/mobx.dart';
5 -import 'package:cake_wallet/src/domain/common/wallet.dart';
6 -import 'package:cake_wallet/src/domain/monero/account.dart';
7 -import 'package:cake_wallet/src/domain/monero/monero_wallet.dart';
8 -import 'package:cake_wallet/src/domain/monero/subaddress.dart';
9 -import 'package:cake_wallet/src/domain/services/wallet_service.dart';
10 -import 'package:cake_wallet/src/domain/common/crypto_currency.dart';
11 -import 'package:cake_wallet/src/stores/settings/settings_store.dart';
12 -import 'package:cake_wallet/generated/i18n.dart';
13 -
14 -part 'monero_wallet_store.g.dart';
15 -
16 -class MoneroWalletStore = MoneroWalletStoreBase with _$MoneroWalletStore;
17 -
18 -abstract class MoneroWalletStoreBase with Store {
19 -
20 -}
\ No newline at end of file
lib/core/setup_pin_code_state.dart new
+15
@@ -0,0 +1,15 @@
1 +import 'package:flutter/foundation.dart';
2 +
3 +abstract class SetupPinCodeState {}
4 +
5 +class InitialSetupPinCodeState extends SetupPinCodeState {}
6 +
7 +class SetupPinCodeInProgress extends SetupPinCodeState {}
8 +
9 +class SetupPinCodeFinishedSuccessfully extends SetupPinCodeState {}
10 +
11 +class SetupPinCodeFinishedFailure extends SetupPinCodeState {
12 + SetupPinCodeFinishedFailure({@required this.error});
13 +
14 + final String error;
15 +}
\ No newline at end of file
lib/core/sign_up_store.dart deleted
-12
@@ -1,12 +0,0 @@
1 -import 'package:flutter/foundation.dart';
2 -import 'package:mobx/mobx.dart';
3 -import 'package:cake_wallet/src/domain/common/wallet_type.dart';
4 -
5 -part 'sign_up_store.g.dart';
6 -
7 -class SignUpStore = SignUpStoreBase with _$SignUpStore;
8 -
9 -
10 -abstract class SignUpStoreBase with Store {
11 -
12 -}
\ No newline at end of file
lib/core/transaction_history.dart new
+27
@@ -0,0 +1,27 @@
1 +import 'package:mobx/mobx.dart';
2 +
3 +abstract class TranasctionHistoryBase<TransactionType> {
4 + TranasctionHistoryBase() : _isUpdating = false;
5 +
6 + @observable
7 + List<TransactionType> transactions;
8 +
9 + bool _isUpdating;
10 +
11 + Future<void> update() async {
12 + if (_isUpdating) {
13 + return;
14 + }
15 +
16 + try {
17 + _isUpdating = false;
18 + transactions = await fetchTransactions();
19 + _isUpdating = true;
20 + } catch (e) {
21 + _isUpdating = false;
22 + rethrow;
23 + }
24 + }
25 +
26 + Future<List<TransactionType>> fetchTransactions();
27 +}
\ No newline at end of file
lib/core/wallet_base.dart new
+20
@@ -0,0 +1,20 @@
1 +import 'package:flutter/foundation.dart';
2 +import 'package:mobx/mobx.dart';
3 +import 'package:cake_wallet/src/domain/common/node.dart';
4 +
5 +abstract class WalletBase<BalaceType> {
6 + String get name;
7 +
8 + String get filename;
9 +
10 + @observable
11 + String address;
12 +
13 + @observable
14 + BalaceType balance;
15 +
16 + Future<void> connectToNode({@required Node node});
17 + Future<void> startSync();
18 + Future<void> createTransaction(Object credentials);
19 + Future<void> save();
20 +}
\ No newline at end of file
lib/core/wallet_creation_service.dart new
+63
@@ -0,0 +1,63 @@
1 +import 'package:cake_wallet/core/wallet_creation_state.dart';
2 +import 'package:flutter/foundation.dart';
3 +import 'package:mobx/mobx.dart';
4 +import 'package:cake_wallet/core/wallet_credentials.dart';
5 +import 'package:cake_wallet/core/bitcoin_wallet_list_service.dart';
6 +import 'package:cake_wallet/core/monero_wallet_list_service.dart';
7 +import 'package:cake_wallet/core/wallet_list_service.dart';
8 +import 'package:cake_wallet/src/domain/common/wallet_type.dart';
9 +
10 +part 'wallet_creation_service.g.dart';
11 +
12 +class WalletCreationService = WalletCreationServiceBase
13 + with _$WalletCreationService;
14 +
15 +abstract class WalletCreationServiceBase with Store {
16 + @observable
17 + WalletCreationState state;
18 +
19 + WalletListService _service;
20 +
21 + void changeWalletType({@required WalletType type}) {
22 + switch (type) {
23 + case WalletType.monero:
24 + _service = MoneroWalletListService();
25 + break;
26 + case WalletType.bitcoin:
27 + _service = BitcoinWalletListService();
28 + break;
29 + default:
30 + break;
31 + }
32 + }
33 +
34 + Future<void> create(WalletCredentials credentials) async {
35 + try {
36 + state = WalletCreating();
37 + await _service.create(credentials);
38 + state = WalletCreatedSuccessfully();
39 + } catch (e) {
40 + state = WalletCreationFailure(error: e.toString());
41 + }
42 + }
43 +
44 + Future<void> restoreFromKeys(WalletCredentials credentials) async {
45 + try {
46 + state = WalletCreating();
47 + await _service.restoreFromKeys(credentials);
48 + state = WalletCreatedSuccessfully();
49 + } catch (e) {
50 + state = WalletCreationFailure(error: e.toString());
51 + }
52 + }
53 +
54 + Future<void> restoreFromSeed(WalletCredentials credentials) async {
55 + try {
56 + state = WalletCreating();
57 + await _service.restoreFromSeed(credentials);
58 + state = WalletCreatedSuccessfully();
59 + } catch (e) {
60 + state = WalletCreationFailure(error: e.toString());
61 + }
62 + }
63 +}
lib/core/wallet_creation_state.dart new
+13
@@ -0,0 +1,13 @@
1 +import 'package:flutter/foundation.dart';
2 +
3 +abstract class WalletCreationState {}
4 +
5 +class WalletCreating extends WalletCreationState {}
6 +
7 +class WalletCreatedSuccessfully extends WalletCreationState {}
8 +
9 +class WalletCreationFailure extends WalletCreationState {
10 + WalletCreationFailure({@required this.error});
11 +
12 + final String error;
13 +}
\ No newline at end of file
lib/core/wallet_credentials.dart new
+6
@@ -0,0 +1,6 @@
1 +abstract class WalletCredentials {
2 + const WalletCredentials({this.name, this.password});
3 +
4 + final String name;
5 + final String password;
6 +}
\ No newline at end of file
lib/core/wallet_list_service.dart
+1 -282
@@ -1,24 +1,4 @@
1 -import 'package:cake_wallet/src/domain/common/wallet_type.dart';
2 -import 'package:flutter/foundation.dart';
3 -
4 -/*
5 -*
6 -* WalletCredentials
7 -*
8 -* */
9 -
10 -abstract class WalletCredentials {
11 - const WalletCredentials({this.name, this.password});
12 -
13 - final String name;
14 - final String password;
15 -}
16 -
17 -/*
18 -*
19 -* WalletListService
20 -*
21 -* */
1 +import 'package:cake_wallet/core/wallet_credentials.dart';
2
3 abstract class WalletListService<N extends WalletCredentials,
4 RFS extends WalletCredentials, RFK extends WalletCredentials> {
@@ -34,264 +14,3 @@ abstract class WalletListService<N extends WalletCredentials,
14
15 Future<void> remove(String wallet);
16 }
37 -
38 -/*
39 -*
40 -* BitcoinRestoreWalletFromSeedCredentials
41 -*
42 -* */
43 -
44 -class BitcoinNewWalletCredentials extends WalletCredentials {}
45 -
46 -/*
47 -*
48 -* BitcoinRestoreWalletFromSeedCredentials
49 -*
50 -* */
51 -
52 -class BitcoinRestoreWalletFromSeedCredentials extends WalletCredentials {
53 - const BitcoinRestoreWalletFromSeedCredentials(
54 - {String name, String password, this.mnemonic})
55 - : super(name: name, password: password);
56 -
57 - final String mnemonic;
58 -}
59 -
60 -/*
61 -*
62 -* BitcoinRestoreWalletFromWIFCredentials
63 -*
64 -* */
65 -
66 -class BitcoinRestoreWalletFromWIFCredentials extends WalletCredentials {
67 - const BitcoinRestoreWalletFromWIFCredentials(
68 - {String name, String password, this.wif})
69 - : super(name: name, password: password);
70 -
71 - final String wif;
72 -}
73 -
74 -/*
75 -*
76 -* BitcoinWalletListService
77 -*
78 -* */
79 -
80 -class BitcoinWalletListService extends WalletListService<
81 - BitcoinNewWalletCredentials,
82 - BitcoinRestoreWalletFromSeedCredentials,
83 - BitcoinRestoreWalletFromWIFCredentials> {
84 - @override
85 - Future<void> create(BitcoinNewWalletCredentials credentials) async {
86 - // TODO: implement create
87 - throw UnimplementedError();
88 - }
89 -
90 - @override
91 - Future<bool> isWalletExit(String name) async {
92 - // TODO: implement isWalletExit
93 - throw UnimplementedError();
94 - }
95 -
96 - @override
97 - Future<void> openWallet(String name, String password) async {
98 - // TODO: implement openWallet
99 - throw UnimplementedError();
100 - }
101 -
102 - Future<void> remove(String wallet) {
103 - // TODO: implement remove
104 - throw UnimplementedError();
105 - }
106 -
107 - @override
108 - Future<void> restoreFromKeys(
109 - BitcoinRestoreWalletFromWIFCredentials credentials) async {
110 - // TODO: implement restoreFromKeys
111 - throw UnimplementedError();
112 - }
113 -
114 - @override
115 - Future<void> restoreFromSeed(
116 - BitcoinRestoreWalletFromSeedCredentials credentials) async {
117 - // TODO: implement restoreFromSeed
118 - throw UnimplementedError();
119 - }
120 -}
121 -
122 -/*
123 -*
124 -* BitcoinWalletListService
125 -*
126 -* */
127 -
128 -class MoneroWalletListService extends WalletListService<
129 - BitcoinNewWalletCredentials,
130 - BitcoinRestoreWalletFromSeedCredentials,
131 - BitcoinRestoreWalletFromWIFCredentials> {
132 - @override
133 - Future<void> create(BitcoinNewWalletCredentials credentials) async {
134 - // TODO: implement create
135 - throw UnimplementedError();
136 - }
137 -
138 - @override
139 - Future<bool> isWalletExit(String name) async {
140 - // TODO: implement isWalletExit
141 - throw UnimplementedError();
142 - }
143 -
144 - @override
145 - Future<void> openWallet(String name, String password) async {
146 - // TODO: implement openWallet
147 - throw UnimplementedError();
148 - }
149 -
150 - Future<void> remove(String wallet) {
151 - // TODO: implement remove
152 - throw UnimplementedError();
153 - }
154 -
155 - @override
156 - Future<void> restoreFromKeys(
157 - BitcoinRestoreWalletFromWIFCredentials credentials) async {
158 - // TODO: implement restoreFromKeys
159 - throw UnimplementedError();
160 - }
161 -
162 - @override
163 - Future<void> restoreFromSeed(
164 - BitcoinRestoreWalletFromSeedCredentials credentials) async {
165 - // TODO: implement restoreFromSeed
166 - throw UnimplementedError();
167 - }
168 -}
169 -
170 -/*
171 -*
172 -* SignUpState
173 -*
174 -* */
175 -
176 -abstract class WalletCreationState {}
177 -
178 -class WalletCreating extends WalletCreationState {}
179 -
180 -class WalletCreatedSuccessfully extends WalletCreationState {}
181 -
182 -class WalletCreationFailure extends WalletCreationState {
183 - WalletCreationFailure({@required this.error});
184 -
185 - final String error;
186 -}
187 -
188 -/*
189 -*
190 -* WalletCreationService
191 -*
192 -* */
193 -
194 -class WalletCreationService {
195 - WalletCreationState state;
196 - WalletListService _service;
197 -
198 - void changeWalletType({@required WalletType type}) {
199 - switch (type) {
200 - case WalletType.monero:
201 - _service = MoneroWalletListService();
202 - break;
203 - case WalletType.bitcoin:
204 - _service = BitcoinWalletListService();
205 - break;
206 - default:
207 - break;
208 - }
209 - }
210 -
211 - Future<void> create(WalletCredentials credentials) async {
212 - try {
213 - state = WalletCreating();
214 - await _service.create(credentials);
215 - state = WalletCreatedSuccessfully();
216 - } catch (e) {
217 - state = WalletCreationFailure(error: e.toString());
218 - }
219 - }
220 -
221 - Future<void> restoreFromKeys(WalletCredentials credentials) async {
222 - try {
223 - state = WalletCreating();
224 - await _service.create(credentials);
225 - state = WalletCreatedSuccessfully();
226 - } catch (e) {
227 - state = WalletCreationFailure(error: e.toString());
228 - }
229 - }
230 -
231 - Future<void> restoreFromSeed(WalletCredentials credentials) async {
232 - try {
233 - state = WalletCreating();
234 - await _service.create(credentials);
235 - state = WalletCreatedSuccessfully();
236 - } catch (e) {
237 - state = WalletCreationFailure(error: e.toString());
238 - }
239 - }
240 -}
241 -
242 -/*
243 -*
244 -* AuthService
245 -*
246 -* */
247 -
248 -//abstract class LoginState {}
249 -
250 -abstract class SetupPinCodeState {}
251 -
252 -class InitialSetupPinCodeState extends SetupPinCodeState {}
253 -
254 -class SetupPinCodeInProgress extends SetupPinCodeState {}
255 -
256 -class SetupPinCodeFinishedSuccessfully extends SetupPinCodeState {}
257 -
258 -class SetupPinCodeFinishedFailure extends SetupPinCodeState {
259 - SetupPinCodeFinishedFailure({@required this.error});
260 -
261 - final String error;
262 -}
263 -
264 -class AuthService {
265 - SetupPinCodeState setupPinCodeState;
266 -
267 - Future<void> setupPinCode({@required String pin}) async {}
268 -
269 - Future<bool> authenticate({@required String pin}) async {
270 - return false;
271 - }
272 -
273 - void resetSetupPinCodeState() =>
274 - setupPinCodeState = InitialSetupPinCodeState();
275 -}
276 -
277 -/*
278 -*
279 -* SignUpService
280 -*
281 -* */
282 -
283 -class SignUpService {
284 - SignUpService(
285 - {@required this.walletCreationService, @required this.authService});
286 -
287 - WalletCreationService walletCreationService;
288 - AuthService authService;
289 -}
290 -
291 -/*
292 -*
293 -* AppService
294 -*
295 -* */
296 -
297 -class AppService {}
lib/src/domain/common/sync_status.dart
+5 -10
@@ -9,24 +9,19 @@ abstract class SyncStatus {
9 }
10
11 class SyncingSyncStatus extends SyncStatus {
12 - SyncingSyncStatus(this.height, this.blockchainHeight, this.refreshHeight);
12 + SyncingSyncStatus(this.blocksLeft, this.ptc);
13
14 - final int height;
15 - final int blockchainHeight;
16 - final int refreshHeight;
14 + final double ptc;
15 + final int blocksLeft;
16
17 @override
19 - double progress() {
20 - final line = blockchainHeight - refreshHeight;
21 - final diff = line - (blockchainHeight - height);
22 - return diff <= 0 ? 0.0 : diff / line;
23 - }
18 + double progress() => ptc;
19
20 @override
21 String title() => S.current.sync_status_syncronizing;
22
23 @override
29 - String toString() => '${blockchainHeight - height}';
24 + String toString() => '$blocksLeft';
25 }
26
27 class SyncedSyncStatus extends SyncStatus {
lib/src/domain/monero/monero_amount_format.dart
+2
@@ -11,3 +11,5 @@ String moneroAmountToString({int amount}) =>
11 moneroAmountFormat.format(cryptoAmountToDouble(amount: amount, divider: moneroAmountDivider));
12
13 double moneroAmountToDouble({int amount}) => cryptoAmountToDouble(amount: amount, divider: moneroAmountDivider);
14 +
15 +int moneroParseAmount({String amount}) => moneroAmountFormat.parse(amount).toInt();
\ No newline at end of file
lib/src/domain/monero/monero_wallet.dart
+73 -82
@@ -139,11 +139,10 @@ class MoneroWallet extends Wallet {
139 @override
140 Future updateInfo() async {
141 _name.value = await getName();
142 - final acccountList = getAccountList();
143 - acccountList.refresh();
142 + final acccountList = getAccountList()..refresh();
143 _account.value = acccountList.getAll().first;
144 final subaddressList = getSubaddress();
146 - await subaddressList.refresh(
145 + subaddressList.refresh(
146 accountIndex: _account.value != null ? _account.value.id : 0);
147 final subaddresses = subaddressList.getAll();
148 _subaddress.value = subaddresses.first;
@@ -218,7 +217,7 @@ class MoneroWallet extends Wallet {
217
218 @override
219 Future close() async {
221 - monero_wallet.closeListeners();
220 +// monero_wallet.closeListeners();
221 monero_wallet.closeCurrentWallet();
222 await _name.close();
223 await _address.close();
@@ -330,11 +329,8 @@ class MoneroWallet extends Wallet {
329
330 void changeAccount(Account account) {
331 _account.add(account);
333 -
334 - getSubaddress()
335 - .refresh(accountIndex: account.id)
336 - .then((dynamic _) => getSubaddress().getAll())
337 - .then((subaddresses) => _subaddress.value = subaddresses[0]);
332 + final subaddress = getSubaddress()..refresh(accountIndex: account.id);
333 + _subaddress.value = subaddress.getAll().first;
334 }
335
336 Future store() async {
@@ -353,77 +349,72 @@ class MoneroWallet extends Wallet {
349 }
350 }
351
356 - void setListeners() => monero_wallet.setListeners(
357 - _onNewBlock, _onNeedToRefresh, _onNewTransaction);
358 -
359 - Future _onNewBlock(int height) async {
360 - try {
361 - final nodeHeight = await getNodeHeightOrUpdate(height);
362 -
363 - if (isRecovery && _refreshHeight <= 0) {
364 - _refreshHeight = height;
365 - }
366 -
367 - if (isRecovery &&
368 - (_lastSyncHeight == 0 ||
369 - (height - _lastSyncHeight) > moneroBlockSize)) {
370 - _lastSyncHeight = height;
371 - await askForUpdateBalance();
372 - await askForUpdateTransactionHistory();
373 - }
374 -
375 - if (height > 0 && ((nodeHeight - height) < moneroBlockSize)) {
376 - _syncStatus.add(SyncedSyncStatus());
377 - } else {
378 - _syncStatus.add(SyncingSyncStatus(height, nodeHeight, _refreshHeight));
379 - }
380 - } catch (e) {
381 - print(e);
382 - }
383 - }
384 -
385 - Future _onNeedToRefresh() async {
386 - try {
387 - final currentHeight = await getCurrentHeight();
388 - final nodeHeight = await getNodeHeightOrUpdate(currentHeight);
389 -
390 - // no blocks - maybe we're not connected to the node ?
391 - if (currentHeight <= 1 || nodeHeight == 0) {
392 - return;
393 - }
394 -
395 - if (_syncStatus.value is FailedSyncStatus) {
396 - return;
397 - }
398 -
399 - await askForUpdateBalance();
400 -
401 - _syncStatus.add(SyncedSyncStatus());
402 -
403 - if (isRecovery) {
404 - await askForUpdateTransactionHistory();
405 - }
406 -
407 - if (isRecovery && (nodeHeight - currentHeight < moneroBlockSize)) {
408 - await setAsRecovered();
409 - }
410 -
411 - final now = DateTime.now().millisecondsSinceEpoch;
412 - final diff = now - _lastRefreshTime;
413 -
414 - if (diff >= 0 && diff < 60000) {
415 - return;
416 - }
417 -
418 - await store();
419 - _lastRefreshTime = now;
420 - } catch (e) {
421 - print(e);
422 - }
423 - }
424 -
425 - Future _onNewTransaction() async {
426 - await askForUpdateBalance();
427 - await askForUpdateTransactionHistory();
428 - }
352 + void setListeners() => null;
353 +// monero_wallet.setListeners(
354 +// _onNewBlock, _onNeedToRefresh, _onNewTransaction);
355 +
356 +// Future _onNewBlock(int height) async {
357 +// try {
358 +// final nodeHeight = await getNodeHeightOrUpdate(height);
359 +//
360 +// if (isRecovery && _refreshHeight <= 0) {
361 +// _refreshHeight = height;
362 +// }
363 +//
364 +// if (isRecovery &&
365 +// (_lastSyncHeight == 0 ||
366 +// (height - _lastSyncHeight) > moneroBlockSize)) {
367 +// _lastSyncHeight = height;
368 +// await askForUpdateBalance();
369 +// await askForUpdateTransactionHistory();
370 +// }
371 +//
372 +// if (height > 0 && ((nodeHeight - height) < moneroBlockSize)) {
373 +// _syncStatus.add(SyncedSyncStatus());
374 +// } else {
375 +// _syncStatus.add(SyncingSyncStatus(height, nodeHeight, _refreshHeight));
376 +// }
377 +// } catch (e) {
378 +// print(e);
379 +// }
380 +// }
381 +
382 +// Future _onNeedToRefresh() async {
383 +// try {
384 +//
385 +//
386 +// if (_syncStatus.value is FailedSyncStatus) {
387 +// return;
388 +// }
389 +//
390 +// await askForUpdateBalance();
391 +//
392 +// _syncStatus.add(SyncedSyncStatus());
393 +//
394 +// if (isRecovery) {
395 +// await askForUpdateTransactionHistory();
396 +// }
397 +//
398 +//// if (isRecovery && (nodeHeight - currentHeight < moneroBlockSize)) {
399 +//// await setAsRecovered();
400 +//// }
401 +//
402 +// final now = DateTime.now().millisecondsSinceEpoch;
403 +// final diff = now - _lastRefreshTime;
404 +//
405 +// if (diff >= 0 && diff < 60000) {
406 +// return;
407 +// }
408 +//
409 +// await store();
410 +// _lastRefreshTime = now;
411 +// } catch (e) {
412 +// print(e);
413 +// }
414 +// }
415 +
416 +// Future _onNewTransaction() async {
417 +// await askForUpdateBalance();
418 +// await askForUpdateTransactionHistory();
419 +// }
420 }
lib/src/domain/monero/subaddress_list.dart
+4 -5
@@ -16,16 +16,15 @@ class SubaddressList {
16 bool _isRefreshing;
17 bool _isUpdating;
18
19 - Future update({int accountIndex}) async {
19 + void update({int accountIndex}) {
20 if (_isUpdating) {
21 return;
22 }
23
24 try {
25 _isUpdating = true;
26 - await refresh(accountIndex: accountIndex);
27 - final subaddresses = getAll();
28 - _subaddress.add(subaddresses);
26 + refresh(accountIndex: accountIndex);
27 + _subaddress.add(getAll());
28 _isUpdating = false;
29 } catch (e) {
30 _isUpdating = false;
@@ -53,7 +52,7 @@ class SubaddressList {
52 await update();
53 }
54
56 - Future refresh({int accountIndex}) async {
55 + void refresh({int accountIndex}) {
56 if (_isRefreshing) {
57 return;
58 }