mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-08 03:49:43 +00:00
monero background sync view key update
This commit is contained in:
parent
585ced1c21
commit
08aed18f19
11 changed files with 186 additions and 97 deletions
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
|
@ -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 (_) {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue