fix: incorrect restore height sometimes being set on monero (#2390)

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

cyan committed Jul 17, 2025 at 05:41 UTC 0da7047c2aa5631c63cb6618244f3e678f1fc597
3 files changed +26 -11
cw_monero/lib/api/wallet_manager.dart
+5 -1
@@ -90,8 +90,9 @@ void createWallet(
90 if (status != 0) {
91 throw WalletCreationException(message: newW.errorString());
92 }
93 -
93 + newW.store(path: path);
94 setupBackgroundSync(password, newW);
95 + newW.store(path: path);
96
97 currentWallet = newW;
98 currentWallet!.setCacheAttribute(key: "cakewallet.passphrase", value: passphrase);
@@ -179,6 +180,8 @@ void restoreWalletFromKeys(
180 throw WalletRestoreFromKeysException(
181 message: newW.errorString());
182 }
183 + newW.store(path: path);
184 +
185
186 // CW-712 - Try to restore deterministic wallet first, if the view key doesn't
187 // match the view key provided
@@ -202,6 +205,7 @@ void restoreWalletFromKeys(
205 throw WalletRestoreFromKeysException(
206 message: newW.errorString());
207 }
208 + newW.store(path: path);
209
210 setupBackgroundSync(password, newW);
211 }
cw_monero/lib/monero_wallet.dart
+17 -6
@@ -804,28 +804,39 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
804 throw Exception("height isn't > $MIN_RESTORE_HEIGHT!");
805 }
806
807 - void _setHeightFromDate() {
807 + void _setHeightFromDate({int tryNum = 0}) {
808 if (walletInfo.isRecovery) {
809 return;
810 }
811
812 int height = 0;
813 try {
814 - height = _getHeightByDate(walletInfo.date);
815 - } catch (_) {}
814 + height = _getHeightByDate(walletInfo.date.subtract(Duration(days: 14)));
815 + if (height <= 0) {
816 + throw Exception("height is <= 0");
817 + }
818 + monero_wallet.setRefreshFromBlockHeight(height: height);
819 + } catch (_) {
820 + if (tryNum <= 3) {
821 + printV("Failed to set height from date, retrying... $tryNum");
822 + unawaited(() async {
823 + await Future.delayed(Duration(seconds: 10));
824 + _setHeightFromDate(tryNum: tryNum + 1);
825 + }());
826 + }
827 + }
828
829 monero_wallet.setRecoveringFromSeed(isRecovery: true);
818 - monero_wallet.setRefreshFromBlockHeight(height: height);
830 setupBackgroundSync(password, currentWallet!);
831 }
832
833 int _getHeightDistance(DateTime date) {
834 final distance =
824 - DateTime.now().millisecondsSinceEpoch - date.millisecondsSinceEpoch;
835 + DateTime.now().difference(date).inSeconds;
836 final daysTmp = (distance / 86400).round();
837 final days = daysTmp < 1 ? 1 : daysTmp;
838
828 - return days * 1000;
839 + return days * 720; // there are720 blocks per day on xmr
840 }
841
842 int _getHeightByDate(DateTime date) {
lib/exchange/provider/chainflip_exchange_provider.dart
+4 -4
@@ -297,14 +297,14 @@ class ChainflipExchangeProvider extends ExchangeProvider {
297 throw Exception('Unexpected response: ${response.statusCode} / ${uri.toString()} / ${response.body}');
298 }
299
300 - final quotes = json.decode(response.body) as List<dynamic>;
300 + final quotes = json.decode(response.body) as List<Map<String, dynamic>>;
301
302 Map<String, dynamic> highestQuote = quotes.reduce((current, next) {
303 - final currentAmount = current['egressAmount'] as double;
304 - final nextAmount = next['egressAmount'] as double;
303 + double currentAmount = current['egressAmount'] as double;
304 + double nextAmount = next['egressAmount'] as double;
305
306 return currentAmount > nextAmount ? current : next;
307 - }) as Map<String, dynamic>;
307 + });
308
309 return highestQuote;
310 }