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
}