What changed, and why it matters
This commit is a routine development update titled 'Progress' for the Skylight Wallet app. It mainly refactors how the wallet object is handled (making it nullable to avoid crashes before a wallet is loaded), moves timer logic out of the home screen into a shared model, updates native Monero library files, and adjusts balance/transaction getters. There is no clear security fix or vulnerability being patched in the visible code changes.
Treat as a normal development commit. If security relevance is suspected, verify the upstream `monero_c` changes between commits `1ffe3694a5390c12f7e7499393908fbd4d1eba6a` and `3f327c26ba1168af7423c66a892ff49310505c21`, and scan the updated native binaries for known vulnerabilities. No immediate security response is indicated by the diff alone.
Security signals we found
Native library binaries changed (arm64-v8a updated, x86_64 added) — cannot assess content from diff alone
Dependency `monero_c` git ref updated from 1ffe3694 to 3f327c26 — upstream changes not reviewed
Nullable wallet object refactor reduces risk of late-initialization/runtime crashes
Error logging added to sensitive flows (seed generation, wallet restore) — minor hardening
No explicit security fix, CVE reference, or vulnerability description present
Evidence from the diff
The diff shows a broad refactor of the Flutter wallet model and UI screens. Key changes include: converting _w2Wallet, _w2TxHistory, and related FFI addresses from late to nullable types and adding null checks before use; moving periodic refresh/connection timers from WalletHomeScreen into WalletModel; changing isConnected()/isSynced() methods to getters; updating pubspec.lock to a newer monero_c commit (3f327c26...); adding an x86_64 native library build; and adding error logging in seed generation and wallet restore. No explicit security bug is fixed or introduced in the diff.
Changed components
lib/models/wallet_model.dartlib/periodic_tasks.dartlib/screens/wallet_home.dartlib/screens/send.dartlib/screens/scan_qr.dartlib/screens/secret_keys.dartlib/screens/lws_details.dartlib/screens/lws_keys.dartlib/screens/generate_seed.dartlib/screens/restore_wallet.dartandroid/app/src/main/jniLibs/arm64-v8a/libmonero_libwallet2_api_c.soandroid/app/src/main/jniLibs/x86_64/libmonero_libwallet2_api_c.sopubspec.lockInspect captured patch +110 / −150
diff --git a/android/app/src/main/jniLibs/arm64-v8a/libmonero_libwallet2_api_c.so b/android/app/src/main/jniLibs/arm64-v8a/libmonero_libwallet2_api_c.so
index f1440aa..3fa8898 100755
Binary files a/android/app/src/main/jniLibs/arm64-v8a/libmonero_libwallet2_api_c.so and b/android/app/src/main/jniLibs/arm64-v8a/libmonero_libwallet2_api_c.so differ
diff --git a/android/app/src/main/jniLibs/x86_64/libmonero_libwallet2_api_c.so b/android/app/src/main/jniLibs/x86_64/libmonero_libwallet2_api_c.so
new file mode 100755
index 0000000..a6228b6
Binary files /dev/null and b/android/app/src/main/jniLibs/x86_64/libmonero_libwallet2_api_c.so differ
diff --git a/lib/models/wallet_model.dart b/lib/models/wallet_model.dart
index 4707149..a027bdc 100644
--- a/lib/models/wallet_model.dart
+++ b/lib/models/wallet_model.dart
@@ -122,20 +122,17 @@ class LWSConnectionDetails {
}
class WalletModel with ChangeNotifier {
- Timer? _connectionCheckTimer;
- Timer? _refreshTimer;
-
final _w2WalletManager = Monero()
.walletManagerFactory()
.getLWSFWalletManager();
- late int _w2WalletManagerFfiAddr;
+ int? _w2WalletManagerFfiAddr;
- late Wallet2Wallet _w2Wallet;
- late int _w2WalletFfiAddress;
+ Wallet2Wallet? _w2Wallet;
+ int? _w2WalletFfiAddress;
- late Wallet2TransactionHistory _w2TxHistory;
- late int _w2TxHistoryFfiAddress;
+ Wallet2TransactionHistory? _w2TxHistory;
+ int? _w2TxHistoryFfiAddress;
late String _connectionAddress;
late String _connectionProxyPort;
@@ -147,14 +144,15 @@ class WalletModel with ChangeNotifier {
int? _syncedHeight;
double? _unlockedBalance;
double? _totalBalance;
- List<TxDetails> _txHistory = [];
+ List<TxDetails>? _txHistory = [];
+ Wallet2Wallet? get w2Wallet => _w2Wallet;
bool get isConnected => _isConnected;
bool get isSynced => _isSynced;
int? get syncedHeight => _syncedHeight;
double? get unlockedBalance => _unlockedBalance;
double? get totalBalance => _totalBalance;
- List<TxDetails> get txHistory => _txHistory;
+ List<TxDetails>? get txHistory => _txHistory;
WalletModel() {
_w2WalletManagerFfiAddr = _w2WalletManager.ffiAddress();
@@ -163,16 +161,22 @@ class WalletModel with ChangeNotifier {
}
void _startTimers() {
- _connectionCheckTimer = Timer.periodic(Duration(seconds: 1), (timer) {
+ log(LogLevel.info, "Starting timers");
+
+ Timer.periodic(Duration(seconds: 1), (timer) {
_runCheckConnectionTimerTask();
});
- _refreshTimer = Timer.periodic(Duration(seconds: 20), (timer) {
+ Timer.periodic(Duration(seconds: 20), (timer) {
_runRefreshTimerTask();
});
}
Future<void> _runCheckConnectionTimerTask() async {
+ if (_w2Wallet == null) {
+ return;
+ }
+
final isConnected = await getIsConnected();
if (isConnected != _isConnected) {
@@ -189,6 +193,10 @@ class WalletModel with ChangeNotifier {
}
Future<void> _runRefreshTimerTask() async {
+ if (_w2Wallet == null) {
+ return;
+ }
+
await Future.wait([
loadIsSynced(),
loadSyncedHeight(),
@@ -201,11 +209,10 @@ class WalletModel with ChangeNotifier {
}
Future<void> _loadTxHistory() async {
- final txCount = _w2TxHistory.count();
+ final txCount = _w2TxHistory!.count();
- if (txCount > _txHistory.length) {
+ if (_txHistory == null || txCount > _txHistory!.length) {
_txHistory = await _getFullTxHistory();
- await _persistTxHistoryCount();
}
}
@@ -272,9 +279,15 @@ class WalletModel with ChangeNotifier {
);
}
- Future<void> _persistTxHistoryCount() async {
+ Future<void> persistTxHistoryCount() async {
+ if (_txHistory == null) {
+ throw Exception(
+ "Should not attempt to persist tx history count when tx history is null",
+ );
+ }
+
SharedPreferences prefs = await SharedPreferences.getInstance();
- prefs.setInt('txHistoryCount', _txHistory.length);
+ prefs.setInt('txHistoryCount', _txHistory!.length);
}
Future<int> getPersistedTxHistoryCount() async {
@@ -296,6 +309,8 @@ class WalletModel with ChangeNotifier {
}
Future<void> connectToDaemon() async {
+ if (_w2Wallet == null) throw Exception("w2wallet is null");
+
String? torProxyPort;
if (_connectionUseTor) {
@@ -304,20 +319,22 @@ class WalletModel with ChangeNotifier {
final proxyPort = torProxyPort ?? _connectionProxyPort;
- _w2Wallet.init(
+ _w2Wallet!.init(
daemonAddress: _connectionAddress,
proxyAddress: proxyPort != '' ? '127.0.0.1:$proxyPort' : '',
useSsl: _connectionUseSsl,
lightWallet: true,
);
- _w2Wallet.connectToDaemon();
+ _w2Wallet!.connectToDaemon();
}
void refresh() {
- _w2Wallet.startRefresh();
- _w2Wallet.refresh();
- _w2TxHistory.refresh();
+ if (_w2Wallet == null) throw Exception("w2wallet is null");
+
+ _w2Wallet!.startRefresh();
+ _w2Wallet!.refresh();
+ _w2TxHistory!.refresh();
}
Future<String> create() async {
@@ -425,20 +442,24 @@ class WalletModel with ChangeNotifier {
_w2Wallet = MoneroWallet(walletPtr);
}
- _w2WalletFfiAddress = _w2Wallet.ffiAddress();
+ if (_w2Wallet == null) {
+ throw Exception("Something went wrong when generating seed");
+ }
+
+ _w2WalletFfiAddress = _w2Wallet!.ffiAddress();
_w2TxHistory = MoneroTransactionHistory(
Pointer<Void>.fromAddress(
await Isolate.run(
// ignore: deprecated_member_use
() => monero.Wallet_history(
- Pointer<Void>.fromAddress(_w2WalletFfiAddress),
+ Pointer<Void>.fromAddress(_w2WalletFfiAddress!),
).address,
),
),
);
- _w2TxHistoryFfiAddress = _w2TxHistory.ffiAddress();
+ _w2TxHistoryFfiAddress = _w2TxHistory!.ffiAddress();
store();
notifyListeners();
@@ -454,13 +475,13 @@ class WalletModel with ChangeNotifier {
log(LogLevel.error, 'Failed to open existing wallet: $errorString');
}
- _w2TxHistory = _w2Wallet.history();
+ _w2TxHistory = _w2Wallet!.history();
notifyListeners();
}
Future<bool> store() async {
- final walletFfiAddr = _w2Wallet.ffiAddress();
+ final walletFfiAddr = _w2Wallet!.ffiAddress();
return Isolate.run(
// ignore: deprecated_member_use
() => monero.Wallet_store(Pointer<Void>.fromAddress(walletFfiAddr)),
@@ -468,7 +489,8 @@ class WalletModel with ChangeNotifier {
}
Future delete() async {
- _w2WalletManager.closeWallet(_w2Wallet, false);
+ _w2WalletManager.closeWallet(_w2Wallet!, false);
+ _w2Wallet == null;
final path = await getWalletPath();
final walletFile = File(path);
await walletFile.delete();
@@ -489,7 +511,7 @@ class WalletModel with ChangeNotifier {
}
Future<bool> getIsConnected() async {
- final w2WalletFfiAddr = _w2Wallet.ffiAddress();
+ final w2WalletFfiAddr = _w2Wallet!.ffiAddress();
final connected = await Isolate.run(
// ignore: deprecated_member_use
@@ -503,7 +525,7 @@ class WalletModel with ChangeNotifier {
_isSynced = await Isolate.run(
// ignore: deprecated_member_use
() => monero.Wallet_synchronized(
- Pointer<Void>.fromAddress(_w2WalletFfiAddress),
+ Pointer<Void>.fromAddress(_w2WalletFfiAddress!),
),
);
}
@@ -512,7 +534,7 @@ class WalletModel with ChangeNotifier {
_syncedHeight = await Isolate.run(
// ignore: deprecated_member_use
() => monero.Wallet_blockChainHeight(
- Pointer<Void>.fromAddress(_w2WalletFfiAddress),
+ Pointer<Void>.fromAddress(_w2WalletFfiAddress!),
),
);
}
@@ -521,7 +543,7 @@ class WalletModel with ChangeNotifier {
final amount = await Isolate.run(
// ignore: deprecated_member_use
() => monero.Wallet_balance(
- Pointer<Void>.fromAddress(_w2WalletFfiAddress),
+ Pointer<Void>.fromAddress(_w2WalletFfiAddress!),
accountIndex: 0,
),
);
@@ -533,7 +555,7 @@ class WalletModel with ChangeNotifier {
final amount = await Isolate.run(
// ignore: deprecated_member_use
() => monero.Wallet_unlockedBalance(
- Pointer<Void>.fromAddress(_w2WalletFfiAddress),
+ Pointer<Void>.fromAddress(_w2WalletFfiAddress!),
accountIndex: 0,
),
);
@@ -542,7 +564,7 @@ class WalletModel with ChangeNotifier {
}
String getPrimaryAddress() {
- return _w2Wallet.address(accountIndex: 0);
+ return _w2Wallet!.address(accountIndex: 0);
}
Future<String> getUnusedSubaddress() async {
@@ -564,7 +586,7 @@ class WalletModel with ChangeNotifier {
nextSubaddrIndex++;
}
- return _w2Wallet.address(accountIndex: 0, addressIndex: nextSubaddrIndex);
+ return _w2Wallet!.address(accountIndex: 0, addressIndex: nextSubaddrIndex);
}
Future<MoneroPendingTransaction> createTx(
@@ -572,8 +594,8 @@ class WalletModel with ChangeNotifier {
double amount,
bool isSweepAll,
) async {
- final amountInt = _w2Wallet.amountFromDouble(amount);
- final w2WalletFfiAddr = _w2Wallet.ffiAddress();
+ final amountInt = _w2Wallet!.amountFromDouble(amount);
+ final w2WalletFfiAddr = _w2Wallet!.ffiAddress();
final txPointer = Pointer<Void>.fromAddress(
await Isolate.run(() {
@@ -633,7 +655,7 @@ class WalletModel with ChangeNotifier {
timestamp: (DateTime.now().millisecondsSinceEpoch / 1000).round(),
height: 0,
confirmations: 0,
- key: _w2Wallet.getTxKey(txid: tx.txid('')),
+ key: _w2Wallet!.getTxKey(txid: tx.txid('')),
);
await addPendingTx(txDetails);
@@ -683,7 +705,7 @@ class WalletModel with ChangeNotifier {
}
List<TxDetails> getConfirmedTxHistory() {
- final txCount = _w2TxHistory.count();
+ final txCount = _w2TxHistory!.count();
final List<TxDetails> confirmedTxs = [];
for (int i = 0; i < txCount; i++) {
@@ -721,15 +743,15 @@ class WalletModel with ChangeNotifier {
}
TxDetails getTxDetails(int txIndex) {
- final tx = _w2TxHistory.transaction(txIndex);
+ final tx = _w2TxHistory!.transaction(txIndex);
final direction = tx.direction();
final hash = tx.hash();
final amountSent = doubleAmountFromInt(tx.amount());
final fee = doubleAmountFromInt(tx.fee());
final timestamp = tx.timestamp();
final height = tx.blockHeight();
- final confirmations = _w2Wallet.blockChainHeight() - height + 1;
- final key = _w2Wallet.getTxKey(txid: hash);
+ final confirmations = _w2Wallet!.blockChainHeight() - height + 1;
+ final key = _w2Wallet!.getTxKey(txid: hash);
List<TxRecipient> recipients = [];
final recipientsCount = tx.transfers_count();
diff --git a/lib/periodic_tasks.dart b/lib/periodic_tasks.dart
index 93d230e..545e073 100644
--- a/lib/periodic_tasks.dart
+++ b/lib/periodic_tasks.dart
@@ -23,14 +23,14 @@ void callbackDispatcher() {
wallet.connectToDaemon();
wallet.refresh();
- if (!wallet.isConnected()) {
+ if (wallet.isConnected) {
return false;
}
int itersBeforeSynced = 0;
while (true) {
- if (wallet.isSynced()) {
+ if (wallet.isSynced) {
break;
}
@@ -43,8 +43,12 @@ void callbackDispatcher() {
}
}
+ if (wallet.txHistory == null) {
+ return true;
+ }
+
final persistedTxCount = await wallet.getPersistedTxHistoryCount();
- final currentTxCount = await wallet.getTxHistoryCount();
+ final currentTxCount = wallet.txHistory!.length;
final newTxCount = currentTxCount - persistedTxCount;
if (newTxCount > 0 && currentTxCount != 0) {
@@ -55,7 +59,7 @@ void callbackDispatcher() {
}
}
- await wallet._persistTxHistoryCount();
+ await wallet.persistTxHistoryCount();
}
break;
diff --git a/lib/screens/generate_seed.dart b/lib/screens/generate_seed.dart
index d1fa47b..f283880 100644
--- a/lib/screens/generate_seed.dart
+++ b/lib/screens/generate_seed.dart
@@ -5,6 +5,7 @@ import 'package:monero_light_wallet/l10n/app_localizations.dart';
import 'package:monero_light_wallet/models/wallet_model.dart';
import 'package:monero_light_wallet/screens/create_wallet.dart';
import 'package:monero_light_wallet/util/height.dart';
+import 'package:monero_light_wallet/util/logging.dart';
import 'package:provider/provider.dart';
class GenerateSeedScreen extends StatefulWidget {
@@ -38,6 +39,8 @@ class _GenerateSeedScreenState extends State<GenerateSeedScreen> {
if (error.toString().contains('failedToLoadHeight')) {
errorMsg = 'Check your internet connection.';
+ } else {
+ log(LogLevel.error, error.toString());
}
if (mounted) {
diff --git a/lib/screens/lws_details.dart b/lib/screens/lws_details.dart
index 405f39f..ed0d4e4 100644
--- a/lib/screens/lws_details.dart
+++ b/lib/screens/lws_details.dart
@@ -12,7 +12,7 @@ class LwsDetailsScreen extends StatelessWidget {
final i18n = AppLocalizations.of(context)!;
final wallet = context.watch<WalletModel>();
final primaryAddress = wallet.getPrimaryAddress();
- final secretViewKey = wallet.wallet.secretViewKey();
+ final secretViewKey = wallet.w2Wallet!.secretViewKey();
final restoreHeight = ModalRoute.of(context)!.settings.arguments as int;
return Scaffold(
diff --git a/lib/screens/lws_keys.dart b/lib/screens/lws_keys.dart
index 44e86da..9428ee8 100644
--- a/lib/screens/lws_keys.dart
+++ b/lib/screens/lws_keys.dart
@@ -24,7 +24,7 @@ class _LwsKeysScreenState extends State<LwsKeysScreen> {
Future<void> _loadRestoreHeight() async {
final wallet = Provider.of<WalletModel>(context, listen: false);
- final restoreHeight = wallet.wallet.getRefreshFromBlockHeight();
+ final restoreHeight = wallet.w2Wallet!.getRefreshFromBlockHeight();
if (restoreHeight > 0) {
setState(() {
@@ -43,7 +43,7 @@ class _LwsKeysScreenState extends State<LwsKeysScreen> {
final i18n = AppLocalizations.of(context)!;
final wallet = context.watch<WalletModel>();
final primaryAddress = wallet.getPrimaryAddress();
- final secretViewKey = wallet.wallet.secretViewKey();
+ final secretViewKey = wallet.w2Wallet!.secretViewKey();
return Scaffold(
appBar: AppBar(title: Text(i18n.lwsKeysTitle)),
diff --git a/lib/screens/restore_wallet.dart b/lib/screens/restore_wallet.dart
index 845fc9d..f602337 100644
--- a/lib/screens/restore_wallet.dart
+++ b/lib/screens/restore_wallet.dart
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:monero_light_wallet/l10n/app_localizations.dart';
+import 'package:monero_light_wallet/util/logging.dart';
import 'package:provider/provider.dart';
import 'package:monero_light_wallet/models/wallet_model.dart';
@@ -46,6 +47,7 @@ class _RestoreWalletScreenState extends State<RestoreWalletScreen> {
}
return;
} catch (error) {
+ log(LogLevel.error, error.toString());
if (mounted) {
final i18n = AppLocalizations.of(context)!;
diff --git a/lib/screens/scan_qr.dart b/lib/screens/scan_qr.dart
index fa06b20..77b313a 100644
--- a/lib/screens/scan_qr.dart
+++ b/lib/screens/scan_qr.dart
@@ -28,14 +28,14 @@ class _ScanQrScreenState extends State<ScanQrScreen> {
final uri = Uri.tryParse(scanResult);
if (uri != null && uri.scheme == 'monero') {
- if (!wallet.wallet.addressValid(uri.path, 0)) return;
+ if (!wallet.w2Wallet!.addressValid(uri.path, 0)) return;
address = uri.path;
if (uri.queryParameters.containsKey('tx_amount')) {
amount = double.tryParse(uri.queryParameters['tx_amount']!);
}
- } else if (wallet.wallet.addressValid(scanResult, 0)) {
+ } else if (wallet.w2Wallet!.addressValid(scanResult, 0)) {
address = scanResult;
} else {
return;
diff --git a/lib/screens/secret_keys.dart b/lib/screens/secret_keys.dart
index 5b85553..eee205c 100644
--- a/lib/screens/secret_keys.dart
+++ b/lib/screens/secret_keys.dart
@@ -12,11 +12,11 @@ class SecretKeysScreen extends StatelessWidget {
Widget build(BuildContext context) {
final i18n = AppLocalizations.of(context)!;
final wallet = context.watch<WalletModel>();
- final legacySeed = wallet.wallet.seed(seedOffset: '');
- final polyseed = wallet.wallet.getPolyseed(passphrase: '');
- final secretSpendKey = wallet.wallet.secretSpendKey();
- final publicSpendKey = wallet.wallet.publicSpendKey();
- final publicViewKey = wallet.wallet.publicViewKey();
+ final legacySeed = wallet.w2Wallet!.seed(seedOffset: '');
+ final polyseed = wallet.w2Wallet!.getPolyseed(passphrase: '');
+ final secretSpendKey = wallet.w2Wallet!.secretSpendKey();
+ final publicSpendKey = wallet.w2Wallet!.publicSpendKey();
+ final publicViewKey = wallet.w2Wallet!.publicViewKey();
return Scaffold(
appBar: AppBar(title: Text(i18n.secretKeysTitle)),
diff --git a/lib/screens/send.dart b/lib/screens/send.dart
index 6e05d9a..65b385a 100644
--- a/lib/screens/send.dart
+++ b/lib/screens/send.dart
@@ -90,7 +90,7 @@ class _SendScreenState extends State<SendScreen> {
}
destinationOpenAlias = unresolvedDestinationAddress;
- } else if (wallet.wallet.addressValid(unresolvedDestinationAddress, 0)) {
+ } else if (wallet.w2Wallet!.addressValid(unresolvedDestinationAddress, 0)) {
// check for address
destinationAddress = unresolvedDestinationAddress;
} else {
@@ -101,7 +101,7 @@ class _SendScreenState extends State<SendScreen> {
return;
}
- if (amount > wallet.getTotalBalance()) {
+ if (amount > (wallet.totalBalance ?? 0)) {
setState(() {
_amountError = i18n.sendInsufficientBalanceError;
_isLoading = false;
@@ -142,8 +142,7 @@ class _SendScreenState extends State<SendScreen> {
void _setBalanceAsSendAmount() {
final wallet = Provider.of<WalletModel>(context, listen: false);
- final unlockedBalance = wallet.getUnlockedBalance();
- _amountController.text = unlockedBalance.toString();
+ _amountController.text = (wallet.unlockedBalance ?? 0).toString();
setState(() {
_isSweepAll = true;
@@ -163,7 +162,6 @@ class _SendScreenState extends State<SendScreen> {
final i18n = AppLocalizations.of(context)!;
final wallet = context.watch<WalletModel>();
- final unlockedBalance = wallet.getUnlockedBalance();
return Scaffold(
body: Center(
@@ -229,7 +227,7 @@ class _SendScreenState extends State<SendScreen> {
height: 18,
),
MoneroAmount(
- amount: unlockedBalance,
+ amount: wallet.unlockedBalance ?? 0,
maxFontSize: 18,
),
],
diff --git a/lib/screens/wallet_home.dart b/lib/screens/wallet_home.dart
index 89850f2..0706aff 100644
--- a/lib/screens/wallet_home.dart
+++ b/lib/screens/wallet_home.dart
@@ -26,24 +26,10 @@ class WalletHomeScreen extends StatefulWidget {
}
class _WalletHomeScreenState extends State<WalletHomeScreen> {
- Timer? _timer1;
- Timer? _timer10;
- bool _isConnected = false;
- List<TxDetails>? _txHistory;
-
@override
void initState() {
super.initState();
- final wallet = Provider.of<WalletModel>(context, listen: false);
- wallet.refresh();
-
- if (!wallet.isConnected()) {
- wallet.connectToDaemon();
- }
-
- _loadTxHistory();
-
Workmanager().initialize(callbackDispatcher, isInDebugMode: true);
_initNewTxsCheckIfNeeded();
@@ -59,69 +45,12 @@ class _WalletHomeScreenState extends State<WalletHomeScreen> {
@override
void dispose() {
- _timer10?.cancel();
- _timer1?.cancel();
super.dispose();
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
-
- if (_timer1 == null && _timer10 == null) {
- _startTimers();
- }
- }
-
- void _startTimers() {
- if (!mounted) return;
-
- _timer1 = Timer.periodic(Duration(seconds: 1), (timer) async {
- if (!mounted) {
- timer.cancel();
- return;
- }
-
- final wallet = Provider.of<WalletModel>(context, listen: false);
- final isConnected = await wallet.isConnected();
-
- if (isConnected != _isConnected) {
- setState(() {
- _isConnected = isConnected;
- });
-
- if (isConnected) {
- wallet.refresh();
- await _loadTxHistory();
- wallet.store();
- }
- }
- });
-
- _timer10 = Timer.periodic(Duration(seconds: 10), (timer) async {
- if (!mounted) {
- timer.cancel();
- return;
- }
-
- final wallet = Provider.of<WalletModel>(context, listen: false);
- if (_isConnected) {
- wallet.refresh();
- await _loadTxHistory();
- wallet.store();
- }
- });
- }
-
- Future<void> _loadTxHistory() async {
- final wallet = Provider.of<WalletModel>(context, listen: false);
- final newTxHistory = await wallet._getFullTxHistory();
-
- setState(() {
- _txHistory = newTxHistory;
- });
-
- await wallet._persistTxHistoryCount();
}
void _showTxDetails(TxDetails txDetails) {
@@ -158,14 +87,12 @@ class _WalletHomeScreenState extends State<WalletHomeScreen> {
final currentLocale = Localizations.localeOf(context);
final wallet = context.watch<WalletModel>();
final fiatRate = context.watch<FiatRateModel>();
- final synced = wallet.isSynced();
- final height = wallet.getSyncedHeight();
- final totalBalance = wallet.getTotalBalance();
- final unlockedBalance = wallet.getUnlockedBalance();
- final unlockedBalanceFiat = fiatRate.rate is double
- ? unlockedBalance * fiatRate.rate!
+ final unlockedBalanceFiat =
+ fiatRate.rate is double && wallet.unlockedBalance is double
+ ? wallet.unlockedBalance! * fiatRate.rate!
: null;
- final lockedBalance = totalBalance - unlockedBalance;
+ final lockedBalance =
+ (wallet.totalBalance ?? 0) - (wallet.unlockedBalance ?? 0);
final fiatSymbol = fiatRate.fiatCode == 'EUR' ? '€' : '\$';
return Scaffold(
@@ -191,7 +118,9 @@ class _WalletHomeScreenState extends State<WalletHomeScreen> {
child: Column(
spacing: 10,
children: [
- if (_isConnected && synced && height != 0)
+ if (wallet.isConnected &&
+ wallet.isSynced &&
+ wallet.syncedHeight != 0)
SizedBox(
width: 26,
height: 26,
@@ -202,7 +131,9 @@ class _WalletHomeScreenState extends State<WalletHomeScreen> {
),
),
- if (_isConnected && (!synced || height == 0))
+ if (wallet.isConnected &&
+ (!wallet.isSynced ||
+ wallet.syncedHeight == 0))
SizedBox(
width: 22,
height: 22,
@@ -215,7 +146,7 @@ class _WalletHomeScreenState extends State<WalletHomeScreen> {
),
),
- if (!_isConnected)
+ if (!wallet.isConnected)
SizedBox(
width: 26,
height: 26,
@@ -255,7 +186,7 @@ class _WalletHomeScreenState extends State<WalletHomeScreen> {
height: 22,
),
MoneroAmount(
- amount: unlockedBalance,
+ amount: wallet.unlockedBalance ?? 0,
maxFontSize: 30,
),
],
@@ -321,14 +252,14 @@ class _WalletHomeScreenState extends State<WalletHomeScreen> {
),
),
),
- if (_txHistory != null && _txHistory!.isNotEmpty)
+ if (wallet.txHistory != null && wallet.txHistory!.isNotEmpty)
Expanded(
child: SizedBox(
child: ListView.separated(
separatorBuilder: (context, index) => Divider(),
- itemCount: _txHistory!.length,
+ itemCount: wallet.txHistory!.length,
itemBuilder: (BuildContext context, int index) {
- final tx = _txHistory![index];
+ final tx = wallet.txHistory![index];
final amountFiat = fiatRate.rate is double
? tx.amount * fiatRate.rate!
: null;
@@ -431,9 +362,9 @@ class _WalletHomeScreenState extends State<WalletHomeScreen> {
),
),
),
- if (_txHistory != null && _txHistory!.isEmpty)
+ if (wallet.txHistory != null && wallet.txHistory!.isEmpty)
Text(i18n.homeNoTransactions),
- if (_txHistory == null) CircularProgressIndicator(),
+ if (wallet.txHistory == null) CircularProgressIndicator(),
],
),
),
diff --git a/pubspec.lock b/pubspec.lock
index 9f8d719..6caf489 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -298,7 +298,7 @@ packages:
description:
path: "impls/monero.dart"
ref: lwsf
- resolved-ref: "1ffe3694a5390c12f7e7499393908fbd4d1eba6a"
+ resolved-ref: "3f327c26ba1168af7423c66a892ff49310505c21"
url: "https://github.com/vtnerd/monero_c"
source: git
version: "0.0.0"
Why this scored 26/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.