Merge pull request #735 from cypherstack/monero_changes

Possible monero shared history fix
This commit is contained in:
julian-CStack 2024-01-28 22:48:03 -06:00 committed by GitHub
commit cd03849180
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 213 additions and 109 deletions

View file

@ -37,7 +37,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
@override
Address addressFor({required int index, int account = 0}) {
String address = (cwWalletBase as MoneroWalletBase)
String address = (CwBasedInterface.cwWalletBase as MoneroWalletBase)
.getTransactionAddress(account, index);
final newReceivingAddress = Address(
@ -55,16 +55,19 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
@override
Future<void> exitCwWallet() async {
resetWalletOpenCompleter();
(cwWalletBase as MoneroWalletBase?)?.onNewBlock = null;
(cwWalletBase as MoneroWalletBase?)?.onNewTransaction = null;
(cwWalletBase as MoneroWalletBase?)?.syncStatusChanged = null;
await (cwWalletBase as MoneroWalletBase?)?.save(prioritySave: true);
(CwBasedInterface.cwWalletBase as MoneroWalletBase?)?.onNewBlock = null;
(CwBasedInterface.cwWalletBase as MoneroWalletBase?)?.onNewTransaction =
null;
(CwBasedInterface.cwWalletBase as MoneroWalletBase?)?.syncStatusChanged =
null;
await (CwBasedInterface.cwWalletBase as MoneroWalletBase?)
?.save(prioritySave: true);
}
@override
Future<void> open() async {
resetWalletOpenCompleter();
// await any previous exit
await CwBasedInterface.exitMutex.protect(() async {});
String? password;
try {
@ -73,30 +76,32 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
throw Exception("Password not found $e, $s");
}
cwWalletBase?.close();
cwWalletBase = (await cwWalletService!.openWallet(walletId, password))
as MoneroWalletBase;
CwBasedInterface.cwWalletBase?.close();
CwBasedInterface.cwWalletBase = (await CwBasedInterface.cwWalletService!
.openWallet(walletId, password)) as MoneroWalletBase;
(cwWalletBase as MoneroWalletBase?)?.onNewBlock = onNewBlock;
(cwWalletBase as MoneroWalletBase?)?.onNewTransaction = onNewTransaction;
(cwWalletBase as MoneroWalletBase?)?.syncStatusChanged = syncStatusChanged;
(CwBasedInterface.cwWalletBase as MoneroWalletBase?)?.onNewBlock =
onNewBlock;
(CwBasedInterface.cwWalletBase as MoneroWalletBase?)?.onNewTransaction =
onNewTransaction;
(CwBasedInterface.cwWalletBase as MoneroWalletBase?)?.syncStatusChanged =
syncStatusChanged;
await updateNode();
await cwWalletBase?.startSync();
await CwBasedInterface.cwWalletBase?.startSync();
unawaited(refresh());
autoSaveTimer?.cancel();
autoSaveTimer = Timer.periodic(
const Duration(seconds: 193),
(_) async => await cwWalletBase?.save(),
(_) async => await CwBasedInterface.cwWalletBase?.save(),
);
walletOpenCompleter?.complete();
}
@override
Future<Amount> estimateFeeFor(Amount amount, int feeRate) async {
if (cwWalletBase == null || cwWalletBase?.syncStatus is! SyncedSyncStatus) {
if (CwBasedInterface.cwWalletBase == null ||
CwBasedInterface.cwWalletBase?.syncStatus is! SyncedSyncStatus) {
return Amount.zeroWith(
fractionDigits: cryptoCurrency.fractionDigits,
);
@ -124,7 +129,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
int approximateFee = 0;
await estimateFeeMutex.protect(() async {
approximateFee = cwWalletBase!.calculateEstimatedFee(
approximateFee = CwBasedInterface.cwWalletBase!.calculateEstimatedFee(
priority,
amount.raw.toInt(),
);
@ -138,7 +143,9 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
@override
Future<bool> pingCheck() async {
return await (cwWalletBase as MoneroWalletBase?)?.isConnected() ?? false;
return await (CwBasedInterface.cwWalletBase as MoneroWalletBase?)
?.isConnected() ??
false;
}
@override
@ -146,7 +153,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
final node = getCurrentNode();
final host = Uri.parse(node.host).host;
await cwWalletBase?.connectToNode(
await CwBasedInterface.cwWalletBase?.connectToNode(
node: Node(
uri: "$host:${node.port}",
type: WalletType.monero,
@ -157,16 +164,15 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
@override
Future<void> updateTransactions() async {
try {
await waitForWalletOpen().timeout(const Duration(seconds: 30));
} catch (e, s) {
Logging.instance
.log("Failed to wait for wallet open: $e\n$s", level: LogLevel.Fatal);
}
final base = (CwBasedInterface.cwWalletBase as MoneroWalletBase?);
await (cwWalletBase as MoneroWalletBase?)?.updateTransactions();
final transactions =
(cwWalletBase as MoneroWalletBase?)?.transactionHistory?.transactions;
if (base == null ||
base.walletInfo.name != walletId ||
CwBasedInterface.exitMutex.isLocked) {
return;
}
await base.updateTransactions();
final transactions = base.transactionHistory?.transactions;
// final cachedTransactions =
// DB.instance.get<dynamic>(boxName: walletId, key: 'latest_tx_model')
@ -210,7 +216,8 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
final addressInfo = tx.value.additionalInfo;
final addressString =
(cwWalletBase as MoneroWalletBase?)?.getTransactionAddress(
(CwBasedInterface.cwWalletBase as MoneroWalletBase?)
?.getTransactionAddress(
addressInfo!['accountIndex'] as int,
addressInfo['addressIndex'] as int,
);
@ -256,15 +263,42 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
}
}
await mainDB.addNewTransactionData(txnsData, walletId);
await mainDB.isar.writeTxn(() async {
await mainDB.isar.transactions
.where()
.walletIdEqualTo(walletId)
.deleteAll();
for (final data in txnsData) {
final tx = data.item1;
// save transaction
await mainDB.isar.transactions.put(tx);
if (data.item2 != null) {
final address = await mainDB.getAddress(walletId, data.item2!.value);
// check if address exists in db and add if it does not
if (address == null) {
await mainDB.isar.addresses.put(data.item2!);
}
// link and save address
tx.address.value = address ?? data.item2!;
await tx.address.save();
}
}
});
}
@override
Future<void> init({bool? isRestore}) async {
cwWalletService = xmr_dart.monero
await CwBasedInterface.exitMutex.protect(() async {});
CwBasedInterface.cwWalletService = xmr_dart.monero
.createMoneroWalletService(DB.instance.moneroWalletInfoBox);
if (!(await cwWalletService!.isWalletExit(walletId)) && isRestore != true) {
if (!(await CwBasedInterface.cwWalletService!.isWalletExit(walletId)) &&
isRestore != true) {
WalletInfo walletInfo;
WalletCredentials credentials;
try {
@ -292,7 +326,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
final _walletCreationService = WalletCreationService(
secureStorage: secureStorageInterface,
walletService: cwWalletService,
walletService: CwBasedInterface.cwWalletService,
keyService: cwKeysStorage,
);
_walletCreationService.type = WalletType.monero;
@ -328,7 +362,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
wallet.close();
} catch (e, s) {
Logging.instance.log("$e\n$s", level: LogLevel.Fatal);
cwWalletBase?.close();
CwBasedInterface.cwWalletBase?.close();
}
await updateNode();
}
@ -338,14 +372,17 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
@override
Future<void> recover({required bool isRescan}) async {
await CwBasedInterface.exitMutex.protect(() async {});
if (isRescan) {
await refreshMutex.protect(() async {
// clear blockchain info
await mainDB.deleteWalletBlockchainData(walletId);
var restoreHeight = cwWalletBase?.walletInfo.restoreHeight;
var restoreHeight =
CwBasedInterface.cwWalletBase?.walletInfo.restoreHeight;
highestPercentCached = 0;
await cwWalletBase?.rescan(height: restoreHeight ?? 0);
await CwBasedInterface.cwWalletBase?.rescan(height: restoreHeight ?? 0);
});
unawaited(refresh());
return;
@ -367,7 +404,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
isar: mainDB.isar,
);
cwWalletService = xmr_dart.monero
CwBasedInterface.cwWalletService = xmr_dart.monero
.createMoneroWalletService(DB.instance.moneroWalletInfoBox);
WalletInfo walletInfo;
WalletCredentials credentials;
@ -397,7 +434,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
final cwWalletCreationService = WalletCreationService(
secureStorage: secureStorageInterface,
walletService: cwWalletService,
walletService: CwBasedInterface.cwWalletService,
keyService: cwKeysStorage,
);
cwWalletCreationService.type = WalletType.monero;
@ -425,15 +462,15 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
isar: mainDB.isar,
);
}
cwWalletBase?.close();
cwWalletBase = wallet as MoneroWalletBase;
CwBasedInterface.cwWalletBase?.close();
CwBasedInterface.cwWalletBase = wallet as MoneroWalletBase;
} catch (e, s) {
Logging.instance.log("$e\n$s", level: LogLevel.Fatal);
}
await updateNode();
await cwWalletBase?.rescan(height: credentials.height);
cwWalletBase?.close();
await CwBasedInterface.cwWalletBase?.rescan(height: credentials.height);
CwBasedInterface.cwWalletBase?.close();
} catch (e, s) {
Logging.instance.log(
"Exception rethrown from recoverFromMnemonic(): $e\n$s",
@ -475,7 +512,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
List<monero_output.Output> outputs = [];
for (final recipient in txData.recipients!) {
final output = monero_output.Output(cwWalletBase!);
final output = monero_output.Output(CwBasedInterface.cwWalletBase!);
output.address = recipient.address;
output.sendAll = isSendAll;
String amountToSend = recipient.amount.decimal.toString();
@ -490,7 +527,8 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
);
await prepareSendMutex.protect(() async {
awaitPendingTransaction = cwWalletBase!.createTransaction(tmp);
awaitPendingTransaction =
CwBasedInterface.cwWalletBase!.createTransaction(tmp);
});
} catch (e, s) {
Logging.instance.log("Exception rethrown from prepareSend(): $e\n$s",
@ -549,9 +587,13 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
@override
Future<Amount> get availableBalance async {
try {
if (CwBasedInterface.exitMutex.isLocked) {
throw Exception("Exit in progress");
}
int runningBalance = 0;
for (final entry
in (cwWalletBase as MoneroWalletBase?)!.balance!.entries) {
for (final entry in (CwBasedInterface.cwWalletBase as MoneroWalletBase?)!
.balance!
.entries) {
runningBalance += entry.value.unlockedBalance;
}
return Amount(
@ -566,8 +608,13 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
@override
Future<Amount> get totalBalance async {
try {
if (CwBasedInterface.exitMutex.isLocked) {
throw Exception("Exit in progress");
}
final balanceEntries =
(cwWalletBase as MoneroWalletBase?)?.balance?.entries;
(CwBasedInterface.cwWalletBase as MoneroWalletBase?)
?.balance
?.entries;
if (balanceEntries != null) {
int bal = 0;
for (var element in balanceEntries) {
@ -578,7 +625,8 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
fractionDigits: cryptoCurrency.fractionDigits,
);
} else {
final transactions = (cwWalletBase as MoneroWalletBase?)!
final transactions =
(CwBasedInterface.cwWalletBase as MoneroWalletBase?)!
.transactionHistory!
.transactions;
int transactionBalance = 0;

View file

@ -39,7 +39,7 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
@override
Address addressFor({required int index, int account = 0}) {
String address = (cwWalletBase as WowneroWalletBase)
String address = (CwBasedInterface.cwWalletBase as WowneroWalletBase)
.getTransactionAddress(account, index);
final newReceivingAddress = Address(
@ -57,7 +57,8 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
@override
Future<Amount> estimateFeeFor(Amount amount, int feeRate) async {
if (cwWalletBase == null || cwWalletBase?.syncStatus is! SyncedSyncStatus) {
if (CwBasedInterface.cwWalletBase == null ||
CwBasedInterface.cwWalletBase?.syncStatus is! SyncedSyncStatus) {
return Amount.zeroWith(
fractionDigits: cryptoCurrency.fractionDigits,
);
@ -112,7 +113,7 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
// unsure why this delay?
await Future<void>.delayed(const Duration(milliseconds: 500));
} catch (e) {
approximateFee = cwWalletBase!.calculateEstimatedFee(
approximateFee = CwBasedInterface.cwWalletBase!.calculateEstimatedFee(
priority,
amount.raw.toInt(),
);
@ -132,7 +133,9 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
@override
Future<bool> pingCheck() async {
return await (cwWalletBase as WowneroWalletBase?)?.isConnected() ?? false;
return await (CwBasedInterface.cwWalletBase as WowneroWalletBase?)
?.isConnected() ??
false;
}
@override
@ -140,7 +143,7 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
final node = getCurrentNode();
final host = Uri.parse(node.host).host;
await cwWalletBase?.connectToNode(
await CwBasedInterface.cwWalletBase?.connectToNode(
node: Node(
uri: "$host:${node.port}",
type: WalletType.wownero,
@ -151,9 +154,15 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
@override
Future<void> updateTransactions() async {
await (cwWalletBase as WowneroWalletBase?)?.updateTransactions();
final transactions =
(cwWalletBase as WowneroWalletBase?)?.transactionHistory?.transactions;
final base = (CwBasedInterface.cwWalletBase as WowneroWalletBase?);
if (base == null ||
base.walletInfo.name != walletId ||
CwBasedInterface.exitMutex.isLocked) {
return;
}
await base.updateTransactions();
final transactions = base.transactionHistory?.transactions;
// final cachedTransactions =
// DB.instance.get<dynamic>(boxName: walletId, key: 'latest_tx_model')
@ -197,7 +206,8 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
final addressInfo = tx.value.additionalInfo;
final addressString =
(cwWalletBase as WowneroWalletBase?)?.getTransactionAddress(
(CwBasedInterface.cwWalletBase as WowneroWalletBase?)
?.getTransactionAddress(
addressInfo!['accountIndex'] as int,
addressInfo['addressIndex'] as int,
);
@ -243,15 +253,41 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
}
}
await mainDB.addNewTransactionData(txnsData, walletId);
await mainDB.isar.writeTxn(() async {
await mainDB.isar.transactions
.where()
.walletIdEqualTo(walletId)
.deleteAll();
for (final data in txnsData) {
final tx = data.item1;
// save transaction
await mainDB.isar.transactions.put(tx);
if (data.item2 != null) {
final address = await mainDB.getAddress(walletId, data.item2!.value);
// check if address exists in db and add if it does not
if (address == null) {
await mainDB.isar.addresses.put(data.item2!);
}
// link and save address
tx.address.value = address ?? data.item2!;
await tx.address.save();
}
}
});
}
@override
Future<void> init({bool? isRestore}) async {
cwWalletService = wow_dart.wownero
await CwBasedInterface.exitMutex.protect(() async {});
CwBasedInterface.cwWalletService = wow_dart.wownero
.createWowneroWalletService(DB.instance.moneroWalletInfoBox);
if (!(await cwWalletService!.isWalletExit(walletId)) && isRestore != true) {
if (!(await CwBasedInterface.cwWalletService!.isWalletExit(walletId)) &&
isRestore != true) {
WalletInfo walletInfo;
WalletCredentials credentials;
try {
@ -280,7 +316,7 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
final _walletCreationService = WalletCreationService(
secureStorage: secureStorageInterface,
walletService: cwWalletService,
walletService: CwBasedInterface.cwWalletService,
keyService: cwKeysStorage,
);
// _walletCreationService.changeWalletType();
@ -321,7 +357,7 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
wallet.close();
} catch (e, s) {
Logging.instance.log("$e\n$s", level: LogLevel.Fatal);
cwWalletBase?.close();
CwBasedInterface.cwWalletBase?.close();
}
await updateNode();
}
@ -331,6 +367,9 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
@override
Future<void> open() async {
// await any previous exit
await CwBasedInterface.exitMutex.protect(() async {});
String? password;
try {
password = await cwKeysStorage.getWalletPassword(walletName: walletId);
@ -338,43 +377,52 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
throw Exception("Password not found $e, $s");
}
cwWalletBase?.close();
cwWalletBase = (await cwWalletService!.openWallet(walletId, password))
as WowneroWalletBase;
CwBasedInterface.cwWalletBase?.close();
CwBasedInterface.cwWalletBase = (await CwBasedInterface.cwWalletService!
.openWallet(walletId, password)) as WowneroWalletBase;
(cwWalletBase as WowneroWalletBase?)?.onNewBlock = onNewBlock;
(cwWalletBase as WowneroWalletBase?)?.onNewTransaction = onNewTransaction;
(cwWalletBase as WowneroWalletBase?)?.syncStatusChanged = syncStatusChanged;
(CwBasedInterface.cwWalletBase as WowneroWalletBase?)?.onNewBlock =
onNewBlock;
(CwBasedInterface.cwWalletBase as WowneroWalletBase?)?.onNewTransaction =
onNewTransaction;
(CwBasedInterface.cwWalletBase as WowneroWalletBase?)?.syncStatusChanged =
syncStatusChanged;
await updateNode();
await (cwWalletBase as WowneroWalletBase?)?.startSync();
await (CwBasedInterface.cwWalletBase as WowneroWalletBase?)?.startSync();
unawaited(refresh());
autoSaveTimer?.cancel();
autoSaveTimer = Timer.periodic(
const Duration(seconds: 193),
(_) async => await cwWalletBase?.save(),
(_) async => await CwBasedInterface.cwWalletBase?.save(),
);
}
@override
Future<void> exitCwWallet() async {
(cwWalletBase as WowneroWalletBase?)?.onNewBlock = null;
(cwWalletBase as WowneroWalletBase?)?.onNewTransaction = null;
(cwWalletBase as WowneroWalletBase?)?.syncStatusChanged = null;
await (cwWalletBase as WowneroWalletBase?)?.save(prioritySave: true);
(CwBasedInterface.cwWalletBase as WowneroWalletBase?)?.onNewBlock = null;
(CwBasedInterface.cwWalletBase as WowneroWalletBase?)?.onNewTransaction =
null;
(CwBasedInterface.cwWalletBase as WowneroWalletBase?)?.syncStatusChanged =
null;
await (CwBasedInterface.cwWalletBase as WowneroWalletBase?)
?.save(prioritySave: true);
}
@override
Future<void> recover({required bool isRescan}) async {
await CwBasedInterface.exitMutex.protect(() async {});
if (isRescan) {
await refreshMutex.protect(() async {
// clear blockchain info
await mainDB.deleteWalletBlockchainData(walletId);
var restoreHeight = cwWalletBase?.walletInfo.restoreHeight;
var restoreHeight =
CwBasedInterface.cwWalletBase?.walletInfo.restoreHeight;
highestPercentCached = 0;
await cwWalletBase?.rescan(height: restoreHeight ?? 0);
await CwBasedInterface.cwWalletBase?.rescan(height: restoreHeight ?? 0);
});
unawaited(refresh());
return;
@ -402,7 +450,7 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
// await DB.instance
// .put<dynamic>(boxName: walletId, key: "restoreHeight", value: height);
cwWalletService = wow_dart.wownero
CwBasedInterface.cwWalletService = wow_dart.wownero
.createWowneroWalletService(DB.instance.moneroWalletInfoBox);
WalletInfo walletInfo;
WalletCredentials credentials;
@ -432,7 +480,7 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
final cwWalletCreationService = WalletCreationService(
secureStorage: secureStorageInterface,
walletService: cwWalletService,
walletService: CwBasedInterface.cwWalletService,
keyService: cwKeysStorage,
);
cwWalletCreationService.type = WalletType.wownero;
@ -442,8 +490,8 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
walletInfo.address = wallet.walletAddresses.address;
await DB.instance
.add<WalletInfo>(boxName: WalletInfo.boxName, value: walletInfo);
cwWalletBase?.close();
cwWalletBase = wallet;
CwBasedInterface.cwWalletBase?.close();
CwBasedInterface.cwWalletBase = wallet;
if (walletInfo.address != null) {
final newReceivingAddress = await getCurrentReceivingAddress() ??
Address(
@ -467,8 +515,8 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
}
await updateNode();
await cwWalletBase?.rescan(height: credentials.height);
cwWalletBase?.close();
await CwBasedInterface.cwWalletBase?.rescan(height: credentials.height);
CwBasedInterface.cwWalletBase?.close();
} catch (e, s) {
Logging.instance.log(
"Exception rethrown from recoverFromMnemonic(): $e\n$s",
@ -510,7 +558,8 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
List<wownero_output.Output> outputs = [];
for (final recipient in txData.recipients!) {
final output = wownero_output.Output(cwWalletBase!);
final output =
wownero_output.Output(CwBasedInterface.cwWalletBase!);
output.address = recipient.address;
output.sendAll = isSendAll;
String amountToSend = recipient.amount.decimal.toString();
@ -525,7 +574,8 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
);
await prepareSendMutex.protect(() async {
awaitPendingTransaction = cwWalletBase!.createTransaction(tmp);
awaitPendingTransaction =
CwBasedInterface.cwWalletBase!.createTransaction(tmp);
});
} catch (e, s) {
Logging.instance.log("Exception rethrown from prepareSend(): $e\n$s",
@ -584,9 +634,14 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
@override
Future<Amount> get availableBalance async {
try {
if (CwBasedInterface.exitMutex.isLocked) {
throw Exception("Exit in progress");
}
int runningBalance = 0;
for (final entry
in (cwWalletBase as WowneroWalletBase?)!.balance!.entries) {
for (final entry in (CwBasedInterface.cwWalletBase as WowneroWalletBase?)!
.balance!
.entries) {
runningBalance += entry.value.unlockedBalance;
}
return Amount(
@ -601,8 +656,13 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
@override
Future<Amount> get totalBalance async {
try {
if (CwBasedInterface.exitMutex.isLocked) {
throw Exception("Exit in progress");
}
final balanceEntries =
(cwWalletBase as WowneroWalletBase?)?.balance?.entries;
(CwBasedInterface.cwWalletBase as WowneroWalletBase?)
?.balance
?.entries;
if (balanceEntries != null) {
int bal = 0;
for (var element in balanceEntries) {
@ -613,7 +673,8 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
fractionDigits: cryptoCurrency.fractionDigits,
);
} else {
final transactions = cwWalletBase!.transactionHistory!.transactions;
final transactions =
CwBasedInterface.cwWalletBase!.transactionHistory!.transactions;
int transactionBalance = 0;
for (var tx in transactions!.entries) {
if (tx.value.direction == TransactionDirection.incoming) {

View file

@ -35,8 +35,8 @@ mixin CwBasedInterface<T extends CryptonoteCurrency> on CryptonoteWallet<T>
KeyService get cwKeysStorage =>
_cwKeysStorageCached ??= KeyService(secureStorageInterface);
WalletService? cwWalletService;
WalletBase? cwWalletBase;
static WalletService? cwWalletService;
static WalletBase? cwWalletBase;
bool _hasCalledExit = false;
bool _txRefreshLock = false;
@ -46,9 +46,6 @@ mixin CwBasedInterface<T extends CryptonoteCurrency> on CryptonoteWallet<T>
double highestPercentCached = 0;
Timer? autoSaveTimer;
static bool walletOperationWaiting = false;
Future<String> pathForWalletDir({
required String name,
required WalletType type,
@ -246,13 +243,6 @@ mixin CwBasedInterface<T extends CryptonoteCurrency> on CryptonoteWallet<T>
@override
Future<void> updateBalance() async {
try {
await waitForWalletOpen().timeout(const Duration(seconds: 30));
} catch (e, s) {
Logging.instance
.log("Failed to wait for wallet open: $e\n$s", level: LogLevel.Fatal);
}
final total = await totalBalance;
final available = await availableBalance;
@ -306,14 +296,19 @@ mixin CwBasedInterface<T extends CryptonoteCurrency> on CryptonoteWallet<T>
}
}
static Mutex exitMutex = Mutex();
@override
Future<void> exit() async {
if (!_hasCalledExit) {
resetWalletOpenCompleter();
await exitMutex.protect(() async {
_hasCalledExit = true;
autoSaveTimer?.cancel();
await exitCwWallet();
cwWalletBase?.close();
cwWalletBase = null;
cwWalletService = null;
});
}
}