mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-12-22 19:39:22 +00:00
concurrent xmr/wow wallets
This commit is contained in:
parent
cdd9e078f8
commit
642f0906b8
8 changed files with 150 additions and 227 deletions
|
@ -1 +1 @@
|
||||||
Subproject commit 7186b0bb936428cba441b69f77b508d007c50fb2
|
Subproject commit fd9892cfa3ab85d50354f334a18a537b4af7d00e
|
|
@ -20,8 +20,6 @@ import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:cw_core/wallet_type.dart';
|
import 'package:cw_core/wallet_type.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_libmonero/monero/monero.dart';
|
|
||||||
import 'package:flutter_libmonero/wownero/wownero.dart';
|
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
@ -237,9 +235,6 @@ void main(List<String> args) async {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
monero.onStartup();
|
|
||||||
wownero.onStartup();
|
|
||||||
|
|
||||||
// SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
|
// SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
|
||||||
// overlays: [SystemUiOverlay.bottom]);
|
// overlays: [SystemUiOverlay.bottom]);
|
||||||
unawaited(NotificationApi.init());
|
unawaited(NotificationApi.init());
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
import '../../../../utilities/logger.dart';
|
import '../../../../utilities/logger.dart';
|
||||||
|
|
||||||
class UpdatedInBackgroundEvent {
|
class UpdatedInBackgroundEvent {
|
||||||
|
@ -15,9 +17,11 @@ class UpdatedInBackgroundEvent {
|
||||||
String walletId;
|
String walletId;
|
||||||
|
|
||||||
UpdatedInBackgroundEvent(this.message, this.walletId) {
|
UpdatedInBackgroundEvent(this.message, this.walletId) {
|
||||||
Logging.instance.log(
|
if (kDebugMode) {
|
||||||
"UpdatedInBackgroundEvent fired with message: $message",
|
Logging.instance.log(
|
||||||
level: LogLevel.Info,
|
"UpdatedInBackgroundEvent fired with message: $message",
|
||||||
);
|
level: LogLevel.Info,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:cw_wownero/api/wallet.dart' as wownero_wallet;
|
import 'package:monero/wownero.dart' as wownero;
|
||||||
|
|
||||||
import '../../../models/node_model.dart';
|
import '../../../models/node_model.dart';
|
||||||
import '../../../utilities/default_nodes.dart';
|
import '../../../utilities/default_nodes.dart';
|
||||||
|
@ -48,7 +48,7 @@ class Wownero extends CryptonoteCurrency {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool validateAddress(String address) {
|
bool validateAddress(String address) {
|
||||||
return wownero_wallet.addressValid(address);
|
return wownero.Wallet_addressValid(address, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -13,6 +13,7 @@ import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:cw_core/wallet_type.dart';
|
import 'package:cw_core/wallet_type.dart';
|
||||||
import 'package:cw_monero/api/exceptions/creation_transaction_exception.dart';
|
import 'package:cw_monero/api/exceptions/creation_transaction_exception.dart';
|
||||||
import 'package:cw_monero/monero_wallet.dart';
|
import 'package:cw_monero/monero_wallet.dart';
|
||||||
|
import 'package:cw_monero/monero_wallet_service.dart';
|
||||||
import 'package:cw_monero/pending_monero_transaction.dart';
|
import 'package:cw_monero/pending_monero_transaction.dart';
|
||||||
import 'package:decimal/decimal.dart';
|
import 'package:decimal/decimal.dart';
|
||||||
import 'package:flutter_libmonero/core/wallet_creation_service.dart';
|
import 'package:flutter_libmonero/core/wallet_creation_service.dart';
|
||||||
|
@ -73,9 +74,15 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
MoneroWalletBase? cwWalletBase;
|
||||||
|
|
||||||
|
@override
|
||||||
|
MoneroWalletService? cwWalletService;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Address addressFor({required int index, int account = 0}) {
|
Address addressFor({required int index, int account = 0}) {
|
||||||
final String address = (CwBasedInterface.cwWalletBase as MoneroWalletBase)
|
final String address = (cwWalletBase as MoneroWalletBase)
|
||||||
.getTransactionAddress(account, index);
|
.getTransactionAddress(account, index);
|
||||||
|
|
||||||
final newReceivingAddress = Address(
|
final newReceivingAddress = Address(
|
||||||
|
@ -91,22 +98,8 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
return newReceivingAddress;
|
return newReceivingAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> exitCwWallet() async {
|
|
||||||
(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
|
@override
|
||||||
Future<void> open() async {
|
Future<void> open() async {
|
||||||
// await any previous exit
|
|
||||||
await CwBasedInterface.exitMutex.protect(() async {});
|
|
||||||
|
|
||||||
String? password;
|
String? password;
|
||||||
try {
|
try {
|
||||||
password = await cwKeysStorage.getWalletPassword(walletName: walletId);
|
password = await cwKeysStorage.getWalletPassword(walletName: walletId);
|
||||||
|
@ -114,18 +107,20 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
throw Exception("Password not found $e, $s");
|
throw Exception("Password not found $e, $s");
|
||||||
}
|
}
|
||||||
|
|
||||||
CwBasedInterface.cwWalletBase?.close();
|
bool wasNull = false;
|
||||||
CwBasedInterface.cwWalletBase = (await CwBasedInterface.cwWalletService!
|
|
||||||
.openWallet(walletId, password)) as MoneroWalletBase;
|
|
||||||
|
|
||||||
(CwBasedInterface.cwWalletBase as MoneroWalletBase?)?.onNewBlock =
|
if (cwWalletBase == null) {
|
||||||
onNewBlock;
|
wasNull = true;
|
||||||
(CwBasedInterface.cwWalletBase as MoneroWalletBase?)?.onNewTransaction =
|
// cwWalletBaseT?.close();
|
||||||
onNewTransaction;
|
cwWalletBase ??= (await cwWalletService!.openWallet(walletId, password))
|
||||||
(CwBasedInterface.cwWalletBase as MoneroWalletBase?)?.syncStatusChanged =
|
as MoneroWalletBase;
|
||||||
syncStatusChanged;
|
|
||||||
|
|
||||||
await updateNode();
|
cwWalletBase?.onNewBlock ??= onNewBlock;
|
||||||
|
cwWalletBase?.onNewTransaction ??= onNewTransaction;
|
||||||
|
cwWalletBase?.syncStatusChanged ??= syncStatusChanged;
|
||||||
|
|
||||||
|
await updateNode();
|
||||||
|
}
|
||||||
|
|
||||||
Address? currentAddress = await getCurrentReceivingAddress();
|
Address? currentAddress = await getCurrentReceivingAddress();
|
||||||
if (currentAddress == null) {
|
if (currentAddress == null) {
|
||||||
|
@ -139,19 +134,23 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await CwBasedInterface.cwWalletBase?.startSync();
|
if (wasNull) {
|
||||||
|
await cwWalletBase?.startSync();
|
||||||
|
} else {
|
||||||
|
cwWalletBase?.wallet.startListeners();
|
||||||
|
}
|
||||||
unawaited(refresh());
|
unawaited(refresh());
|
||||||
|
|
||||||
autoSaveTimer?.cancel();
|
autoSaveTimer?.cancel();
|
||||||
autoSaveTimer = Timer.periodic(
|
autoSaveTimer = Timer.periodic(
|
||||||
const Duration(seconds: 193),
|
const Duration(seconds: 193),
|
||||||
(_) async => await CwBasedInterface.cwWalletBase?.save(),
|
(_) async => await cwWalletBase?.save(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Amount> estimateFeeFor(Amount amount, int feeRate) async {
|
Future<Amount> estimateFeeFor(Amount amount, int feeRate) async {
|
||||||
if (CwBasedInterface.cwWalletBase == null ||
|
if (cwWalletBase == null || cwWalletBase?.syncStatus is! SyncedSyncStatus) {
|
||||||
CwBasedInterface.cwWalletBase?.syncStatus is! SyncedSyncStatus) {
|
|
||||||
return Amount.zeroWith(
|
return Amount.zeroWith(
|
||||||
fractionDigits: cryptoCurrency.fractionDigits,
|
fractionDigits: cryptoCurrency.fractionDigits,
|
||||||
);
|
);
|
||||||
|
@ -179,7 +178,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
|
|
||||||
int approximateFee = 0;
|
int approximateFee = 0;
|
||||||
await estimateFeeMutex.protect(() async {
|
await estimateFeeMutex.protect(() async {
|
||||||
approximateFee = CwBasedInterface.cwWalletBase!.calculateEstimatedFee(
|
approximateFee = cwWalletBase!.calculateEstimatedFee(
|
||||||
priority,
|
priority,
|
||||||
amount.raw.toInt(),
|
amount.raw.toInt(),
|
||||||
);
|
);
|
||||||
|
@ -193,9 +192,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> pingCheck() async {
|
Future<bool> pingCheck() async {
|
||||||
return await (CwBasedInterface.cwWalletBase as MoneroWalletBase?)
|
return await cwWalletBase?.isConnected() ?? false;
|
||||||
?.isConnected() ??
|
|
||||||
false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -212,7 +209,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
}
|
}
|
||||||
if (_requireMutex) {
|
if (_requireMutex) {
|
||||||
await _torConnectingLock.protect(() async {
|
await _torConnectingLock.protect(() async {
|
||||||
await CwBasedInterface.cwWalletBase?.connectToNode(
|
await cwWalletBase?.connectToNode(
|
||||||
node: Node(
|
node: Node(
|
||||||
uri: "$host:${node.port}",
|
uri: "$host:${node.port}",
|
||||||
type: WalletType.monero,
|
type: WalletType.monero,
|
||||||
|
@ -224,7 +221,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await CwBasedInterface.cwWalletBase?.connectToNode(
|
await cwWalletBase?.connectToNode(
|
||||||
node: Node(
|
node: Node(
|
||||||
uri: "$host:${node.port}",
|
uri: "$host:${node.port}",
|
||||||
type: WalletType.monero,
|
type: WalletType.monero,
|
||||||
|
@ -241,11 +238,9 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<CWKeyData?> getKeys() async {
|
Future<CWKeyData?> getKeys() async {
|
||||||
final base = (CwBasedInterface.cwWalletBase as MoneroWalletBase?);
|
final base = cwWalletBase;
|
||||||
|
|
||||||
if (base == null ||
|
if (base == null || base.walletInfo.name != walletId) {
|
||||||
base.walletInfo.name != walletId ||
|
|
||||||
CwBasedInterface.exitMutex.isLocked) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,11 +255,9 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> updateTransactions() async {
|
Future<void> updateTransactions() async {
|
||||||
final base = (CwBasedInterface.cwWalletBase as MoneroWalletBase?);
|
final base = cwWalletBase;
|
||||||
|
|
||||||
if (base == null ||
|
if (base == null || base.walletInfo.name != walletId) {
|
||||||
base.walletInfo.name != walletId ||
|
|
||||||
CwBasedInterface.exitMutex.isLocked) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await base.updateTransactions();
|
await base.updateTransactions();
|
||||||
|
@ -311,9 +304,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
if (tx.value.direction == TransactionDirection.incoming) {
|
if (tx.value.direction == TransactionDirection.incoming) {
|
||||||
final addressInfo = tx.value.additionalInfo;
|
final addressInfo = tx.value.additionalInfo;
|
||||||
|
|
||||||
final addressString =
|
final addressString = cwWalletBase?.getTransactionAddress(
|
||||||
(CwBasedInterface.cwWalletBase as MoneroWalletBase?)
|
|
||||||
?.getTransactionAddress(
|
|
||||||
addressInfo!['accountIndex'] as int,
|
addressInfo!['accountIndex'] as int,
|
||||||
addressInfo['addressIndex'] as int,
|
addressInfo['addressIndex'] as int,
|
||||||
);
|
);
|
||||||
|
@ -388,12 +379,11 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> init({bool? isRestore}) async {
|
Future<void> init({bool? isRestore}) async {
|
||||||
await CwBasedInterface.exitMutex.protect(() async {});
|
cwWalletService ??= xmr_dart.monero
|
||||||
|
.createMoneroWalletService(DB.instance.moneroWalletInfoBox)
|
||||||
|
as MoneroWalletService;
|
||||||
|
|
||||||
CwBasedInterface.cwWalletService = xmr_dart.monero
|
if (!(await cwWalletService!.isWalletExist(walletId)) &&
|
||||||
.createMoneroWalletService(DB.instance.moneroWalletInfoBox);
|
|
||||||
|
|
||||||
if (!(await CwBasedInterface.cwWalletService!.isWalletExit(walletId)) &&
|
|
||||||
isRestore != true) {
|
isRestore != true) {
|
||||||
WalletInfo walletInfo;
|
WalletInfo walletInfo;
|
||||||
WalletCredentials credentials;
|
WalletCredentials credentials;
|
||||||
|
@ -422,10 +412,10 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
|
|
||||||
final _walletCreationService = WalletCreationService(
|
final _walletCreationService = WalletCreationService(
|
||||||
secureStorage: secureStorageInterface,
|
secureStorage: secureStorageInterface,
|
||||||
walletService: CwBasedInterface.cwWalletService,
|
walletService: cwWalletService!,
|
||||||
keyService: cwKeysStorage,
|
keyService: cwKeysStorage,
|
||||||
|
type: WalletType.monero,
|
||||||
);
|
);
|
||||||
_walletCreationService.type = WalletType.monero;
|
|
||||||
// To restore from a seed
|
// To restore from a seed
|
||||||
final wallet = await _walletCreationService.create(credentials);
|
final wallet = await _walletCreationService.create(credentials);
|
||||||
|
|
||||||
|
@ -459,7 +449,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
wallet.close();
|
wallet.close();
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
Logging.instance.log("$e\n$s", level: LogLevel.Fatal);
|
Logging.instance.log("$e\n$s", level: LogLevel.Fatal);
|
||||||
CwBasedInterface.cwWalletBase?.close();
|
cwWalletBase?.close();
|
||||||
}
|
}
|
||||||
await updateNode();
|
await updateNode();
|
||||||
}
|
}
|
||||||
|
@ -469,17 +459,14 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> recover({required bool isRescan}) async {
|
Future<void> recover({required bool isRescan}) async {
|
||||||
await CwBasedInterface.exitMutex.protect(() async {});
|
|
||||||
|
|
||||||
if (isRescan) {
|
if (isRescan) {
|
||||||
await refreshMutex.protect(() async {
|
await refreshMutex.protect(() async {
|
||||||
// clear blockchain info
|
// clear blockchain info
|
||||||
await mainDB.deleteWalletBlockchainData(walletId);
|
await mainDB.deleteWalletBlockchainData(walletId);
|
||||||
|
|
||||||
final restoreHeight =
|
final restoreHeight = cwWalletBase?.walletInfo.restoreHeight;
|
||||||
CwBasedInterface.cwWalletBase?.walletInfo.restoreHeight;
|
|
||||||
highestPercentCached = 0;
|
highestPercentCached = 0;
|
||||||
await CwBasedInterface.cwWalletBase?.rescan(height: restoreHeight ?? 0);
|
await cwWalletBase?.rescan(height: restoreHeight ?? 0);
|
||||||
});
|
});
|
||||||
unawaited(refresh());
|
unawaited(refresh());
|
||||||
return;
|
return;
|
||||||
|
@ -501,8 +488,9 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
isar: mainDB.isar,
|
isar: mainDB.isar,
|
||||||
);
|
);
|
||||||
|
|
||||||
CwBasedInterface.cwWalletService = xmr_dart.monero
|
cwWalletService = xmr_dart.monero
|
||||||
.createMoneroWalletService(DB.instance.moneroWalletInfoBox);
|
.createMoneroWalletService(DB.instance.moneroWalletInfoBox)
|
||||||
|
as MoneroWalletService;
|
||||||
WalletInfo walletInfo;
|
WalletInfo walletInfo;
|
||||||
WalletCredentials credentials;
|
WalletCredentials credentials;
|
||||||
final String name = walletId;
|
final String name = walletId;
|
||||||
|
@ -531,10 +519,10 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
|
|
||||||
final cwWalletCreationService = WalletCreationService(
|
final cwWalletCreationService = WalletCreationService(
|
||||||
secureStorage: secureStorageInterface,
|
secureStorage: secureStorageInterface,
|
||||||
walletService: CwBasedInterface.cwWalletService,
|
walletService: cwWalletService!,
|
||||||
keyService: cwKeysStorage,
|
keyService: cwKeysStorage,
|
||||||
|
type: WalletType.monero,
|
||||||
);
|
);
|
||||||
cwWalletCreationService.type = WalletType.monero;
|
|
||||||
// To restore from a seed
|
// To restore from a seed
|
||||||
final wallet =
|
final wallet =
|
||||||
await cwWalletCreationService.restoreFromSeed(credentials);
|
await cwWalletCreationService.restoreFromSeed(credentials);
|
||||||
|
@ -559,15 +547,15 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
isar: mainDB.isar,
|
isar: mainDB.isar,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
CwBasedInterface.cwWalletBase?.close();
|
cwWalletBase?.close();
|
||||||
CwBasedInterface.cwWalletBase = wallet as MoneroWalletBase;
|
cwWalletBase = wallet as MoneroWalletBase;
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
Logging.instance.log("$e\n$s", level: LogLevel.Fatal);
|
Logging.instance.log("$e\n$s", level: LogLevel.Fatal);
|
||||||
}
|
}
|
||||||
await updateNode();
|
await updateNode();
|
||||||
|
|
||||||
await CwBasedInterface.cwWalletBase?.rescan(height: credentials.height);
|
await cwWalletBase?.rescan(height: credentials.height);
|
||||||
CwBasedInterface.cwWalletBase?.close();
|
cwWalletBase?.close();
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
Logging.instance.log(
|
Logging.instance.log(
|
||||||
"Exception rethrown from recoverFromMnemonic(): $e\n$s",
|
"Exception rethrown from recoverFromMnemonic(): $e\n$s",
|
||||||
|
@ -610,7 +598,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
|
|
||||||
final List<monero_output.Output> outputs = [];
|
final List<monero_output.Output> outputs = [];
|
||||||
for (final recipient in txData.recipients!) {
|
for (final recipient in txData.recipients!) {
|
||||||
final output = monero_output.Output(CwBasedInterface.cwWalletBase!);
|
final output = monero_output.Output(cwWalletBase!);
|
||||||
output.address = recipient.address;
|
output.address = recipient.address;
|
||||||
output.sendAll = isSendAll;
|
output.sendAll = isSendAll;
|
||||||
final String amountToSend = recipient.amount.decimal.toString();
|
final String amountToSend = recipient.amount.decimal.toString();
|
||||||
|
@ -625,8 +613,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
);
|
);
|
||||||
|
|
||||||
await prepareSendMutex.protect(() async {
|
await prepareSendMutex.protect(() async {
|
||||||
awaitPendingTransaction =
|
awaitPendingTransaction = cwWalletBase!.createTransaction(tmp);
|
||||||
CwBasedInterface.cwWalletBase!.createTransaction(tmp);
|
|
||||||
});
|
});
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
Logging.instance.log(
|
Logging.instance.log(
|
||||||
|
@ -694,13 +681,8 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
@override
|
@override
|
||||||
Future<Amount> get availableBalance async {
|
Future<Amount> get availableBalance async {
|
||||||
try {
|
try {
|
||||||
if (CwBasedInterface.exitMutex.isLocked) {
|
|
||||||
throw Exception("Exit in progress");
|
|
||||||
}
|
|
||||||
int runningBalance = 0;
|
int runningBalance = 0;
|
||||||
for (final entry in (CwBasedInterface.cwWalletBase as MoneroWalletBase?)!
|
for (final entry in cwWalletBase!.balance!.entries) {
|
||||||
.balance!
|
|
||||||
.entries) {
|
|
||||||
runningBalance += entry.value.unlockedBalance;
|
runningBalance += entry.value.unlockedBalance;
|
||||||
}
|
}
|
||||||
return Amount(
|
return Amount(
|
||||||
|
@ -715,13 +697,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
@override
|
@override
|
||||||
Future<Amount> get totalBalance async {
|
Future<Amount> get totalBalance async {
|
||||||
try {
|
try {
|
||||||
if (CwBasedInterface.exitMutex.isLocked) {
|
final balanceEntries = cwWalletBase?.balance?.entries;
|
||||||
throw Exception("Exit in progress");
|
|
||||||
}
|
|
||||||
final balanceEntries =
|
|
||||||
(CwBasedInterface.cwWalletBase as MoneroWalletBase?)
|
|
||||||
?.balance
|
|
||||||
?.entries;
|
|
||||||
if (balanceEntries != null) {
|
if (balanceEntries != null) {
|
||||||
int bal = 0;
|
int bal = 0;
|
||||||
for (final element in balanceEntries) {
|
for (final element in balanceEntries) {
|
||||||
|
@ -732,10 +708,7 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
fractionDigits: cryptoCurrency.fractionDigits,
|
fractionDigits: cryptoCurrency.fractionDigits,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
final transactions =
|
final transactions = cwWalletBase!.transactionHistory!.transactions;
|
||||||
(CwBasedInterface.cwWalletBase as MoneroWalletBase?)!
|
|
||||||
.transactionHistory!
|
|
||||||
.transactions;
|
|
||||||
int transactionBalance = 0;
|
int transactionBalance = 0;
|
||||||
for (final tx in transactions!.entries) {
|
for (final tx in transactions!.entries) {
|
||||||
if (tx.value.direction == TransactionDirection.incoming) {
|
if (tx.value.direction == TransactionDirection.incoming) {
|
||||||
|
|
|
@ -12,9 +12,9 @@ import 'package:cw_core/wallet_credentials.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:cw_core/wallet_type.dart';
|
import 'package:cw_core/wallet_type.dart';
|
||||||
import 'package:cw_monero/api/exceptions/creation_transaction_exception.dart';
|
import 'package:cw_monero/api/exceptions/creation_transaction_exception.dart';
|
||||||
import 'package:cw_wownero/api/account_list.dart';
|
|
||||||
import 'package:cw_wownero/pending_wownero_transaction.dart';
|
import 'package:cw_wownero/pending_wownero_transaction.dart';
|
||||||
import 'package:cw_wownero/wownero_wallet.dart';
|
import 'package:cw_wownero/wownero_wallet.dart';
|
||||||
|
import 'package:cw_wownero/wownero_wallet_service.dart';
|
||||||
import 'package:decimal/decimal.dart';
|
import 'package:decimal/decimal.dart';
|
||||||
import 'package:flutter_libmonero/core/wallet_creation_service.dart';
|
import 'package:flutter_libmonero/core/wallet_creation_service.dart';
|
||||||
import 'package:flutter_libmonero/view_model/send/output.dart'
|
import 'package:flutter_libmonero/view_model/send/output.dart'
|
||||||
|
@ -76,9 +76,15 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
WowneroWalletBase? cwWalletBase;
|
||||||
|
|
||||||
|
@override
|
||||||
|
WowneroWalletService? cwWalletService;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Address addressFor({required int index, int account = 0}) {
|
Address addressFor({required int index, int account = 0}) {
|
||||||
final String address = (CwBasedInterface.cwWalletBase as WowneroWalletBase)
|
final String address = (cwWalletBase as WowneroWalletBase)
|
||||||
.getTransactionAddress(account, index);
|
.getTransactionAddress(account, index);
|
||||||
|
|
||||||
final newReceivingAddress = Address(
|
final newReceivingAddress = Address(
|
||||||
|
@ -96,8 +102,7 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Amount> estimateFeeFor(Amount amount, int feeRate) async {
|
Future<Amount> estimateFeeFor(Amount amount, int feeRate) async {
|
||||||
if (CwBasedInterface.cwWalletBase == null ||
|
if (cwWalletBase == null || cwWalletBase?.syncStatus is! SyncedSyncStatus) {
|
||||||
CwBasedInterface.cwWalletBase?.syncStatus is! SyncedSyncStatus) {
|
|
||||||
return Amount.zeroWith(
|
return Amount.zeroWith(
|
||||||
fractionDigits: cryptoCurrency.fractionDigits,
|
fractionDigits: cryptoCurrency.fractionDigits,
|
||||||
);
|
);
|
||||||
|
@ -152,7 +157,7 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
// unsure why this delay?
|
// unsure why this delay?
|
||||||
await Future<void>.delayed(const Duration(milliseconds: 500));
|
await Future<void>.delayed(const Duration(milliseconds: 500));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
approximateFee = CwBasedInterface.cwWalletBase!.calculateEstimatedFee(
|
approximateFee = cwWalletBase!.calculateEstimatedFee(
|
||||||
priority,
|
priority,
|
||||||
amount.raw.toInt(),
|
amount.raw.toInt(),
|
||||||
);
|
);
|
||||||
|
@ -172,9 +177,7 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> pingCheck() async {
|
Future<bool> pingCheck() async {
|
||||||
return await (CwBasedInterface.cwWalletBase as WowneroWalletBase?)
|
return await cwWalletBase?.isConnected() ?? false;
|
||||||
?.isConnected() ??
|
|
||||||
false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -188,7 +191,7 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
}
|
}
|
||||||
if (_requireMutex) {
|
if (_requireMutex) {
|
||||||
await _torConnectingLock.protect(() async {
|
await _torConnectingLock.protect(() async {
|
||||||
await CwBasedInterface.cwWalletBase?.connectToNode(
|
await cwWalletBase?.connectToNode(
|
||||||
node: Node(
|
node: Node(
|
||||||
uri: "$host:${node.port}",
|
uri: "$host:${node.port}",
|
||||||
type: WalletType.wownero,
|
type: WalletType.wownero,
|
||||||
|
@ -200,7 +203,7 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await CwBasedInterface.cwWalletBase?.connectToNode(
|
await cwWalletBase?.connectToNode(
|
||||||
node: Node(
|
node: Node(
|
||||||
uri: "$host:${node.port}",
|
uri: "$host:${node.port}",
|
||||||
type: WalletType.wownero,
|
type: WalletType.wownero,
|
||||||
|
@ -217,11 +220,9 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<CWKeyData?> getKeys() async {
|
Future<CWKeyData?> getKeys() async {
|
||||||
final base = (CwBasedInterface.cwWalletBase as WowneroWalletBase?);
|
final base = cwWalletBase;
|
||||||
|
|
||||||
if (base == null ||
|
if (base == null || base.walletInfo.name != walletId) {
|
||||||
base.walletInfo.name != walletId ||
|
|
||||||
CwBasedInterface.exitMutex.isLocked) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,11 +237,9 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> updateTransactions() async {
|
Future<void> updateTransactions() async {
|
||||||
final base = (CwBasedInterface.cwWalletBase as WowneroWalletBase?);
|
final base = cwWalletBase;
|
||||||
|
|
||||||
if (base == null ||
|
if (base == null || base.walletInfo.name != walletId) {
|
||||||
base.walletInfo.name != walletId ||
|
|
||||||
CwBasedInterface.exitMutex.isLocked) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await base.updateTransactions();
|
await base.updateTransactions();
|
||||||
|
@ -287,9 +286,7 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
if (tx.value.direction == TransactionDirection.incoming) {
|
if (tx.value.direction == TransactionDirection.incoming) {
|
||||||
final addressInfo = tx.value.additionalInfo;
|
final addressInfo = tx.value.additionalInfo;
|
||||||
|
|
||||||
final addressString =
|
final addressString = cwWalletBase?.getTransactionAddress(
|
||||||
(CwBasedInterface.cwWalletBase as WowneroWalletBase?)
|
|
||||||
?.getTransactionAddress(
|
|
||||||
addressInfo!['accountIndex'] as int,
|
addressInfo!['accountIndex'] as int,
|
||||||
addressInfo['addressIndex'] as int,
|
addressInfo['addressIndex'] as int,
|
||||||
);
|
);
|
||||||
|
@ -364,11 +361,11 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> init({bool? isRestore}) async {
|
Future<void> init({bool? isRestore}) async {
|
||||||
await CwBasedInterface.exitMutex.protect(() async {});
|
cwWalletService = wow_dart.wownero
|
||||||
CwBasedInterface.cwWalletService = wow_dart.wownero
|
.createWowneroWalletService(DB.instance.moneroWalletInfoBox)
|
||||||
.createWowneroWalletService(DB.instance.moneroWalletInfoBox);
|
as WowneroWalletService;
|
||||||
|
|
||||||
if (!(await CwBasedInterface.cwWalletService!.isWalletExit(walletId)) &&
|
if (!(await cwWalletService!.isWalletExist(walletId)) &&
|
||||||
isRestore != true) {
|
isRestore != true) {
|
||||||
WalletInfo walletInfo;
|
WalletInfo walletInfo;
|
||||||
WalletCredentials credentials;
|
WalletCredentials credentials;
|
||||||
|
@ -398,15 +395,16 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
|
|
||||||
final _walletCreationService = WalletCreationService(
|
final _walletCreationService = WalletCreationService(
|
||||||
secureStorage: secureStorageInterface,
|
secureStorage: secureStorageInterface,
|
||||||
walletService: CwBasedInterface.cwWalletService,
|
walletService: cwWalletService!,
|
||||||
keyService: cwKeysStorage,
|
keyService: cwKeysStorage,
|
||||||
|
type: WalletType.wownero,
|
||||||
);
|
);
|
||||||
// _walletCreationService.changeWalletType();
|
|
||||||
_walletCreationService.type = WalletType.wownero;
|
|
||||||
// To restore from a seed
|
// To restore from a seed
|
||||||
final wallet = await _walletCreationService.create(credentials);
|
final wallet = await _walletCreationService.create(credentials)
|
||||||
|
as WowneroWalletBase;
|
||||||
|
|
||||||
final height = wownerodart.Wallet_getRefreshFromBlockHeight(wptr!);
|
final height =
|
||||||
|
wownerodart.Wallet_getRefreshFromBlockHeight(wallet.wallet.wptr);
|
||||||
|
|
||||||
await info.updateRestoreHeight(
|
await info.updateRestoreHeight(
|
||||||
newRestoreHeight: height,
|
newRestoreHeight: height,
|
||||||
|
@ -433,7 +431,7 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
wallet.close();
|
wallet.close();
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
Logging.instance.log("$e\n$s", level: LogLevel.Fatal);
|
Logging.instance.log("$e\n$s", level: LogLevel.Fatal);
|
||||||
CwBasedInterface.cwWalletBase?.close();
|
cwWalletBase?.close();
|
||||||
}
|
}
|
||||||
await updateNode();
|
await updateNode();
|
||||||
}
|
}
|
||||||
|
@ -443,9 +441,6 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> open() async {
|
Future<void> open() async {
|
||||||
// await any previous exit
|
|
||||||
await CwBasedInterface.exitMutex.protect(() async {});
|
|
||||||
|
|
||||||
String? password;
|
String? password;
|
||||||
try {
|
try {
|
||||||
password = await cwKeysStorage.getWalletPassword(walletName: walletId);
|
password = await cwKeysStorage.getWalletPassword(walletName: walletId);
|
||||||
|
@ -453,18 +448,20 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
throw Exception("Password not found $e, $s");
|
throw Exception("Password not found $e, $s");
|
||||||
}
|
}
|
||||||
|
|
||||||
CwBasedInterface.cwWalletBase?.close();
|
bool wasNull = false;
|
||||||
CwBasedInterface.cwWalletBase = (await CwBasedInterface.cwWalletService!
|
|
||||||
.openWallet(walletId, password)) as WowneroWalletBase;
|
|
||||||
|
|
||||||
(CwBasedInterface.cwWalletBase as WowneroWalletBase?)?.onNewBlock =
|
if (cwWalletBase == null) {
|
||||||
onNewBlock;
|
wasNull = true;
|
||||||
(CwBasedInterface.cwWalletBase as WowneroWalletBase?)?.onNewTransaction =
|
// cwWalletBaseT?.close();
|
||||||
onNewTransaction;
|
cwWalletBase = (await cwWalletService!.openWallet(walletId, password))
|
||||||
(CwBasedInterface.cwWalletBase as WowneroWalletBase?)?.syncStatusChanged =
|
as WowneroWalletBase;
|
||||||
syncStatusChanged;
|
|
||||||
|
|
||||||
await updateNode();
|
cwWalletBase?.onNewBlock = onNewBlock;
|
||||||
|
cwWalletBase?.onNewTransaction = onNewTransaction;
|
||||||
|
cwWalletBase?.syncStatusChanged = syncStatusChanged;
|
||||||
|
|
||||||
|
await updateNode();
|
||||||
|
}
|
||||||
|
|
||||||
Address? currentAddress = await getCurrentReceivingAddress();
|
Address? currentAddress = await getCurrentReceivingAddress();
|
||||||
if (currentAddress == null) {
|
if (currentAddress == null) {
|
||||||
|
@ -478,39 +475,29 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await (CwBasedInterface.cwWalletBase as WowneroWalletBase?)?.startSync();
|
if (wasNull) {
|
||||||
|
await cwWalletBase?.startSync();
|
||||||
|
} else {
|
||||||
|
cwWalletBase?.wallet.startListeners();
|
||||||
|
}
|
||||||
unawaited(refresh());
|
unawaited(refresh());
|
||||||
autoSaveTimer?.cancel();
|
|
||||||
autoSaveTimer = Timer.periodic(
|
autoSaveTimer = Timer.periodic(
|
||||||
const Duration(seconds: 193),
|
const Duration(seconds: 193),
|
||||||
(_) async => await CwBasedInterface.cwWalletBase?.save(),
|
(_) async => await cwWalletBase?.save(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> exitCwWallet() async {
|
|
||||||
(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
|
@override
|
||||||
Future<void> recover({required bool isRescan}) async {
|
Future<void> recover({required bool isRescan}) async {
|
||||||
await CwBasedInterface.exitMutex.protect(() async {});
|
|
||||||
|
|
||||||
if (isRescan) {
|
if (isRescan) {
|
||||||
await refreshMutex.protect(() async {
|
await refreshMutex.protect(() async {
|
||||||
// clear blockchain info
|
// clear blockchain info
|
||||||
await mainDB.deleteWalletBlockchainData(walletId);
|
await mainDB.deleteWalletBlockchainData(walletId);
|
||||||
|
|
||||||
final restoreHeight =
|
final restoreHeight = cwWalletBase?.walletInfo.restoreHeight;
|
||||||
CwBasedInterface.cwWalletBase?.walletInfo.restoreHeight;
|
|
||||||
highestPercentCached = 0;
|
highestPercentCached = 0;
|
||||||
await CwBasedInterface.cwWalletBase?.rescan(height: restoreHeight ?? 0);
|
await cwWalletBase?.rescan(height: restoreHeight ?? 0);
|
||||||
});
|
});
|
||||||
unawaited(refresh());
|
unawaited(refresh());
|
||||||
return;
|
return;
|
||||||
|
@ -534,12 +521,14 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
height = max(height, 0);
|
height = max(height, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: info.updateRestoreHeight
|
await info.updateRestoreHeight(
|
||||||
// await DB.instance
|
newRestoreHeight: height,
|
||||||
// .put<dynamic>(boxName: walletId, key: "restoreHeight", value: height);
|
isar: mainDB.isar,
|
||||||
|
);
|
||||||
|
|
||||||
CwBasedInterface.cwWalletService = wow_dart.wownero
|
cwWalletService = wow_dart.wownero
|
||||||
.createWowneroWalletService(DB.instance.moneroWalletInfoBox);
|
.createWowneroWalletService(DB.instance.moneroWalletInfoBox)
|
||||||
|
as WowneroWalletService;
|
||||||
WalletInfo walletInfo;
|
WalletInfo walletInfo;
|
||||||
WalletCredentials credentials;
|
WalletCredentials credentials;
|
||||||
final String name = walletId;
|
final String name = walletId;
|
||||||
|
@ -569,14 +558,15 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
|
|
||||||
final cwWalletCreationService = WalletCreationService(
|
final cwWalletCreationService = WalletCreationService(
|
||||||
secureStorage: secureStorageInterface,
|
secureStorage: secureStorageInterface,
|
||||||
walletService: CwBasedInterface.cwWalletService,
|
walletService: cwWalletService!,
|
||||||
keyService: cwKeysStorage,
|
keyService: cwKeysStorage,
|
||||||
|
type: WalletType.wownero,
|
||||||
);
|
);
|
||||||
cwWalletCreationService.type = WalletType.wownero;
|
|
||||||
// To restore from a seed
|
// To restore from a seed
|
||||||
final wallet = await cwWalletCreationService
|
final wallet = await cwWalletCreationService
|
||||||
.restoreFromSeed(credentials) as WowneroWalletBase;
|
.restoreFromSeed(credentials) as WowneroWalletBase;
|
||||||
height = wownerodart.Wallet_getRefreshFromBlockHeight(wptr!);
|
height =
|
||||||
|
wownerodart.Wallet_getRefreshFromBlockHeight(wallet.wallet.wptr);
|
||||||
walletInfo.address = wallet.walletAddresses.address;
|
walletInfo.address = wallet.walletAddresses.address;
|
||||||
walletInfo.restoreHeight = height;
|
walletInfo.restoreHeight = height;
|
||||||
await info.updateRestoreHeight(
|
await info.updateRestoreHeight(
|
||||||
|
@ -585,8 +575,8 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
);
|
);
|
||||||
await DB.instance
|
await DB.instance
|
||||||
.add<WalletInfo>(boxName: WalletInfo.boxName, value: walletInfo);
|
.add<WalletInfo>(boxName: WalletInfo.boxName, value: walletInfo);
|
||||||
CwBasedInterface.cwWalletBase?.close();
|
cwWalletBase?.close();
|
||||||
CwBasedInterface.cwWalletBase = wallet;
|
cwWalletBase = wallet;
|
||||||
if (walletInfo.address != null) {
|
if (walletInfo.address != null) {
|
||||||
final newReceivingAddress = await getCurrentReceivingAddress() ??
|
final newReceivingAddress = await getCurrentReceivingAddress() ??
|
||||||
Address(
|
Address(
|
||||||
|
@ -610,8 +600,8 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
}
|
}
|
||||||
await updateNode();
|
await updateNode();
|
||||||
|
|
||||||
await CwBasedInterface.cwWalletBase?.rescan(height: credentials.height);
|
await cwWalletBase?.rescan(height: credentials.height);
|
||||||
CwBasedInterface.cwWalletBase?.close();
|
cwWalletBase?.close();
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
Logging.instance.log(
|
Logging.instance.log(
|
||||||
"Exception rethrown from recoverFromMnemonic(): $e\n$s",
|
"Exception rethrown from recoverFromMnemonic(): $e\n$s",
|
||||||
|
@ -654,8 +644,7 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
|
|
||||||
final List<wownero_output.Output> outputs = [];
|
final List<wownero_output.Output> outputs = [];
|
||||||
for (final recipient in txData.recipients!) {
|
for (final recipient in txData.recipients!) {
|
||||||
final output =
|
final output = wownero_output.Output(cwWalletBase!);
|
||||||
wownero_output.Output(CwBasedInterface.cwWalletBase!);
|
|
||||||
output.address = recipient.address;
|
output.address = recipient.address;
|
||||||
output.sendAll = isSendAll;
|
output.sendAll = isSendAll;
|
||||||
final String amountToSend = recipient.amount.decimal.toString();
|
final String amountToSend = recipient.amount.decimal.toString();
|
||||||
|
@ -670,8 +659,7 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
);
|
);
|
||||||
|
|
||||||
await prepareSendMutex.protect(() async {
|
await prepareSendMutex.protect(() async {
|
||||||
awaitPendingTransaction =
|
awaitPendingTransaction = cwWalletBase!.createTransaction(tmp);
|
||||||
CwBasedInterface.cwWalletBase!.createTransaction(tmp);
|
|
||||||
});
|
});
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
Logging.instance.log(
|
Logging.instance.log(
|
||||||
|
@ -739,14 +727,8 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
@override
|
@override
|
||||||
Future<Amount> get availableBalance async {
|
Future<Amount> get availableBalance async {
|
||||||
try {
|
try {
|
||||||
if (CwBasedInterface.exitMutex.isLocked) {
|
|
||||||
throw Exception("Exit in progress");
|
|
||||||
}
|
|
||||||
|
|
||||||
int runningBalance = 0;
|
int runningBalance = 0;
|
||||||
for (final entry in (CwBasedInterface.cwWalletBase as WowneroWalletBase?)!
|
for (final entry in cwWalletBase!.balance!.entries) {
|
||||||
.balance!
|
|
||||||
.entries) {
|
|
||||||
runningBalance += entry.value.unlockedBalance;
|
runningBalance += entry.value.unlockedBalance;
|
||||||
}
|
}
|
||||||
return Amount(
|
return Amount(
|
||||||
|
@ -761,13 +743,7 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
@override
|
@override
|
||||||
Future<Amount> get totalBalance async {
|
Future<Amount> get totalBalance async {
|
||||||
try {
|
try {
|
||||||
if (CwBasedInterface.exitMutex.isLocked) {
|
final balanceEntries = cwWalletBase?.balance?.entries;
|
||||||
throw Exception("Exit in progress");
|
|
||||||
}
|
|
||||||
final balanceEntries =
|
|
||||||
(CwBasedInterface.cwWalletBase as WowneroWalletBase?)
|
|
||||||
?.balance
|
|
||||||
?.entries;
|
|
||||||
if (balanceEntries != null) {
|
if (balanceEntries != null) {
|
||||||
int bal = 0;
|
int bal = 0;
|
||||||
for (final element in balanceEntries) {
|
for (final element in balanceEntries) {
|
||||||
|
@ -778,8 +754,7 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
fractionDigits: cryptoCurrency.fractionDigits,
|
fractionDigits: cryptoCurrency.fractionDigits,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
final transactions =
|
final transactions = cwWalletBase!.transactionHistory!.transactions;
|
||||||
CwBasedInterface.cwWalletBase!.transactionHistory!.transactions;
|
|
||||||
int transactionBalance = 0;
|
int transactionBalance = 0;
|
||||||
for (final tx in transactions!.entries) {
|
for (final tx in transactions!.entries) {
|
||||||
if (tx.value.direction == TransactionDirection.incoming) {
|
if (tx.value.direction == TransactionDirection.incoming) {
|
||||||
|
|
|
@ -9,20 +9,6 @@ abstract class CryptonoteWallet<T extends CryptonoteCurrency> extends Wallet<T>
|
||||||
with MnemonicInterface<T> {
|
with MnemonicInterface<T> {
|
||||||
CryptonoteWallet(super.currency);
|
CryptonoteWallet(super.currency);
|
||||||
|
|
||||||
Completer<void>? walletOpenCompleter;
|
|
||||||
|
|
||||||
void resetWalletOpenCompleter() {
|
|
||||||
if (walletOpenCompleter == null || walletOpenCompleter!.isCompleted) {
|
|
||||||
walletOpenCompleter = Completer<void>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> waitForWalletOpen() async {
|
|
||||||
if (walletOpenCompleter != null && !walletOpenCompleter!.isCompleted) {
|
|
||||||
await walletOpenCompleter!.future;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== Overrides ======================================================
|
// ========== Overrides ======================================================
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -29,7 +29,8 @@ import '../../isar/models/wallet_info.dart';
|
||||||
import '../intermediate/cryptonote_wallet.dart';
|
import '../intermediate/cryptonote_wallet.dart';
|
||||||
import 'multi_address_interface.dart';
|
import 'multi_address_interface.dart';
|
||||||
|
|
||||||
mixin CwBasedInterface<T extends CryptonoteCurrency> on CryptonoteWallet<T>
|
mixin CwBasedInterface<T extends CryptonoteCurrency, U extends WalletBase,
|
||||||
|
V extends WalletService> on CryptonoteWallet<T>
|
||||||
implements MultiAddressInterface<T> {
|
implements MultiAddressInterface<T> {
|
||||||
final prepareSendMutex = Mutex();
|
final prepareSendMutex = Mutex();
|
||||||
final estimateFeeMutex = Mutex();
|
final estimateFeeMutex = Mutex();
|
||||||
|
@ -38,10 +39,6 @@ mixin CwBasedInterface<T extends CryptonoteCurrency> on CryptonoteWallet<T>
|
||||||
KeyService get cwKeysStorage =>
|
KeyService get cwKeysStorage =>
|
||||||
_cwKeysStorageCached ??= KeyService(secureStorageInterface);
|
_cwKeysStorageCached ??= KeyService(secureStorageInterface);
|
||||||
|
|
||||||
static WalletService? cwWalletService;
|
|
||||||
static WalletBase? cwWalletBase;
|
|
||||||
|
|
||||||
bool _hasCalledExit = false;
|
|
||||||
bool _txRefreshLock = false;
|
bool _txRefreshLock = false;
|
||||||
int _lastCheckedHeight = -1;
|
int _lastCheckedHeight = -1;
|
||||||
int _txCount = 0;
|
int _txCount = 0;
|
||||||
|
@ -94,6 +91,7 @@ mixin CwBasedInterface<T extends CryptonoteCurrency> on CryptonoteWallet<T>
|
||||||
|
|
||||||
void syncStatusChanged() async {
|
void syncStatusChanged() async {
|
||||||
final syncStatus = cwWalletBase?.syncStatus;
|
final syncStatus = cwWalletBase?.syncStatus;
|
||||||
|
|
||||||
if (syncStatus != null) {
|
if (syncStatus != null) {
|
||||||
if (syncStatus.progress() == 1 && refreshMutex.isLocked) {
|
if (syncStatus.progress() == 1 && refreshMutex.isLocked) {
|
||||||
refreshMutex.release();
|
refreshMutex.release();
|
||||||
|
@ -188,11 +186,12 @@ mixin CwBasedInterface<T extends CryptonoteCurrency> on CryptonoteWallet<T>
|
||||||
|
|
||||||
// ============ Interface ====================================================
|
// ============ Interface ====================================================
|
||||||
|
|
||||||
|
U? get cwWalletBase;
|
||||||
|
V? get cwWalletService;
|
||||||
|
|
||||||
Future<Amount> get availableBalance;
|
Future<Amount> get availableBalance;
|
||||||
Future<Amount> get totalBalance;
|
Future<Amount> get totalBalance;
|
||||||
|
|
||||||
Future<void> exitCwWallet();
|
|
||||||
|
|
||||||
Future<void> open();
|
Future<void> open();
|
||||||
|
|
||||||
Address addressFor({required int index, int account = 0});
|
Address addressFor({required int index, int account = 0});
|
||||||
|
@ -303,20 +302,11 @@ mixin CwBasedInterface<T extends CryptonoteCurrency> on CryptonoteWallet<T>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Mutex exitMutex = Mutex();
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> exit() async {
|
Future<void> exit() async {
|
||||||
if (!_hasCalledExit) {
|
autoSaveTimer?.cancel();
|
||||||
await exitMutex.protect(() async {
|
await cwWalletBase?.save();
|
||||||
_hasCalledExit = true;
|
cwWalletBase?.close();
|
||||||
autoSaveTimer?.cancel();
|
|
||||||
await exitCwWallet();
|
|
||||||
cwWalletBase?.close();
|
|
||||||
cwWalletBase = null;
|
|
||||||
cwWalletService = null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
Loading…
Reference in a new issue