@@ -37,7 +37,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
37
37
38
38
@override
39
39
Address addressFor ({required int index, int account = 0 }) {
40
- String address = (cwWalletBase as MoneroWalletBase )
40
+ String address = (CwBasedInterface . cwWalletBase as MoneroWalletBase )
41
41
.getTransactionAddress (account, index);
42
42
43
43
final newReceivingAddress = Address (
@@ -55,16 +55,19 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
55
55
56
56
@override
57
57
Future <void > exitCwWallet () async {
58
- resetWalletOpenCompleter ();
59
- (cwWalletBase as MoneroWalletBase ? )? .onNewBlock = null ;
60
- (cwWalletBase as MoneroWalletBase ? )? .onNewTransaction = null ;
61
- (cwWalletBase as MoneroWalletBase ? )? .syncStatusChanged = null ;
62
- await (cwWalletBase as MoneroWalletBase ? )? .save (prioritySave: true );
58
+ (CwBasedInterface .cwWalletBase as MoneroWalletBase ? )? .onNewBlock = null ;
59
+ (CwBasedInterface .cwWalletBase as MoneroWalletBase ? )? .onNewTransaction =
60
+ null ;
61
+ (CwBasedInterface .cwWalletBase as MoneroWalletBase ? )? .syncStatusChanged =
62
+ null ;
63
+ await (CwBasedInterface .cwWalletBase as MoneroWalletBase ? )
64
+ ? .save (prioritySave: true );
63
65
}
64
66
65
67
@override
66
68
Future <void > open () async {
67
- resetWalletOpenCompleter ();
69
+ // await any previous exit
70
+ await CwBasedInterface .exitMutex.protect (() async {});
68
71
69
72
String ? password;
70
73
try {
@@ -73,30 +76,32 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
73
76
throw Exception ("Password not found $e , $s " );
74
77
}
75
78
76
- cwWalletBase? .close ();
77
- cwWalletBase = (await cwWalletService! . openWallet (walletId, password))
78
- as MoneroWalletBase ;
79
+ CwBasedInterface . cwWalletBase? .close ();
80
+ CwBasedInterface . cwWalletBase = (await CwBasedInterface . cwWalletService!
81
+ . openWallet (walletId, password)) as MoneroWalletBase ;
79
82
80
- (cwWalletBase as MoneroWalletBase ? )? .onNewBlock = onNewBlock;
81
- (cwWalletBase as MoneroWalletBase ? )? .onNewTransaction = onNewTransaction;
82
- (cwWalletBase as MoneroWalletBase ? )? .syncStatusChanged = syncStatusChanged;
83
+ (CwBasedInterface .cwWalletBase as MoneroWalletBase ? )? .onNewBlock =
84
+ onNewBlock;
85
+ (CwBasedInterface .cwWalletBase as MoneroWalletBase ? )? .onNewTransaction =
86
+ onNewTransaction;
87
+ (CwBasedInterface .cwWalletBase as MoneroWalletBase ? )? .syncStatusChanged =
88
+ syncStatusChanged;
83
89
84
90
await updateNode ();
85
91
86
- await cwWalletBase? .startSync ();
92
+ await CwBasedInterface . cwWalletBase? .startSync ();
87
93
unawaited (refresh ());
88
94
autoSaveTimer? .cancel ();
89
95
autoSaveTimer = Timer .periodic (
90
96
const Duration (seconds: 193 ),
91
- (_) async => await cwWalletBase? .save (),
97
+ (_) async => await CwBasedInterface . cwWalletBase? .save (),
92
98
);
93
-
94
- walletOpenCompleter? .complete ();
95
99
}
96
100
97
101
@override
98
102
Future <Amount > estimateFeeFor (Amount amount, int feeRate) async {
99
- if (cwWalletBase == null || cwWalletBase? .syncStatus is ! SyncedSyncStatus ) {
103
+ if (CwBasedInterface .cwWalletBase == null ||
104
+ CwBasedInterface .cwWalletBase? .syncStatus is ! SyncedSyncStatus ) {
100
105
return Amount .zeroWith (
101
106
fractionDigits: cryptoCurrency.fractionDigits,
102
107
);
@@ -124,7 +129,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
124
129
125
130
int approximateFee = 0 ;
126
131
await estimateFeeMutex.protect (() async {
127
- approximateFee = cwWalletBase! .calculateEstimatedFee (
132
+ approximateFee = CwBasedInterface . cwWalletBase! .calculateEstimatedFee (
128
133
priority,
129
134
amount.raw.toInt (),
130
135
);
@@ -138,15 +143,17 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
138
143
139
144
@override
140
145
Future <bool > pingCheck () async {
141
- return await (cwWalletBase as MoneroWalletBase ? )? .isConnected () ?? false ;
146
+ return await (CwBasedInterface .cwWalletBase as MoneroWalletBase ? )
147
+ ? .isConnected () ??
148
+ false ;
142
149
}
143
150
144
151
@override
145
152
Future <void > updateNode () async {
146
153
final node = getCurrentNode ();
147
154
148
155
final host = Uri .parse (node.host).host;
149
- await cwWalletBase? .connectToNode (
156
+ await CwBasedInterface . cwWalletBase? .connectToNode (
150
157
node: Node (
151
158
uri: "$host :${node .port }" ,
152
159
type: WalletType .monero,
@@ -157,16 +164,15 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
157
164
158
165
@override
159
166
Future <void > updateTransactions () async {
160
- try {
161
- await waitForWalletOpen ().timeout (const Duration (seconds: 30 ));
162
- } catch (e, s) {
163
- Logging .instance
164
- .log ("Failed to wait for wallet open: $e \n $s " , level: LogLevel .Fatal );
165
- }
167
+ final base = (CwBasedInterface .cwWalletBase as MoneroWalletBase ? );
166
168
167
- await (cwWalletBase as MoneroWalletBase ? )? .updateTransactions ();
168
- final transactions =
169
- (cwWalletBase as MoneroWalletBase ? )? .transactionHistory? .transactions;
169
+ if (base == null ||
170
+ base .walletInfo.name != walletId ||
171
+ CwBasedInterface .exitMutex.isLocked) {
172
+ return ;
173
+ }
174
+ await base .updateTransactions ();
175
+ final transactions = base .transactionHistory? .transactions;
170
176
171
177
// final cachedTransactions =
172
178
// DB.instance.get<dynamic>(boxName: walletId, key: 'latest_tx_model')
@@ -210,7 +216,8 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
210
216
final addressInfo = tx.value.additionalInfo;
211
217
212
218
final addressString =
213
- (cwWalletBase as MoneroWalletBase ? )? .getTransactionAddress (
219
+ (CwBasedInterface .cwWalletBase as MoneroWalletBase ? )
220
+ ? .getTransactionAddress (
214
221
addressInfo! ['accountIndex' ] as int ,
215
222
addressInfo['addressIndex' ] as int ,
216
223
);
@@ -256,15 +263,42 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
256
263
}
257
264
}
258
265
259
- await mainDB.addNewTransactionData (txnsData, walletId);
266
+ await mainDB.isar.writeTxn (() async {
267
+ await mainDB.isar.transactions
268
+ .where ()
269
+ .walletIdEqualTo (walletId)
270
+ .deleteAll ();
271
+ for (final data in txnsData) {
272
+ final tx = data.item1;
273
+
274
+ // save transaction
275
+ await mainDB.isar.transactions.put (tx);
276
+
277
+ if (data.item2 != null ) {
278
+ final address = await mainDB.getAddress (walletId, data.item2! .value);
279
+
280
+ // check if address exists in db and add if it does not
281
+ if (address == null ) {
282
+ await mainDB.isar.addresses.put (data.item2! );
283
+ }
284
+
285
+ // link and save address
286
+ tx.address.value = address ?? data.item2! ;
287
+ await tx.address.save ();
288
+ }
289
+ }
290
+ });
260
291
}
261
292
262
293
@override
263
294
Future <void > init ({bool ? isRestore}) async {
264
- cwWalletService = xmr_dart.monero
295
+ await CwBasedInterface .exitMutex.protect (() async {});
296
+
297
+ CwBasedInterface .cwWalletService = xmr_dart.monero
265
298
.createMoneroWalletService (DB .instance.moneroWalletInfoBox);
266
299
267
- if (! (await cwWalletService! .isWalletExit (walletId)) && isRestore != true ) {
300
+ if (! (await CwBasedInterface .cwWalletService! .isWalletExit (walletId)) &&
301
+ isRestore != true ) {
268
302
WalletInfo walletInfo;
269
303
WalletCredentials credentials;
270
304
try {
@@ -292,7 +326,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
292
326
293
327
final _walletCreationService = WalletCreationService (
294
328
secureStorage: secureStorageInterface,
295
- walletService: cwWalletService,
329
+ walletService: CwBasedInterface . cwWalletService,
296
330
keyService: cwKeysStorage,
297
331
);
298
332
_walletCreationService.type = WalletType .monero;
@@ -328,7 +362,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
328
362
wallet.close ();
329
363
} catch (e, s) {
330
364
Logging .instance.log ("$e \n $s " , level: LogLevel .Fatal );
331
- cwWalletBase? .close ();
365
+ CwBasedInterface . cwWalletBase? .close ();
332
366
}
333
367
await updateNode ();
334
368
}
@@ -338,14 +372,17 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
338
372
339
373
@override
340
374
Future <void > recover ({required bool isRescan}) async {
375
+ await CwBasedInterface .exitMutex.protect (() async {});
376
+
341
377
if (isRescan) {
342
378
await refreshMutex.protect (() async {
343
379
// clear blockchain info
344
380
await mainDB.deleteWalletBlockchainData (walletId);
345
381
346
- var restoreHeight = cwWalletBase? .walletInfo.restoreHeight;
382
+ var restoreHeight =
383
+ CwBasedInterface .cwWalletBase? .walletInfo.restoreHeight;
347
384
highestPercentCached = 0 ;
348
- await cwWalletBase? .rescan (height: restoreHeight ?? 0 );
385
+ await CwBasedInterface . cwWalletBase? .rescan (height: restoreHeight ?? 0 );
349
386
});
350
387
unawaited (refresh ());
351
388
return ;
@@ -367,7 +404,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
367
404
isar: mainDB.isar,
368
405
);
369
406
370
- cwWalletService = xmr_dart.monero
407
+ CwBasedInterface . cwWalletService = xmr_dart.monero
371
408
.createMoneroWalletService (DB .instance.moneroWalletInfoBox);
372
409
WalletInfo walletInfo;
373
410
WalletCredentials credentials;
@@ -397,7 +434,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
397
434
398
435
final cwWalletCreationService = WalletCreationService (
399
436
secureStorage: secureStorageInterface,
400
- walletService: cwWalletService,
437
+ walletService: CwBasedInterface . cwWalletService,
401
438
keyService: cwKeysStorage,
402
439
);
403
440
cwWalletCreationService.type = WalletType .monero;
@@ -425,15 +462,15 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
425
462
isar: mainDB.isar,
426
463
);
427
464
}
428
- cwWalletBase? .close ();
429
- cwWalletBase = wallet as MoneroWalletBase ;
465
+ CwBasedInterface . cwWalletBase? .close ();
466
+ CwBasedInterface . cwWalletBase = wallet as MoneroWalletBase ;
430
467
} catch (e, s) {
431
468
Logging .instance.log ("$e \n $s " , level: LogLevel .Fatal );
432
469
}
433
470
await updateNode ();
434
471
435
- await cwWalletBase? .rescan (height: credentials.height);
436
- cwWalletBase? .close ();
472
+ await CwBasedInterface . cwWalletBase? .rescan (height: credentials.height);
473
+ CwBasedInterface . cwWalletBase? .close ();
437
474
} catch (e, s) {
438
475
Logging .instance.log (
439
476
"Exception rethrown from recoverFromMnemonic(): $e \n $s " ,
@@ -475,7 +512,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
475
512
476
513
List <monero_output.Output > outputs = [];
477
514
for (final recipient in txData.recipients! ) {
478
- final output = monero_output.Output (cwWalletBase! );
515
+ final output = monero_output.Output (CwBasedInterface . cwWalletBase! );
479
516
output.address = recipient.address;
480
517
output.sendAll = isSendAll;
481
518
String amountToSend = recipient.amount.decimal.toString ();
@@ -490,7 +527,8 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
490
527
);
491
528
492
529
await prepareSendMutex.protect (() async {
493
- awaitPendingTransaction = cwWalletBase! .createTransaction (tmp);
530
+ awaitPendingTransaction =
531
+ CwBasedInterface .cwWalletBase! .createTransaction (tmp);
494
532
});
495
533
} catch (e, s) {
496
534
Logging .instance.log ("Exception rethrown from prepareSend(): $e \n $s " ,
@@ -549,9 +587,13 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
549
587
@override
550
588
Future <Amount > get availableBalance async {
551
589
try {
590
+ if (CwBasedInterface .exitMutex.isLocked) {
591
+ throw Exception ("Exit in progress" );
592
+ }
552
593
int runningBalance = 0 ;
553
- for (final entry
554
- in (cwWalletBase as MoneroWalletBase ? )! .balance! .entries) {
594
+ for (final entry in (CwBasedInterface .cwWalletBase as MoneroWalletBase ? )!
595
+ .balance!
596
+ .entries) {
555
597
runningBalance += entry.value.unlockedBalance;
556
598
}
557
599
return Amount (
@@ -566,8 +608,13 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
566
608
@override
567
609
Future <Amount > get totalBalance async {
568
610
try {
611
+ if (CwBasedInterface .exitMutex.isLocked) {
612
+ throw Exception ("Exit in progress" );
613
+ }
569
614
final balanceEntries =
570
- (cwWalletBase as MoneroWalletBase ? )? .balance? .entries;
615
+ (CwBasedInterface .cwWalletBase as MoneroWalletBase ? )
616
+ ? .balance
617
+ ? .entries;
571
618
if (balanceEntries != null ) {
572
619
int bal = 0 ;
573
620
for (var element in balanceEntries) {
@@ -578,9 +625,10 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
578
625
fractionDigits: cryptoCurrency.fractionDigits,
579
626
);
580
627
} else {
581
- final transactions = (cwWalletBase as MoneroWalletBase ? )!
582
- .transactionHistory!
583
- .transactions;
628
+ final transactions =
629
+ (CwBasedInterface .cwWalletBase as MoneroWalletBase ? )!
630
+ .transactionHistory!
631
+ .transactions;
584
632
int transactionBalance = 0 ;
585
633
for (var tx in transactions! .entries) {
586
634
if (tx.value.direction == TransactionDirection .incoming) {
0 commit comments