fix regex, don't throw error when opening wallet, fix tx history, fix async calls, move stuff to isolate

This commit is contained in:
Czarek Nakamoto 2024-11-13 11:36:51 -05:00
parent fe0ddcd031
commit 50589a5007
No known key found for this signature in database
GPG key ID: 04FB77CB56AB1DF4
3 changed files with 66 additions and 32 deletions

View file

@ -1,5 +1,6 @@
import 'dart:async';
import 'dart:io';
import 'dart:math';
import 'package:cw_core/cake_hive.dart';
import 'package:cw_core/crypto_currency.dart';
@ -94,9 +95,9 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
Timer? _autoSaveTimer;
/// index of last transaction fetched
int _lastTxIndex = 0;
final int _lastTxIndex = 0;
/// number of transactions in each request
static const int _txChunkSize = 30;
static final int _txChunkSize = (pow(2, 32)-1).toInt();
ZanoWalletBase(WalletInfo walletInfo, String password)
: balance = ObservableMap.of({CryptoCurrency.zano: ZanoBalance.empty()}),
@ -267,8 +268,8 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
final transfers = <Transfer>[];
late GetRecentTxsAndInfoResult result;
do {
result = await getRecentTxsAndInfo(offset: _lastTxIndex, count: _txChunkSize);
_lastTxIndex += result.transfers.length;
result = await getRecentTxsAndInfo(offset: 0, count: _txChunkSize);
// _lastTxIndex += result.transfers.length;
transfers.addAll(result.transfers);
} while (result.lastItemIndex + 1 < result.totalTransfers);
return Transfer.makeMap(transfers, zanoAssets, currentDaemonHeight);
@ -282,7 +283,9 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
await walletAddresses.init();
await walletAddresses.updateAddress(address);
await updateTransactions();
_autoSaveTimer = Timer.periodic(Duration(seconds: _autoSaveIntervalSeconds), (_) async => await save());
_autoSaveTimer = Timer.periodic(Duration(seconds: _autoSaveIntervalSeconds), (_) async {
await save();
});
}
@override
@ -396,6 +399,7 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
}
}
}
await updateTransactions();
// removing balances for assets missing in wallet info balances
balance.removeWhere(
(key, _) => key != CryptoCurrency.zano && !walletInfo.wi.balances.any((element) => element.assetId == (key as ZanoAsset).assetId),
@ -414,15 +418,19 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
Future<void> updateTransactions() async {
try {
print("isTransactionUpdating: $_isTransactionUpdating");
if (_isTransactionUpdating) {
return;
}
_isTransactionUpdating = true;
final transactions = await fetchTransactions();
print("transactions: $transactions");
transactionHistory.clear();
transactionHistory.addMany(transactions);
await transactionHistory.save();
_isTransactionUpdating = false;
} catch (e) {
print("e: $e");
ZanoWalletApi.error(e.toString());
_isTransactionUpdating = false;
}

View file

@ -32,7 +32,7 @@ mixin ZanoWalletApi {
static const _statusDelivered = 'delivered';
static const _maxInvokeAttempts = 10;
static const _maxReopenAttempts = 5;
static const _logInfo = true;
static const _logInfo = false;
static const _logError = true;
static const _logJson = false;
static const int _zanoMixinValue = 10;
@ -84,7 +84,7 @@ mixin ZanoWalletApi {
_json('get_wallet_status', json);
if (_logInfo)
info(
'get_wallet_status connected: ${status.isDaemonConnected} in refresh: ${status.isInLongRefresh} progress: ${status.progress} wallet state: ${status.walletState} sync: ${status.currentWalletHeight}/${status.currentWalletHeight}');
'get_wallet_status connected: ${status.isDaemonConnected} in refresh: ${status.isInLongRefresh} progress: ${status.progress} wallet state: ${status.walletState} sync: ${status.currentWalletHeight}/${status.currentDaemonHeight} ${(status.currentWalletHeight/status.currentDaemonHeight*100).toStringAsFixed(2)}%');
return status;
}
@ -104,13 +104,13 @@ mixin ZanoWalletApi {
"method": methodName,
"params": params,
});
print("zano: >>> $request");
final invokeResult = zano.PlainWallet_syncCall(
'invoke',
hWallet,
request,
);
print("zano: <<< ${invokeResult}");
final invokeResult = await callSyncMethod('invoke', hWallet, request);
// final invokeResult = zano.PlainWallet_syncCall(
// 'invoke',
// hWallet,
// request,
// );
// print("zano: <<< ${invokeResult}");
Map<String, dynamic> map;
try {
map = jsonDecode(invokeResult) as Map<String, dynamic>;
@ -129,7 +129,7 @@ mixin ZanoWalletApi {
final map = jsonDecode(json) as Map<String, dynamic>?;
_checkForErrors(map);
List<ZanoAsset> assets(String type, bool isGlobalWhitelist) =>
(map?['result']?['result']?[type] as List<dynamic>?)
(map?['result']?[type] as List<dynamic>?)
?.map((e) => ZanoAsset.fromJson(e as Map<String, dynamic>, isInGlobalWhitelist: isGlobalWhitelist))
.toList() ??
[];
@ -143,8 +143,8 @@ mixin ZanoWalletApi {
return [...globalWhitelist, ...localWhitelist, ...ownAssets];
} catch (e) {
error('assets_whitelist_get $e');
//return [];
rethrow;
return [];
// rethrow;
}
}
@ -231,9 +231,9 @@ mixin ZanoWalletApi {
_json('get_recent_txs_and_info', json);
final map = jsonDecode(json) as Map<String, dynamic>?;
_checkForErrors(map);
final lastItemIndex = map?['result']?['result']?['last_item_index'] as int?;
final totalTransfers = map?['result']?['result']?['total_transfers'] as int?;
final transfers = map?['result']?['result']?['transfers'] as List<dynamic>?;
final lastItemIndex = map?['result']?['last_item_index'] as int?;
final totalTransfers = map?['result']?['total_transfers'] as int?;
final transfers = map?['result']?['transfers'] as List<dynamic>?;
if (transfers == null || lastItemIndex == null || totalTransfers == null) {
error('get_recent_txs_and_info empty transfers');
return GetRecentTxsAndInfoResult.empty();
@ -262,8 +262,8 @@ mixin ZanoWalletApi {
_json('create_wallet', json);
final map = jsonDecode(json) as Map<String, dynamic>?;
if (map?['error'] != null) {
final code = map!['error']!['code'] ?? '';
final message = map['error']!['message'] ?? '';
final code = map!['error']?['code'] ?? '';
final message = map['error']?['message'] ?? '';
throw ZanoWalletException('Error creating wallet file, $message ($code)');
}
if (map?['result'] == null) {
@ -394,15 +394,41 @@ mixin ZanoWalletApi {
static void printWrapped(String text) => RegExp('.{1,800}').allMatches(text).map((m) => m.group(0)).forEach(print);
static void _json(String methodName, String json) => _logJson ? printWrapped('$methodName $json') : null;
Map<String, dynamic> jsonDecode(String json) {
try {
return decodeJson(json.replaceAll("\\/", "/")) as Map<String, dynamic>;
} catch (e) {
return convert.jsonDecode(json) as Map<String, dynamic>;
}
}
}
String jsonEncode(Object? object) {
return convert.jsonEncode(object);
Future<String> callSyncMethod(String methodName, int hWallet, String params) async {
final params_ = params.toNativeUtf8().address;
// print("zano: >>> $request");
final method_name_ = methodName.toNativeUtf8().address;
final invokeResult = await Isolate.run(() async {
final lib = zanoapi.ZanoC(DynamicLibrary.open(zano.libPath));
final txid = lib.ZANO_PlainWallet_syncCall(
Pointer.fromAddress(method_name_).cast(),
hWallet,
Pointer.fromAddress(params_).cast()
);
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
lib.ZANO_free(strPtr.cast());
return str;
} catch (e) {
return "";
}
});
calloc.free(Pointer.fromAddress(method_name_));
calloc.free(Pointer.fromAddress(params_));
return invokeResult;
}
Map<String, dynamic> jsonDecode(String json) {
try {
return decodeJson(json.replaceAll("\\/", "/")) as Map<String, dynamic>;
} catch (e) {
return convert.jsonDecode(json) as Map<String, dynamic>;
}
}
String jsonEncode(Object? object) {
return convert.jsonEncode(object);
}

View file

@ -136,7 +136,7 @@ class AddressValidator extends TextValidator {
case CryptoCurrency.btcln:
pattern = '(lnbc|LNBC)([0-9]{1,}[a-zA-Z0-9]+)';
case CryptoCurrency.zano:
pattern = '([1-9A-HJ-NP-Za-km-z]{90,200})|(@[\w\d-.]+)';
pattern = r'([1-9A-HJ-NP-Za-km-z]{90,200})|(@[\w\d-.]+)';
default:
pattern = '[0-9a-zA-Z]+';
}