monero background sync view key update

This commit is contained in:
Matthew Fosse 2024-12-26 16:31:00 -05:00
parent 585ced1c21
commit 08aed18f19
11 changed files with 186 additions and 97 deletions

View file

@ -453,7 +453,7 @@ abstract class ElectrumWalletBase
@action @action
@override @override
Future<void> startSync() async { Future<void> startSync({bool isBackgroundSync = false}) async {
try { try {
if (syncStatus is SyncronizingSyncStatus) { if (syncStatus is SyncronizingSyncStatus) {
return; return;

View file

@ -65,9 +65,9 @@ abstract class WalletBase<BalanceType extends Balance, HistoryType extends Trans
// there is a default definition here because only coins with a pow node (nano based) need to override this // there is a default definition here because only coins with a pow node (nano based) need to override this
Future<void> connectToPowNode({required Node node}) async {} Future<void> connectToPowNode({required Node node}) async {}
Future<void> startSync(); Future<void> startSync({bool isBackgroundSync = false});
Future<void> stopSync() async {} Future<void> stopSync({bool isBackgroundSync = false}) async {}
Future<PendingTransaction> createTransaction(Object credentials); Future<PendingTransaction> createTransaction(Object credentials);

View file

@ -300,7 +300,7 @@ abstract class EVMChainWalletBase
@action @action
@override @override
Future<void> startSync() async { Future<void> startSync({bool isBackgroundSync = false}) async {
try { try {
syncStatus = AttemptingSyncStatus(); syncStatus = AttemptingSyncStatus();
await _updateBalance(); await _updateBalance();

View file

@ -32,8 +32,7 @@ String getFilename() => monero.Wallet_filename(wptr!);
String getSeed() { String getSeed() {
// monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed); // monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed);
final cakepolyseed = final cakepolyseed = monero.Wallet_getCacheAttribute(wptr!, key: "cakewallet.seed");
monero.Wallet_getCacheAttribute(wptr!, key: "cakewallet.seed");
if (cakepolyseed != "") { if (cakepolyseed != "") {
return cakepolyseed; return cakepolyseed;
} }
@ -48,11 +47,21 @@ String getSeed() {
String getSeedLegacy(String? language) { String getSeedLegacy(String? language) {
var legacy = monero.Wallet_seed(wptr!, seedOffset: ''); var legacy = monero.Wallet_seed(wptr!, seedOffset: '');
switch (language) { switch (language) {
case "Chinese (Traditional)": language = "Chinese (simplified)"; break; case "Chinese (Traditional)":
case "Chinese (Simplified)": language = "Chinese (simplified)"; break; language = "Chinese (simplified)";
case "Korean": language = "English"; break; break;
case "Czech": language = "English"; break; case "Chinese (Simplified)":
case "Japanese": language = "English"; break; language = "Chinese (simplified)";
break;
case "Korean":
language = "English";
break;
case "Czech":
language = "English";
break;
case "Japanese":
language = "English";
break;
} }
if (monero.Wallet_status(wptr!) != 0) { if (monero.Wallet_status(wptr!) != 0) {
monero.Wallet_setSeedLanguage(wptr!, language: language ?? "English"); monero.Wallet_setSeedLanguage(wptr!, language: language ?? "English");
@ -72,14 +81,14 @@ Map<int, Map<int, Map<int, String>>> addressCache = {};
String getAddress({int accountIndex = 0, int addressIndex = 0}) { String getAddress({int accountIndex = 0, int addressIndex = 0}) {
// printV("getaddress: ${accountIndex}/${addressIndex}: ${monero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex)}: ${monero.Wallet_address(wptr!, accountIndex: accountIndex, addressIndex: addressIndex)}"); // printV("getaddress: ${accountIndex}/${addressIndex}: ${monero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex)}: ${monero.Wallet_address(wptr!, accountIndex: accountIndex, addressIndex: addressIndex)}");
while (monero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex)-1 < addressIndex) { while (monero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex) - 1 < addressIndex) {
printV("adding subaddress"); printV("adding subaddress");
monero.Wallet_addSubaddress(wptr!, accountIndex: accountIndex); monero.Wallet_addSubaddress(wptr!, accountIndex: accountIndex);
} }
addressCache[wptr!.address] ??= {}; addressCache[wptr!.address] ??= {};
addressCache[wptr!.address]![accountIndex] ??= {}; addressCache[wptr!.address]![accountIndex] ??= {};
addressCache[wptr!.address]![accountIndex]![addressIndex] ??= monero.Wallet_address(wptr!, addressCache[wptr!.address]![accountIndex]![addressIndex] ??=
accountIndex: accountIndex, addressIndex: addressIndex); monero.Wallet_address(wptr!, accountIndex: accountIndex, addressIndex: addressIndex);
return addressCache[wptr!.address]![accountIndex]![addressIndex]!; return addressCache[wptr!.address]![accountIndex]![addressIndex]!;
} }
@ -132,7 +141,8 @@ Future<bool> setupNodeSync(
if (kDebugMode) { if (kDebugMode) {
monero.Wallet_init3( monero.Wallet_init3(
wptr!, argv0: '', wptr!,
argv0: '',
defaultLogBaseName: 'moneroc', defaultLogBaseName: 'moneroc',
console: true, console: true,
logPath: '', logPath: '',
@ -147,17 +157,32 @@ void startRefreshSync() {
monero.Wallet_startRefresh(wptr!); monero.Wallet_startRefresh(wptr!);
} }
void setupBackgroundSync(
{required int backgroundSyncType,
required String walletPassword,
required String backgroundCachePassword}) {
monero.Wallet_setupBackgroundSync(wptr!,
backgroundSyncType: backgroundSyncType,
walletPassword: walletPassword,
backgroundCachePassword: backgroundCachePassword);
}
void startBackgroundSync() {
monero.Wallet_startBackgroundSync(wptr!);
}
void stopBackgroundSync(String walletPassword) {
monero.Wallet_stopBackgroundSync(wptr!, walletPassword);
}
void setRefreshFromBlockHeight({required int height}) => void setRefreshFromBlockHeight({required int height}) =>
monero.Wallet_setRefreshFromBlockHeight(wptr!, monero.Wallet_setRefreshFromBlockHeight(wptr!, refresh_from_block_height: height);
refresh_from_block_height: height);
void setRecoveringFromSeed({required bool isRecovery}) => void setRecoveringFromSeed({required bool isRecovery}) =>
monero.Wallet_setRecoveringFromSeed(wptr!, recoveringFromSeed: isRecovery); monero.Wallet_setRecoveringFromSeed(wptr!, recoveringFromSeed: isRecovery);
final storeMutex = Mutex(); final storeMutex = Mutex();
int lastStorePointer = 0; int lastStorePointer = 0;
int lastStoreHeight = 0; int lastStoreHeight = 0;
void storeSync({bool force = false}) async { void storeSync({bool force = false}) async {
@ -227,8 +252,7 @@ class SyncListener {
_cachedBlockchainHeight = 0; _cachedBlockchainHeight = 0;
_lastKnownBlockHeight = 0; _lastKnownBlockHeight = 0;
_initialSyncHeight = 0; _initialSyncHeight = 0;
_updateSyncInfoTimer ??= _updateSyncInfoTimer ??= Timer.periodic(Duration(milliseconds: 1200), (_) async {
Timer.periodic(Duration(milliseconds: 1200), (_) async {
if (isNewTransactionExist()) { if (isNewTransactionExist()) {
onNewTransaction(); onNewTransaction();
} }
@ -267,8 +291,8 @@ class SyncListener {
void stop() => _updateSyncInfoTimer?.cancel(); void stop() => _updateSyncInfoTimer?.cancel();
} }
SyncListener setListeners(void Function(int, int, double) onNewBlock, SyncListener setListeners(
void Function() onNewTransaction) { void Function(int, int, double) onNewBlock, void Function() onNewTransaction) {
final listener = SyncListener(onNewBlock, onNewTransaction); final listener = SyncListener(onNewBlock, onNewTransaction);
// setListenerNative(); // setListenerNative();
return listener; return listener;
@ -330,8 +354,7 @@ String getSubaddressLabel(int accountIndex, int addressIndex) {
accountIndex: accountIndex, addressIndex: addressIndex); accountIndex: accountIndex, addressIndex: addressIndex);
} }
Future setTrustedDaemon(bool trusted) async => Future setTrustedDaemon(bool trusted) async => monero.Wallet_setTrustedDaemon(wptr!, arg: trusted);
monero.Wallet_setTrustedDaemon(wptr!, arg: trusted);
Future<bool> trustedDaemon() async => monero.Wallet_trustedDaemon(wptr!); Future<bool> trustedDaemon() async => monero.Wallet_trustedDaemon(wptr!);
@ -340,5 +363,6 @@ String signMessage(String message, {String address = ""}) {
} }
bool verifyMessage(String message, String address, String signature) { bool verifyMessage(String message, String address, String signature) {
return monero.Wallet_verifySignedMessage(wptr!, message: message, address: address, signature: signature); return monero.Wallet_verifySignedMessage(wptr!,
message: message, address: address, signature: signature);
} }

View file

@ -158,10 +158,10 @@ abstract class MoneroWalletBase
} }
} }
_autoSaveTimer = Timer.periodic( _autoSaveTimer =
Duration(seconds: _autoSaveInterval), (_) async => await save()); Timer.periodic(Duration(seconds: _autoSaveInterval), (_) async => await save());
// update transaction details after restore // update transaction details after restore
walletAddresses.subaddressList.update(accountIndex: walletAddresses.account?.id??0); walletAddresses.subaddressList.update(accountIndex: walletAddresses.account?.id ?? 0);
} }
@override @override
@ -197,7 +197,19 @@ abstract class MoneroWalletBase
} }
@override @override
Future<void> startSync() async { Future<void> startSync({bool isBackgroundSync = false}) async {
if (isBackgroundSync) {
try {
syncStatus = AttemptingSyncStatus();
monero_wallet.startBackgroundSync();
return;
} catch (e) {
syncStatus = FailedSyncStatus();
printV(e);
rethrow;
}
}
try { try {
_assertInitialHeight(); _assertInitialHeight();
} catch (_) { } catch (_) {
@ -219,6 +231,11 @@ abstract class MoneroWalletBase
try { try {
syncStatus = AttemptingSyncStatus(); syncStatus = AttemptingSyncStatus();
monero_wallet.startRefresh(); monero_wallet.startRefresh();
monero_wallet.setupBackgroundSync(
backgroundSyncType: 2,
walletPassword: password,
backgroundCachePassword: "testing-cache-password",
);
_setListeners(); _setListeners();
_listener?.start(); _listener?.start();
} catch (e) { } catch (e) {
@ -259,9 +276,13 @@ abstract class MoneroWalletBase
} }
@override @override
Future<void> stopSync() async { Future<void> stopSync({bool isBackgroundSync = false}) async {
syncStatus = NotConnectedSyncStatus(); syncStatus = NotConnectedSyncStatus();
_listener?.stop(); _listener?.stop();
if (isBackgroundSync) {
monero_wallet.stopBackgroundSync(password);
return;
}
// TODO: find a better way to stop syncing than setting an invalid address: // TODO: find a better way to stop syncing than setting an invalid address:
monero_wallet.setupNode(address: ""); monero_wallet.setupNode(address: "");
} }
@ -307,8 +328,7 @@ abstract class MoneroWalletBase
throw MoneroTransactionCreationException('You do not have enough XMR to send this amount.'); throw MoneroTransactionCreationException('You do not have enough XMR to send this amount.');
} }
if (inputs.isEmpty) MoneroTransactionCreationException( if (inputs.isEmpty) MoneroTransactionCreationException('No inputs selected');
'No inputs selected');
final moneroOutputs = outputs.map((output) { final moneroOutputs = outputs.map((output) {
final outputAddress = output.isParsedAddress ? output.extractedAddress : output.address; final outputAddress = output.isParsedAddress ? output.extractedAddress : output.address;
@ -336,17 +356,14 @@ abstract class MoneroWalletBase
// 'You do not have enough unlocked balance. Unlocked: $formattedBalance. Transaction amount: ${output.cryptoAmount}.'); // 'You do not have enough unlocked balance. Unlocked: $formattedBalance. Transaction amount: ${output.cryptoAmount}.');
// } // }
final estimatedFee = final estimatedFee = calculateEstimatedFee(_credentials.priority, formattedAmount);
calculateEstimatedFee(_credentials.priority, formattedAmount); if (inputs.isEmpty) MoneroTransactionCreationException('No inputs selected');
if (inputs.isEmpty) MoneroTransactionCreationException( pendingTransactionDescription = await transaction_history.createTransaction(
'No inputs selected'); address: address!,
pendingTransactionDescription = amount: amount,
await transaction_history.createTransaction( priorityRaw: _credentials.priority.serialize(),
address: address!, accountIndex: walletAddresses.account!.id,
amount: amount, preferredInputs: inputs);
priorityRaw: _credentials.priority.serialize(),
accountIndex: walletAddresses.account!.id,
preferredInputs: inputs);
} }
// final status = monero.PendingTransaction_status(pendingTransactionDescription); // final status = monero.PendingTransaction_status(pendingTransactionDescription);
@ -498,7 +515,8 @@ abstract class MoneroWalletBase
for (var i = 0; i < coinCount; i++) { for (var i = 0; i < coinCount; i++) {
final coin = getCoin(i); final coin = getCoin(i);
final coinSpent = monero.CoinsInfo_spent(coin); final coinSpent = monero.CoinsInfo_spent(coin);
if (coinSpent == false && monero.CoinsInfo_subaddrAccount(coin) == walletAddresses.account!.id) { if (coinSpent == false &&
monero.CoinsInfo_subaddrAccount(coin) == walletAddresses.account!.id) {
final unspent = MoneroUnspent( final unspent = MoneroUnspent(
monero.CoinsInfo_address(coin), monero.CoinsInfo_address(coin),
monero.CoinsInfo_hash(coin), monero.CoinsInfo_hash(coin),
@ -600,8 +618,7 @@ abstract class MoneroWalletBase
Future<Map<String, MoneroTransactionInfo>> fetchTransactions() async { Future<Map<String, MoneroTransactionInfo>> fetchTransactions() async {
transaction_history.refreshTransactions(); transaction_history.refreshTransactions();
return (await _getAllTransactionsOfAccount(walletAddresses.account?.id)) return (await _getAllTransactionsOfAccount(walletAddresses.account?.id))
.fold<Map<String, MoneroTransactionInfo>>( .fold<Map<String, MoneroTransactionInfo>>(<String, MoneroTransactionInfo>{},
<String, MoneroTransactionInfo>{},
(Map<String, MoneroTransactionInfo> acc, MoneroTransactionInfo tx) { (Map<String, MoneroTransactionInfo> acc, MoneroTransactionInfo tx) {
acc[tx.id] = tx; acc[tx.id] = tx;
return acc; return acc;
@ -630,15 +647,12 @@ abstract class MoneroWalletBase
monero_wallet.getSubaddressLabel(accountIndex, addressIndex); monero_wallet.getSubaddressLabel(accountIndex, addressIndex);
Future<List<MoneroTransactionInfo>> _getAllTransactionsOfAccount(int? accountIndex) async => Future<List<MoneroTransactionInfo>> _getAllTransactionsOfAccount(int? accountIndex) async =>
(await transaction_history (await transaction_history.getAllTransactions())
.getAllTransactions())
.map( .map(
(row) => MoneroTransactionInfo( (row) => MoneroTransactionInfo(
row.hash, row.hash,
row.blockheight, row.blockheight,
row.isSpend row.isSpend ? TransactionDirection.outgoing : TransactionDirection.incoming,
? TransactionDirection.outgoing
: TransactionDirection.incoming,
row.timeStamp, row.timeStamp,
row.isPending, row.isPending,
row.amount, row.amount,
@ -708,8 +722,7 @@ abstract class MoneroWalletBase
void _askForUpdateBalance() { void _askForUpdateBalance() {
final unlockedBalance = _getUnlockedBalance(); final unlockedBalance = _getUnlockedBalance();
final fullBalance = monero_wallet.getFullBalance( final fullBalance = monero_wallet.getFullBalance(accountIndex: walletAddresses.account!.id);
accountIndex: walletAddresses.account!.id);
final frozenBalance = _getFrozenBalance(); final frozenBalance = _getFrozenBalance();
if (balance[currency]!.fullBalance != fullBalance || if (balance[currency]!.fullBalance != fullBalance ||
balance[currency]!.unlockedBalance != unlockedBalance || balance[currency]!.unlockedBalance != unlockedBalance ||
@ -730,8 +743,7 @@ abstract class MoneroWalletBase
var frozenBalance = 0; var frozenBalance = 0;
for (var coin in unspentCoinsInfo.values.where((element) => for (var coin in unspentCoinsInfo.values.where((element) =>
element.walletId == id && element.walletId == id && element.accountIndex == walletAddresses.account!.id)) {
element.accountIndex == walletAddresses.account!.id)) {
if (coin.isFrozen && !coin.isSending) frozenBalance += coin.value; if (coin.isFrozen && !coin.isSending) frozenBalance += coin.value;
} }
return frozenBalance; return frozenBalance;
@ -805,8 +817,7 @@ abstract class MoneroWalletBase
} }
void setLedgerConnection(LedgerConnection connection) { void setLedgerConnection(LedgerConnection connection) {
final dummyWPtr = wptr ?? final dummyWPtr = wptr ?? monero.WalletManager_openWallet(wmPtr, path: '', password: '');
monero.WalletManager_openWallet(wmPtr, path: '', password: '');
enableLedgerExchange(dummyWPtr, connection); enableLedgerExchange(dummyWPtr, connection);
} }
} }

View file

@ -343,7 +343,7 @@ abstract class NanoWalletBase
@action @action
@override @override
Future<void> startSync() async { Future<void> startSync({bool isBackgroundSync = false}) async {
try { try {
syncStatus = AttemptingSyncStatus(); syncStatus = AttemptingSyncStatus();

View file

@ -367,7 +367,7 @@ abstract class SolanaWalletBase
@action @action
@override @override
Future<void> startSync() async { Future<void> startSync({bool isBackgroundSync = false}) async {
try { try {
syncStatus = AttemptingSyncStatus(); syncStatus = AttemptingSyncStatus();

View file

@ -273,7 +273,7 @@ abstract class TronWalletBase
@action @action
@override @override
Future<void> startSync() async { Future<void> startSync({bool isBackgroundSync = false}) async {
try { try {
syncStatus = AttemptingSyncStatus(); syncStatus = AttemptingSyncStatus();
await _updateBalance(); await _updateBalance();

View file

@ -33,8 +33,7 @@ String getFilename() => wownero.Wallet_filename(wptr!);
String getSeed() { String getSeed() {
// wownero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed); // wownero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed);
final cakepolyseed = final cakepolyseed = wownero.Wallet_getCacheAttribute(wptr!, key: "cakewallet.seed");
wownero.Wallet_getCacheAttribute(wptr!, key: "cakewallet.seed");
if (cakepolyseed != "") { if (cakepolyseed != "") {
return cakepolyseed; return cakepolyseed;
} }
@ -49,11 +48,21 @@ String getSeed() {
String getSeedLegacy(String? language) { String getSeedLegacy(String? language) {
var legacy = wownero.Wallet_seed(wptr!, seedOffset: ''); var legacy = wownero.Wallet_seed(wptr!, seedOffset: '');
switch (language) { switch (language) {
case "Chinese (Traditional)": language = "Chinese (simplified)"; break; case "Chinese (Traditional)":
case "Chinese (Simplified)": language = "Chinese (simplified)"; break; language = "Chinese (simplified)";
case "Korean": language = "English"; break; break;
case "Czech": language = "English"; break; case "Chinese (Simplified)":
case "Japanese": language = "English"; break; language = "Chinese (simplified)";
break;
case "Korean":
language = "English";
break;
case "Czech":
language = "English";
break;
case "Japanese":
language = "English";
break;
} }
if (wownero.Wallet_status(wptr!) != 0) { if (wownero.Wallet_status(wptr!) != 0) {
wownero.Wallet_setSeedLanguage(wptr!, language: language ?? "English"); wownero.Wallet_setSeedLanguage(wptr!, language: language ?? "English");
@ -68,17 +77,18 @@ String getSeedLegacy(String? language) {
} }
return legacy; return legacy;
} }
Map<int, Map<int, Map<int, String>>> addressCache = {}; Map<int, Map<int, Map<int, String>>> addressCache = {};
String getAddress({int accountIndex = 0, int addressIndex = 1}) { String getAddress({int accountIndex = 0, int addressIndex = 1}) {
while (wownero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex)-1 < addressIndex) { while (wownero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex) - 1 < addressIndex) {
printV("adding subaddress"); printV("adding subaddress");
wownero.Wallet_addSubaddress(wptr!, accountIndex: accountIndex); wownero.Wallet_addSubaddress(wptr!, accountIndex: accountIndex);
} }
addressCache[wptr!.address] ??= {}; addressCache[wptr!.address] ??= {};
addressCache[wptr!.address]![accountIndex] ??= {}; addressCache[wptr!.address]![accountIndex] ??= {};
addressCache[wptr!.address]![accountIndex]![addressIndex] ??= wownero.Wallet_address(wptr!, addressCache[wptr!.address]![accountIndex]![addressIndex] ??=
accountIndex: accountIndex, addressIndex: addressIndex); wownero.Wallet_address(wptr!, accountIndex: accountIndex, addressIndex: addressIndex);
return addressCache[wptr!.address]![accountIndex]![addressIndex]!; return addressCache[wptr!.address]![accountIndex]![addressIndex]!;
} }
@ -138,13 +148,30 @@ void startRefreshSync() {
wownero.Wallet_startRefresh(wptr!); wownero.Wallet_startRefresh(wptr!);
} }
void setupBackgroundSync(
{required int backgroundSyncType,
required String walletPassword,
required String backgroundCachePassword}) {
wownero.Wallet_setupBackgroundSync(wptr!,
backgroundSyncType: backgroundSyncType,
walletPassword: walletPassword,
backgroundCachePassword: backgroundCachePassword);
}
void startBackgroundSync() {
wownero.Wallet_startBackgroundSync(wptr!);
}
void stopBackgroundSync(String password) {
wownero.Wallet_stopBackgroundSync(wptr!, password);
}
Future<bool> connectToNode() async { Future<bool> connectToNode() async {
return true; return true;
} }
void setRefreshFromBlockHeight({required int height}) => void setRefreshFromBlockHeight({required int height}) =>
wownero.Wallet_setRefreshFromBlockHeight(wptr!, wownero.Wallet_setRefreshFromBlockHeight(wptr!, refresh_from_block_height: height);
refresh_from_block_height: height);
void setRecoveringFromSeed({required bool isRecovery}) => void setRecoveringFromSeed({required bool isRecovery}) =>
wownero.Wallet_setRecoveringFromSeed(wptr!, recoveringFromSeed: isRecovery); wownero.Wallet_setRecoveringFromSeed(wptr!, recoveringFromSeed: isRecovery);
@ -219,8 +246,7 @@ class SyncListener {
_cachedBlockchainHeight = 0; _cachedBlockchainHeight = 0;
_lastKnownBlockHeight = 0; _lastKnownBlockHeight = 0;
_initialSyncHeight = 0; _initialSyncHeight = 0;
_updateSyncInfoTimer ??= _updateSyncInfoTimer ??= Timer.periodic(Duration(milliseconds: 1200), (_) async {
Timer.periodic(Duration(milliseconds: 1200), (_) async {
if (isNewTransactionExist()) { if (isNewTransactionExist()) {
onNewTransaction(); onNewTransaction();
} }
@ -259,8 +285,8 @@ class SyncListener {
void stop() => _updateSyncInfoTimer?.cancel(); void stop() => _updateSyncInfoTimer?.cancel();
} }
SyncListener setListeners(void Function(int, int, double) onNewBlock, SyncListener setListeners(
void Function() onNewTransaction) { void Function(int, int, double) onNewBlock, void Function() onNewTransaction) {
final listener = SyncListener(onNewBlock, onNewTransaction); final listener = SyncListener(onNewBlock, onNewTransaction);
// setListenerNative(); // setListenerNative();
return listener; return listener;
@ -322,8 +348,7 @@ String getSubaddressLabel(int accountIndex, int addressIndex) {
accountIndex: accountIndex, addressIndex: addressIndex); accountIndex: accountIndex, addressIndex: addressIndex);
} }
Future setTrustedDaemon(bool trusted) async => Future setTrustedDaemon(bool trusted) async => wownero.Wallet_setTrustedDaemon(wptr!, arg: trusted);
wownero.Wallet_setTrustedDaemon(wptr!, arg: trusted);
Future<bool> trustedDaemon() async => wownero.Wallet_trustedDaemon(wptr!); Future<bool> trustedDaemon() async => wownero.Wallet_trustedDaemon(wptr!);
@ -332,5 +357,6 @@ String signMessage(String message, {String address = ""}) {
} }
bool verifyMessage(String message, String address, String signature) { bool verifyMessage(String message, String address, String signature) {
return wownero.Wallet_verifySignedMessage(wptr!, message: message, address: address, signature: signature); return wownero.Wallet_verifySignedMessage(wptr!,
message: message, address: address, signature: signature);
} }

View file

@ -51,7 +51,9 @@ abstract class WowneroWalletBase
extends WalletBase<WowneroBalance, WowneroTransactionHistory, WowneroTransactionInfo> extends WalletBase<WowneroBalance, WowneroTransactionHistory, WowneroTransactionInfo>
with Store { with Store {
WowneroWalletBase( WowneroWalletBase(
{required WalletInfo walletInfo, required Box<UnspentCoinsInfo> unspentCoinsInfo, required String password}) {required WalletInfo walletInfo,
required Box<UnspentCoinsInfo> unspentCoinsInfo,
required String password})
: balance = ObservableMap<CryptoCurrency, WowneroBalance>.of({ : balance = ObservableMap<CryptoCurrency, WowneroBalance>.of({
CryptoCurrency.wow: WowneroBalance( CryptoCurrency.wow: WowneroBalance(
fullBalance: wownero_wallet.getFullBalance(accountIndex: 0), fullBalance: wownero_wallet.getFullBalance(accountIndex: 0),
@ -191,7 +193,19 @@ abstract class WowneroWalletBase
} }
@override @override
Future<void> startSync() async { Future<void> startSync({bool isBackgroundSync = false}) async {
if (isBackgroundSync) {
try {
syncStatus = AttemptingSyncStatus();
wownero_wallet.startBackgroundSync();
return;
} catch (e) {
syncStatus = FailedSyncStatus();
printV(e);
rethrow;
}
}
try { try {
_assertInitialHeight(); _assertInitialHeight();
} catch (_) { } catch (_) {

View file

@ -128,6 +128,8 @@ Future<void> onStart(ServiceInstance service) async {
Timer? _syncTimer; Timer? _syncTimer;
Timer? _stuckSyncTimer; Timer? _stuckSyncTimer;
Timer? _queueTimer; Timer? _queueTimer;
List<WalletBase> syncingWallets = [];
List<WalletBase> standbyWallets = [];
// commented because the behavior appears to be bugged: // commented because the behavior appears to be bugged:
// DartPluginRegistrant.ensureInitialized(); // DartPluginRegistrant.ensureInitialized();
@ -135,19 +137,34 @@ Future<void> onStart(ServiceInstance service) async {
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin(); FlutterLocalNotificationsPlugin();
service.on('stopService').listen((event) async { service.on("stopService").listen((event) async {
printV("STOPPING BACKGROUND SERVICE"); printV("STOPPING BACKGROUND SERVICE");
_syncTimer?.cancel(); _syncTimer?.cancel();
_stuckSyncTimer?.cancel(); _stuckSyncTimer?.cancel();
_queueTimer?.cancel(); _queueTimer?.cancel();
try {
// stop all syncing wallets:
for (int i = 0; i < syncingWallets.length; i++) {
final wallet = syncingWallets[i];
await wallet.stopSync(isBackgroundSync: true);
}
// stop all standby wallets (just in case):
for (int i = 0; i < standbyWallets.length; i++) {
final wallet = standbyWallets[i];
await wallet.stopSync(isBackgroundSync: true);
}
} catch (e) {
printV("error stopping sync: $e");
}
// stop the service itself:
await service.stopSelf(); await service.stopSelf();
}); });
service.on('status').listen((event) async { service.on("status").listen((event) async {
printV(event); printV(event);
}); });
service.on('setForeground').listen((event) async { service.on("setForeground").listen((event) async {
bgSyncStarted = false; bgSyncStarted = false;
_syncTimer?.cancel(); _syncTimer?.cancel();
setNotificationStandby(flutterLocalNotificationsPlugin); setNotificationStandby(flutterLocalNotificationsPlugin);
@ -158,7 +175,7 @@ Future<void> onStart(ServiceInstance service) async {
}); });
// we have entered the background, start the sync: // we have entered the background, start the sync:
service.on('setBackground').listen((event) async { service.on("setBackground").listen((event) async {
if (bgSyncStarted) { if (bgSyncStarted) {
return; return;
} }
@ -184,9 +201,6 @@ Future<void> onStart(ServiceInstance service) async {
final settingsStore = getIt.get<SettingsStore>(); final settingsStore = getIt.get<SettingsStore>();
final walletListViewModel = getIt.get<WalletListViewModel>(); final walletListViewModel = getIt.get<WalletListViewModel>();
List<WalletBase> syncingWallets = [];
List<WalletBase> standbyWallets = [];
// get all Monero / Wownero wallets and add them // get all Monero / Wownero wallets and add them
final List<WalletListItem> moneroWallets = walletListViewModel.wallets final List<WalletListItem> moneroWallets = walletListViewModel.wallets
.where((element) => [WalletType.monero, WalletType.wownero].contains(element.type)) .where((element) => [WalletType.monero, WalletType.wownero].contains(element.type))
@ -195,7 +209,7 @@ Future<void> onStart(ServiceInstance service) async {
for (int i = 0; i < moneroWallets.length; i++) { for (int i = 0; i < moneroWallets.length; i++) {
final wallet = await walletLoadingService.load(moneroWallets[i].type, moneroWallets[i].name); final wallet = await walletLoadingService.load(moneroWallets[i].type, moneroWallets[i].name);
final node = settingsStore.getCurrentNode(moneroWallets[i].type); final node = settingsStore.getCurrentNode(moneroWallets[i].type);
await wallet.stopSync(); await wallet.stopSync(isBackgroundSync: true);
syncingWallets.add(wallet); syncingWallets.add(wallet);
} }
@ -271,7 +285,7 @@ Future<void> onStart(ServiceInstance service) async {
printV("${wallet.name} NOT CONNECTED"); printV("${wallet.name} NOT CONNECTED");
final node = settingsStore.getCurrentNode(wallet.type); final node = settingsStore.getCurrentNode(wallet.type);
await wallet.connectToNode(node: node); await wallet.connectToNode(node: node);
wallet.startSync(); wallet.startSync(isBackgroundSync: true);
printV("STARTED SYNC"); printV("STARTED SYNC");
} }
@ -281,7 +295,7 @@ Future<void> onStart(ServiceInstance service) async {
syncedTicks = 0; syncedTicks = 0;
printV("WALLET $i SYNCED"); printV("WALLET $i SYNCED");
try { try {
await wallet.stopSync(); await wallet.stopSync(isBackgroundSync: true);
} catch (e) { } catch (e) {
printV("error stopping sync: $e"); printV("error stopping sync: $e");
} }
@ -329,7 +343,7 @@ Future<void> onStart(ServiceInstance service) async {
} }
} else { } else {
if (syncStatus is! NotConnectedSyncStatus) { if (syncStatus is! NotConnectedSyncStatus) {
wallet.stopSync(); wallet.stopSync(isBackgroundSync: true);
} }
if (progress < SYNC_THRESHOLD) { if (progress < SYNC_THRESHOLD) {
content = "$progressPercent - Waiting in sync queue"; content = "$progressPercent - Waiting in sync queue";
@ -395,7 +409,7 @@ Future<void> onStart(ServiceInstance service) async {
if (syncStatus is NotConnectedSyncStatus) { if (syncStatus is NotConnectedSyncStatus) {
final node = settingsStore.getCurrentNode(wallet.type); final node = settingsStore.getCurrentNode(wallet.type);
await wallet.connectToNode(node: node); await wallet.connectToNode(node: node);
await wallet.startSync(); await wallet.startSync(isBackgroundSync: true);
} }
// wait a while before checking progress: // wait a while before checking progress:
@ -427,7 +441,7 @@ Future<void> onStart(ServiceInstance service) async {
printV("syncing appears to be stuck, restarting..."); printV("syncing appears to be stuck, restarting...");
try { try {
stuckWallets.add(wallet.name); stuckWallets.add(wallet.name);
await wallet.stopSync(); await wallet.stopSync(isBackgroundSync: true);
} catch (e) { } catch (e) {
printV("error restarting sync: $e"); printV("error restarting sync: $e");
} }
@ -439,7 +453,7 @@ Future<void> onStart(ServiceInstance service) async {
stuckWallets = []; stuckWallets = [];
return; return;
} }
wallet.startSync(); wallet.startSync(isBackgroundSync: true);
} }
}); });
}); });