mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-22 02:34:59 +00:00
whitelists
This commit is contained in:
parent
42731fcdcb
commit
89b572cae2
6 changed files with 174 additions and 73 deletions
|
@ -56,7 +56,8 @@ typedef _stringFunction = Pointer<Utf8> Function();
|
|||
|
||||
class ApiCalls {
|
||||
static String _convertUTF8ToString({required Pointer<Utf8> pointer}) {
|
||||
final str = pointer.toDartStringAllowingMalformed();
|
||||
final str = pointer.toDartString();
|
||||
//final str = pointer.toDartStringAllowingMalformed();
|
||||
calloc.free(pointer);
|
||||
return str;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ class Balance {
|
|||
required this.awaitingOut,
|
||||
required this.total,
|
||||
required this.unlocked});
|
||||
|
||||
String get assetId => assetInfo.assetId;
|
||||
|
||||
@override
|
||||
String toString() => '$assetInfo: $total/$unlocked';
|
||||
|
|
|
@ -19,18 +19,20 @@ class ZanoAsset extends CryptoCurrency with HiveObjectMixin {
|
|||
bool _enabled;
|
||||
@HiveField(5)
|
||||
final String? iconPath;
|
||||
// @HiveField(6)
|
||||
// final String? tag;
|
||||
@HiveField(6)
|
||||
final String? tag;
|
||||
@HiveField(7)
|
||||
final String owner;
|
||||
@HiveField(8)
|
||||
@HiveField(7)
|
||||
final String metaInfo;
|
||||
@HiveField(9)
|
||||
@HiveField(8)
|
||||
final int currentSupply;
|
||||
@HiveField(10)
|
||||
@HiveField(9)
|
||||
final bool hiddenSupply;
|
||||
@HiveField(11)
|
||||
@HiveField(10)
|
||||
final int totalMaxSupply;
|
||||
@HiveField(11)
|
||||
final bool isInGlobalWhitelist;
|
||||
|
||||
bool get enabled => _enabled;
|
||||
|
||||
|
@ -43,45 +45,47 @@ class ZanoAsset extends CryptoCurrency with HiveObjectMixin {
|
|||
this.decimalPoint = ZanoFormatter.defaultDecimalPoint,
|
||||
bool enabled = false,
|
||||
this.iconPath,
|
||||
this.tag,
|
||||
//this.tag,
|
||||
this.owner = defaultOwner,
|
||||
this.metaInfo = '',
|
||||
this.currentSupply = 0,
|
||||
this.hiddenSupply = false,
|
||||
this.totalMaxSupply = 0,
|
||||
this.isInGlobalWhitelist = false,
|
||||
}) : _enabled = enabled,
|
||||
super(
|
||||
name: fullName,
|
||||
title: ticker.toUpperCase(),
|
||||
fullName: fullName,
|
||||
tag: tag,
|
||||
tag: 'ZANO',
|
||||
iconPath: iconPath,
|
||||
decimals: decimalPoint,
|
||||
);
|
||||
|
||||
ZanoAsset.copyWith(ZanoAsset other, String? icon, String? tag, {String? assetId, bool enabled = false})
|
||||
ZanoAsset.copyWith(ZanoAsset other, String? icon, /*String? tag,*/ {String? assetId, bool enabled = false})
|
||||
: this.fullName = other.fullName,
|
||||
this.ticker = other.ticker,
|
||||
this.assetId = assetId ?? other.assetId,
|
||||
this.decimalPoint = other.decimalPoint,
|
||||
this._enabled = enabled || other.enabled,
|
||||
this.tag = tag,
|
||||
//this.tag = tag,
|
||||
this.iconPath = icon,
|
||||
this.currentSupply = other.currentSupply,
|
||||
this.hiddenSupply = other.hiddenSupply,
|
||||
this.metaInfo = other.metaInfo,
|
||||
this.owner = other.owner,
|
||||
this.totalMaxSupply = other.totalMaxSupply,
|
||||
this.isInGlobalWhitelist = other.isInGlobalWhitelist,
|
||||
super(
|
||||
name: other.name,
|
||||
title: other.ticker.toUpperCase(),
|
||||
fullName: other.name,
|
||||
tag: tag,
|
||||
tag: 'ZANO',
|
||||
iconPath: icon,
|
||||
decimals: other.decimalPoint,
|
||||
);
|
||||
|
||||
factory ZanoAsset.fromJson(Map<String, dynamic> json) => ZanoAsset(
|
||||
factory ZanoAsset.fromJson(Map<String, dynamic> json, {bool isInGlobalWhitelist = false}) => ZanoAsset(
|
||||
assetId: json['asset_id'] as String? ?? '',
|
||||
currentSupply: json['current_supply'] as int? ?? 0,
|
||||
decimalPoint: json['decimal_point'] as int? ?? ZanoFormatter.defaultDecimalPoint,
|
||||
|
@ -91,9 +95,10 @@ class ZanoAsset extends CryptoCurrency with HiveObjectMixin {
|
|||
owner: json['owner'] as String? ?? '',
|
||||
ticker: json['ticker'] as String? ?? '',
|
||||
totalMaxSupply: json['total_max_supply'] as int? ?? 0,
|
||||
isInGlobalWhitelist: isInGlobalWhitelist,
|
||||
);
|
||||
|
||||
static const typeId = ZANO_ASSET_TYPE_ID;
|
||||
static const zanoAssetsBoxName = 'zanoAssetsBox';
|
||||
static const zanoAssetsBoxName = 'ZanoAssetsBox123'; // TODO: change to normal name
|
||||
static const defaultOwner = '0000000000000000000000000000000000000000000000000000000000000000';
|
||||
}
|
||||
|
|
|
@ -5,14 +5,13 @@ class ZanoBalance extends Balance {
|
|||
final int total;
|
||||
final int unlocked;
|
||||
final int decimalPoint;
|
||||
ZanoBalance({required this.total, required this.unlocked, required this.decimalPoint}) : super(unlocked, total - unlocked);
|
||||
ZanoBalance({required this.total, required this.unlocked, this.decimalPoint = ZanoFormatter.defaultDecimalPoint}) : super(unlocked, total - unlocked);
|
||||
|
||||
ZanoBalance.empty({this.decimalPoint = ZanoFormatter.defaultDecimalPoint}): total = 0, unlocked = 0, super(0, 0);
|
||||
|
||||
@override
|
||||
String get formattedAdditionalBalance => ZanoFormatter.intAmountToString(total - unlocked, decimalPoint);
|
||||
|
||||
@override
|
||||
String get formattedAvailableBalance => ZanoFormatter.intAmountToString(unlocked, decimalPoint);
|
||||
|
||||
// @override
|
||||
// String get formattedFrozenBalance => '';
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import 'package:cw_core/transaction_priority.dart';
|
|||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/wallet_credentials.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_zano/api/model/balance.dart';
|
||||
import 'package:cw_zano/api/model/create_wallet_result.dart';
|
||||
import 'package:cw_zano/api/model/destination.dart';
|
||||
import 'package:cw_zano/api/model/get_wallet_status_result.dart';
|
||||
|
@ -31,6 +32,7 @@ import 'package:cw_zano/zano_wallet_service.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
part 'zano_wallet.g.dart';
|
||||
|
||||
|
@ -59,6 +61,7 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
|
|||
|
||||
static const String zanoAssetId = 'd6329b5b1f7c0805b5c345f4957554002a2f557845f64d7645dae0e051a6498a';
|
||||
late final Box<ZanoAsset> zanoAssetsBox;
|
||||
List<ZanoAsset> whitelists = [];
|
||||
List<ZanoAsset> get zanoAssets => zanoAssetsBox.values.toList();
|
||||
// final Map<String, ZanoAsset> zanoAssets = {};
|
||||
|
||||
|
@ -74,7 +77,7 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
|
|||
Timer? _autoSaveTimer;
|
||||
|
||||
ZanoWalletBase(WalletInfo walletInfo)
|
||||
: balance = ObservableMap.of({CryptoCurrency.zano: ZanoBalance(total: 0, unlocked: 0, decimalPoint: ZanoFormatter.defaultDecimalPoint)}),
|
||||
: balance = ObservableMap.of({CryptoCurrency.zano: ZanoBalance.empty()}),
|
||||
_isTransactionUpdating = false,
|
||||
_hasSyncAfterStartup = false,
|
||||
walletAddresses = ZanoWalletAddresses(walletInfo),
|
||||
|
@ -137,15 +140,16 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
|
|||
|
||||
static void _parseCreateWalletResult(CreateWalletResult result, ZanoWallet wallet) {
|
||||
wallet.hWallet = result.walletId;
|
||||
_info('setting hWallet = ${result.walletId}');
|
||||
wallet.walletAddresses.address = result.wi.address;
|
||||
for (final item in result.wi.balances) {
|
||||
if (item.assetInfo.ticker == 'ZANO') {
|
||||
wallet.balance[CryptoCurrency.zano] = ZanoBalance(
|
||||
total: item.total,
|
||||
unlocked: item.unlocked,
|
||||
decimalPoint: ZanoFormatter.defaultDecimalPoint,
|
||||
);
|
||||
} else {
|
||||
// TODO: here will be always empty!
|
||||
for (final asset in wallet.balance.keys) {
|
||||
if (asset is ZanoAsset && asset.assetId == item.assetInfo.assetId) {
|
||||
wallet.balance[asset] = ZanoBalance(
|
||||
|
@ -306,7 +310,7 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
|
|||
print(
|
||||
'assets in box total: ${zanoAssetsBox.length} ${zanoAssetsBox.values} active: ${zanoAssetsBox.values.where((element) => element.enabled).length} ${zanoAssetsBox.values.where((element) => element.enabled)}');
|
||||
for (final asset in zanoAssetsBox.values) {
|
||||
if (asset.enabled) balance[asset] = ZanoBalance(total: 0, unlocked: 0, decimalPoint: asset.decimalPoint);
|
||||
if (asset.enabled) balance[asset] = ZanoBalance.empty(decimalPoint: asset.decimalPoint);
|
||||
}
|
||||
await walletAddresses.init();
|
||||
await walletAddresses.updateAddress(address);
|
||||
|
@ -392,7 +396,65 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
|
|||
publicViewKey: walletInfo.wiExtended.viewPublicKey,
|
||||
);
|
||||
|
||||
final whitelists = await getAssetsWhitelist();
|
||||
bool areSetsEqual<T>(Set<T> set1, Set<T> set2) => set1.length == set2.length && set1.every(set2.contains);
|
||||
|
||||
Set<String> getSetFromWhitelist(List<ZanoAsset> whitelist, bool isInGlobalWhitelist) =>
|
||||
whitelist.where((item) => item.isInGlobalWhitelist == isInGlobalWhitelist).map((item) => item.assetId).toSet();
|
||||
bool areWhitelistsTheSame(List<ZanoAsset> whitelist1, List<ZanoAsset> whitelist2) {
|
||||
return areSetsEqual(getSetFromWhitelist(whitelist1, true), getSetFromWhitelist(whitelist2, true)) &&
|
||||
areSetsEqual(getSetFromWhitelist(whitelist1, false), getSetFromWhitelist(whitelist2, false));
|
||||
}
|
||||
|
||||
void addOrUpdateBalance(ZanoAsset asset, Balance? _balance) {
|
||||
if (balance.keys.any((element) => element is ZanoAsset && element.assetId == asset.assetId)) {
|
||||
balance[balance.keys.firstWhere((element) => element is ZanoAsset && element.assetId == asset.assetId)] = _balance == null
|
||||
? ZanoBalance.empty(decimalPoint: asset.decimalPoint)
|
||||
: ZanoBalance(total: _balance.total, unlocked: _balance.unlocked, decimalPoint: asset.decimalPoint);
|
||||
} else {
|
||||
balance[asset] = _balance == null
|
||||
? ZanoBalance.empty(decimalPoint: asset.decimalPoint)
|
||||
: ZanoBalance(total: _balance.total, unlocked: _balance.unlocked, decimalPoint: asset.decimalPoint);
|
||||
}
|
||||
}
|
||||
|
||||
final whitelistsFromServer = await getAssetsWhitelist();
|
||||
void loadWhitelists() {
|
||||
debugPrint('loadWhitelists');
|
||||
final globalWhitelist = whitelistsFromServer.where((item) => item.isInGlobalWhitelist);
|
||||
final globalWhitelistIds = globalWhitelist.map((item) => item.assetId).toSet();
|
||||
final localWhitelist = whitelistsFromServer.where((item) => !item.isInGlobalWhitelist && !globalWhitelistIds.contains(item.assetId));
|
||||
for (final asset in globalWhitelist.followedBy(localWhitelist)) {
|
||||
// we have two options:
|
||||
// 1. adding as active (enabled) and adding to balance (even there's no balance for this asset)
|
||||
// 2. checking if there's a balance, then setting enabled true or false
|
||||
bool firstOption = 1 == 0;
|
||||
if (firstOption) {
|
||||
asset.enabled = true;
|
||||
zanoAssetsBox.put(asset.assetId, ZanoAsset.copyWith(asset, _getIconPath(asset.title), enabled: true));
|
||||
addOrUpdateBalance(asset, walletInfo.wi.balances.firstWhereOrNull((item) => item.assetId == asset.assetId));
|
||||
} else {
|
||||
final _balance = walletInfo.wi.balances.firstWhereOrNull((item) => item.assetId == asset.assetId);
|
||||
zanoAssetsBox.put(asset.assetId, ZanoAsset.copyWith(asset, _getIconPath(asset.title), enabled: _balance != null));
|
||||
addOrUpdateBalance(asset, _balance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.whitelists.isEmpty) {
|
||||
if (zanoAssetsBox.isEmpty) loadWhitelists();
|
||||
this.whitelists = whitelistsFromServer;
|
||||
} else if (!areWhitelistsTheSame(whitelistsFromServer, this.whitelists)) {
|
||||
// // updating whitelists from server
|
||||
// if (zanoAssetsBox.isEmpty) {
|
||||
// debugPrint('first loading of whitelists');
|
||||
// loadWhitelists();
|
||||
// } else {
|
||||
// debugPrint('later updating of whitelists');
|
||||
// }
|
||||
debugPrint('whitelists changed!');
|
||||
if (zanoAssetsBox.isEmpty) loadWhitelists();
|
||||
this.whitelists = whitelistsFromServer;
|
||||
}
|
||||
// TODO: here should be synchronization of whitelists
|
||||
// for (final item in whitelists) {
|
||||
// if (!zanoAssets.containsKey(item.assetId)) zanoAssets[item.assetId] = item;
|
||||
|
@ -400,23 +462,33 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
|
|||
// // removing assets missing in whitelists (in case some were removed since last time)
|
||||
// zanoAssets.removeWhere((key, _) => !whitelists.any((element) => element.assetId == key));
|
||||
|
||||
for (final asset in balance.keys) {
|
||||
if (asset == CryptoCurrency.zano) {
|
||||
final _balance = walletInfo.wi.balances.firstWhere((element) => element.assetId == zanoAssetId);
|
||||
balance[asset] = ZanoBalance(total: _balance.total, unlocked: _balance.unlocked);
|
||||
} else if (asset is ZanoAsset) {
|
||||
addOrUpdateBalance(asset, walletInfo.wi.balances.firstWhereOrNull((element) => element.assetId == asset.assetId));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// matching balances and whitelists
|
||||
// 1. show only balances available in whitelists
|
||||
// 2. set whitelists available in balances as 'enabled' ('disabled' by default)
|
||||
for (final item in walletInfo.wi.balances) {
|
||||
if (item.assetInfo.ticker == 'ZANO') {
|
||||
balance[CryptoCurrency.zano] = ZanoBalance(total: item.total, unlocked: item.unlocked, decimalPoint: ZanoFormatter.defaultDecimalPoint);
|
||||
for (final b in walletInfo.wi.balances) {
|
||||
if (b.assetInfo.ticker == 'ZANO') {
|
||||
balance[CryptoCurrency.zano] = ZanoBalance(total: b.total, unlocked: b.unlocked, decimalPoint: ZanoFormatter.defaultDecimalPoint);
|
||||
} else {
|
||||
final asset = zanoAssetsBox.get(item.assetInfo.assetId);
|
||||
final asset = zanoAssetsBox.get(b.assetInfo.assetId);
|
||||
if (asset == null) {
|
||||
debugPrint('balance for an unknown asset ${item.assetInfo.assetId}');
|
||||
debugPrint('balance for an unknown asset ${b.assetInfo.assetId}');
|
||||
continue;
|
||||
}
|
||||
if (balance.keys.any((element) => element is ZanoAsset && element.assetId == item.assetInfo.assetId)) {
|
||||
balance[balance.keys.firstWhere((element) => element is ZanoAsset && element.assetId == item.assetInfo.assetId)] =
|
||||
ZanoBalance(total: item.total, unlocked: item.unlocked, decimalPoint: asset.decimalPoint);
|
||||
if (balance.keys.any((element) => element is ZanoAsset && element.assetId == b.assetInfo.assetId)) {
|
||||
balance[balance.keys.firstWhere((element) => element is ZanoAsset && element.assetId == b.assetInfo.assetId)] =
|
||||
ZanoBalance(total: b.total, unlocked: b.unlocked, decimalPoint: asset.decimalPoint);
|
||||
} else {
|
||||
balance[asset] = ZanoBalance(total: item.total, unlocked: item.unlocked, decimalPoint: asset.decimalPoint);
|
||||
balance[asset] = ZanoBalance(total: b.total, unlocked: b.unlocked, decimalPoint: asset.decimalPoint);
|
||||
}
|
||||
//balance[asset] = ZanoBalance(total: item.total, unlocked: item.unlocked, decimalPoint: asset.decimalPoint);
|
||||
asset.enabled = true;
|
||||
|
@ -426,7 +498,7 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
|
|||
balance.removeWhere(
|
||||
(key, _) =>
|
||||
key != CryptoCurrency.zano && !walletInfo.wi.balances.any((element) => element.assetInfo.assetId == (key as ZanoAsset).assetId),
|
||||
);
|
||||
);*/
|
||||
|
||||
//if (_counter++ % 10 == 0) await _askForUpdateTransactionHistory();
|
||||
}
|
||||
|
@ -465,29 +537,29 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
|
|||
if (assetDescriptor == null) {
|
||||
throw "there's no zano asset with id $assetId";
|
||||
}
|
||||
String? iconPath;
|
||||
try {
|
||||
iconPath = CryptoCurrency.all.firstWhere((element) => element.title.toUpperCase() == assetDescriptor.title.toUpperCase()).iconPath;
|
||||
} catch (_) {}
|
||||
// TODO: copywith two times. was it intended
|
||||
final asset = ZanoAsset.copyWith(assetDescriptor, iconPath, 'ZANO', assetId: assetId, enabled: true);
|
||||
zanoAssetsBox.put(asset.assetId, ZanoAsset.copyWith(asset, iconPath, 'ZANO'));
|
||||
balance[asset] = ZanoBalance(total: 0, unlocked: 0, decimalPoint: asset.decimalPoint);
|
||||
final iconPath = _getIconPath(assetDescriptor.title);
|
||||
final asset = ZanoAsset.copyWith(assetDescriptor, iconPath, assetId: assetId, enabled: true);
|
||||
zanoAssetsBox.put(asset.assetId, asset);
|
||||
balance[asset] = ZanoBalance.empty(decimalPoint: asset.decimalPoint);
|
||||
return asset;
|
||||
}
|
||||
|
||||
Future<void> changeZanoAssetAvailability(ZanoAsset asset) async {
|
||||
String? iconPath;
|
||||
String? _getIconPath(String title) {
|
||||
try {
|
||||
iconPath = CryptoCurrency.all.firstWhere((element) => element.title.toUpperCase() == asset.title.toUpperCase()).iconPath;
|
||||
return CryptoCurrency.all.firstWhere((element) => element.title.toUpperCase() == title.toUpperCase()).iconPath;
|
||||
} catch (_) {}
|
||||
zanoAssetsBox.put(asset.assetId, ZanoAsset.copyWith(asset, iconPath, 'ZANO'));
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<void> changeZanoAssetAvailability(ZanoAsset asset) async {
|
||||
String? iconPath = _getIconPath(asset.title);
|
||||
zanoAssetsBox.put(asset.assetId, ZanoAsset.copyWith(asset, iconPath));
|
||||
if (asset.enabled) {
|
||||
final assetDescriptor = await addAssetsWhitelist(asset.assetId);
|
||||
if (assetDescriptor == null) {
|
||||
throw 'error adding zano asset';
|
||||
}
|
||||
balance[asset] = ZanoBalance(total: 0, unlocked: 0, decimalPoint: asset.decimalPoint);
|
||||
balance[asset] = ZanoBalance.empty(decimalPoint: asset.decimalPoint);
|
||||
} else {
|
||||
final result = await removeAssetsWhitelist(asset.assetId);
|
||||
if (result == false) {
|
||||
|
@ -574,4 +646,8 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
|
|||
// 1. Actual new height; 2. Blocks left to finish; 3. Progress in percents;
|
||||
_onNewBlock.call(syncHeight, left, ptc);
|
||||
}
|
||||
|
||||
static void _info(String s) {
|
||||
debugPrint('[info] $s');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ mixin ZanoWalletApi {
|
|||
void closeWallet() => ApiCalls.closeWallet(hWallet: hWallet);
|
||||
|
||||
Future<bool> setupNode() async {
|
||||
debugPrint('[info] init $_defaultNodeUri');
|
||||
_info('init $_defaultNodeUri');
|
||||
final result = ApiCalls.setupNode(
|
||||
address: _defaultNodeUri,
|
||||
login: '',
|
||||
|
@ -57,7 +57,7 @@ mixin ZanoWalletApi {
|
|||
useSSL: false,
|
||||
isLightWallet: false,
|
||||
);
|
||||
debugPrint('[info] init result $result');
|
||||
_info('init result $result');
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -66,8 +66,7 @@ mixin ZanoWalletApi {
|
|||
final result = GetWalletInfoResult.fromJson(jsonDecode(json) as Map<String, dynamic>);
|
||||
if (_logJson) debugPrint('get_wallet_info $json');
|
||||
await _writeLog('get_wallet_info', 'get_wallet_info result $json');
|
||||
if (_logInfo)
|
||||
debugPrint('[info] get_wallet_info got ${result.wi.balances.length} balances: ${result.wi.balances} seed: ${_shorten(result.wiExtended.seed)}');
|
||||
_info('get_wallet_info got ${result.wi.balances.length} balances: ${result.wi.balances} seed: ${_shorten(result.wiExtended.seed)}');
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -81,8 +80,7 @@ mixin ZanoWalletApi {
|
|||
if (_logJson) debugPrint('get_wallet_status $json');
|
||||
await _writeLog('get_wallet_status', 'get_wallet_status result $json');
|
||||
if (_logInfo)
|
||||
debugPrint(
|
||||
'[info] get_wallet_status connected: ${status.isDaemonConnected} in refresh: ${status.isInLongRefresh} progress: ${status.progress} wallet state: ${status.walletState}');
|
||||
_info('get_wallet_status connected: ${status.isDaemonConnected} in refresh: ${status.isInLongRefresh} progress: ${status.progress} wallet state: ${status.walletState}');
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -90,14 +88,25 @@ mixin ZanoWalletApi {
|
|||
await _writeLog(methodName, 'invoke method $methodName params: ${jsonEncode(params)} hWallet: $hWallet');
|
||||
var invokeResult =
|
||||
ApiCalls.asyncCall(methodName: 'invoke', hWallet: hWallet, params: '{"method": "$methodName","params": ${jsonEncode(params)}}');
|
||||
var map = jsonDecode(invokeResult) as Map<String, dynamic>;
|
||||
Map<String, dynamic> map;
|
||||
try {
|
||||
map = jsonDecode(invokeResult) as Map<String, dynamic>;
|
||||
} catch (e) {
|
||||
debugPrint('exception in parsing json in invokeMethod: $invokeResult');
|
||||
rethrow;
|
||||
}
|
||||
int attempts = 0;
|
||||
if (map['job_id'] != null) {
|
||||
final jobId = map['job_id'] as int;
|
||||
do {
|
||||
await Future.delayed(Duration(milliseconds: attempts < 2 ? 100 : 500));
|
||||
final result = ApiCalls.tryPullResult(jobId);
|
||||
map = jsonDecode(result) as Map<String, dynamic>;
|
||||
try {
|
||||
map = jsonDecode(result) as Map<String, dynamic>;
|
||||
} catch (e) {
|
||||
debugPrint('exception in parsing json in invokeMethod: $result');
|
||||
rethrow;
|
||||
}
|
||||
if (map['status'] != null && map['status'] == _statusDelivered && map['result'] != null) {
|
||||
await _writeLog(methodName, 'invoke method $methodName result $result');
|
||||
return result;
|
||||
|
@ -114,13 +123,16 @@ mixin ZanoWalletApi {
|
|||
if (_logJson) debugPrint('assets_whitelist_get $json');
|
||||
final map = jsonDecode(json) as Map<String, dynamic>?;
|
||||
_checkForErrors(map);
|
||||
List<ZanoAsset> assets(String type) =>
|
||||
(map?['result']?['result']?[type] as List<dynamic>?)?.map((e) => ZanoAsset.fromJson(e as Map<String, dynamic>)).toList() ?? [];
|
||||
final localWhitelist = assets('local_whitelist');
|
||||
final globalWhitelist = assets('global_whitelist');
|
||||
final ownAssets = assets('own_assets');
|
||||
List<ZanoAsset> assets(String type, bool isGlobalWhitelist) =>
|
||||
(map?['result']?['result']?[type] as List<dynamic>?)
|
||||
?.map((e) => ZanoAsset.fromJson(e as Map<String, dynamic>, isInGlobalWhitelist: isGlobalWhitelist))
|
||||
.toList() ??
|
||||
[];
|
||||
final localWhitelist = assets('local_whitelist', false);
|
||||
final globalWhitelist = assets('global_whitelist', true);
|
||||
final ownAssets = assets('own_assets', false);
|
||||
if (_logInfo)
|
||||
print('[info] assets_whitelist_get got local whitelist: ${localWhitelist.length} ($localWhitelist); '
|
||||
_info('assets_whitelist_get got local whitelist: ${localWhitelist.length} ($localWhitelist); '
|
||||
'global whitelist: ${globalWhitelist.length} ($globalWhitelist); '
|
||||
'own assets: ${ownAssets.length} ($ownAssets)');
|
||||
return [...localWhitelist, ...globalWhitelist, ...ownAssets];
|
||||
|
@ -138,10 +150,10 @@ mixin ZanoWalletApi {
|
|||
_checkForErrors(map);
|
||||
if (map!['result']!['result']!['status']! == 'OK') {
|
||||
final assetDescriptor = ZanoAsset.fromJson(map['result']!['result']!['asset_descriptor']! as Map<String, dynamic>);
|
||||
if (_logInfo) print('[info] assets_whitelist_add added ${assetDescriptor.fullName} ${assetDescriptor.ticker}');
|
||||
_info('assets_whitelist_add added ${assetDescriptor.fullName} ${assetDescriptor.ticker}');
|
||||
return assetDescriptor;
|
||||
} else {
|
||||
if (_logInfo) print('[info] assets_whitelist_add status ${map['result']!['result']!['status']!}');
|
||||
_info('assets_whitelist_add status ${map['result']!['result']!['status']!}');
|
||||
return null;
|
||||
}
|
||||
} catch (e) {
|
||||
|
@ -156,7 +168,7 @@ mixin ZanoWalletApi {
|
|||
if (_logJson) print('assets_whitelist_remove $assetId $json');
|
||||
final map = jsonDecode(json) as Map<String, dynamic>?;
|
||||
_checkForErrors(map);
|
||||
if (_logInfo) print('[info] assets_whitelist_remove status ${map!['result']!['result']!['status']!}');
|
||||
_info('assets_whitelist_remove status ${map!['result']!['result']!['status']!}');
|
||||
return (map!['result']!['result']!['status']! == 'OK');
|
||||
} catch (e) {
|
||||
print('[error] assets_whitelist_remove $e');
|
||||
|
@ -182,14 +194,14 @@ mixin ZanoWalletApi {
|
|||
}
|
||||
final map = jsonDecode(result.body) as Map<String, dynamic>?;
|
||||
if (map!['error'] != null) {
|
||||
if (_logInfo) print('[info] get_asset_info $assetId error ${map['error']!['code']} ${map['error']!['message']}');
|
||||
_info('get_asset_info $assetId error ${map['error']!['code']} ${map['error']!['message']}');
|
||||
return null;
|
||||
} else if (map['result']!['status']! == 'OK') {
|
||||
final assetDescriptor = ZanoAsset.fromJson(map['result']!['asset_descriptor']! as Map<String, dynamic>);
|
||||
if (_logInfo) print('[info] get_asset_info $assetId ${assetDescriptor.fullName} ${assetDescriptor.ticker}');
|
||||
_info('get_asset_info $assetId ${assetDescriptor.fullName} ${assetDescriptor.ticker}');
|
||||
return assetDescriptor;
|
||||
} else {
|
||||
if (_logInfo) print('[info] get_asset_info $assetId status ${map['result']!['status']!}');
|
||||
_info('get_asset_info $assetId status ${map['result']!['status']!}');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -214,10 +226,10 @@ mixin ZanoWalletApi {
|
|||
_checkForErrors(map);
|
||||
final transfers = map?['result']?['result']?['transfers'] as List<dynamic>?;
|
||||
if (transfers == null) {
|
||||
if (_logInfo) print('[info] get_recent_txs_and_info empty transfers');
|
||||
_info('get_recent_txs_and_info empty transfers');
|
||||
return [];
|
||||
}
|
||||
if (_logInfo) print('[info] get_recent_txs_and_info transfers: ${transfers.length}');
|
||||
_info('get_recent_txs_and_info transfers: ${transfers.length}');
|
||||
return transfers.map((e) => Transfer.fromJson(e as Map<String, dynamic>)).toList();
|
||||
} catch (e) {
|
||||
print('[error] get_recent_txs_and_info $e');
|
||||
|
@ -232,7 +244,7 @@ mixin ZanoWalletApi {
|
|||
String _shorten(String s) => s.length > 10 ? '${s.substring(0, 4)}...${s.substring(s.length - 4)}' : s;
|
||||
|
||||
Future<CreateWalletResult> createWallet(String path, String password) async {
|
||||
if (_logInfo) debugPrint('[info] create_wallet path $path password ${_shorten(password)}');
|
||||
_info('create_wallet path $path password ${_shorten(password)}');
|
||||
await _writeLog('create_wallet', 'create_wallet path $path password ${_shorten(password)}');
|
||||
final json = ApiCalls.createWallet(path: path, password: password);
|
||||
if (_logJson) debugPrint('create_wallet $json');
|
||||
|
@ -247,12 +259,12 @@ mixin ZanoWalletApi {
|
|||
throw ZanoWalletException('Error creating wallet file, empty response');
|
||||
}
|
||||
final result = CreateWalletResult.fromJson(map!['result'] as Map<String, dynamic>);
|
||||
if (_logInfo) debugPrint('[info] create_wallet ${result.name} ${result.seed}');
|
||||
_info('create_wallet ${result.name} ${result.seed}');
|
||||
return result;
|
||||
}
|
||||
|
||||
Future<CreateWalletResult> restoreWalletFromSeed(String path, String password, String seed) async {
|
||||
if (_logInfo) debugPrint('[info] restore_wallet path $path password ${_shorten(password)} seed ${_shorten(seed)}');
|
||||
_info('restore_wallet path $path password ${_shorten(password)} seed ${_shorten(seed)}');
|
||||
await _writeLog('restore_wallet', 'restore_wallet path $path password ${_shorten(password)} seed ${_shorten(seed)}');
|
||||
final json = ApiCalls.restoreWalletFromSeed(path: path, password: password, seed: seed);
|
||||
if (_logJson) debugPrint('restore_wallet $json');
|
||||
|
@ -272,12 +284,12 @@ mixin ZanoWalletApi {
|
|||
throw RestoreFromKeysException('Error restoring wallet, empty response');
|
||||
}
|
||||
final result = CreateWalletResult.fromJson(map!['result'] as Map<String, dynamic>);
|
||||
if (_logInfo) debugPrint('[info] restore_wallet ${result.name} ${result.wi.address}');
|
||||
_info('restore_wallet ${result.name} ${result.wi.address}');
|
||||
return result;
|
||||
}
|
||||
|
||||
Future<CreateWalletResult> loadWallet(String path, String password, [bool secondAttempt = false]) async {
|
||||
if (_logInfo) debugPrint('[info] load_wallet path $path password ${_shorten(password)}');
|
||||
_info('load_wallet path $path password ${_shorten(password)}');
|
||||
await _writeLog('load_wallet', 'load_wallet path $path password ${_shorten(password)}');
|
||||
final json = ApiCalls.loadWallet(path: path, password: password);
|
||||
if (_logJson) debugPrint('load_wallet $json');
|
||||
|
@ -300,7 +312,7 @@ mixin ZanoWalletApi {
|
|||
throw ZanoWalletException('Error loading wallet, empty response');
|
||||
}
|
||||
final result = CreateWalletResult.fromJson(map!['result'] as Map<String, dynamic>);
|
||||
if (_logInfo) debugPrint('[info] load_wallet ${result.name} ${result.wi.address}');
|
||||
_info('load_wallet ${result.name} ${result.wi.address}');
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -365,4 +377,10 @@ mixin ZanoWalletApi {
|
|||
await logFile.writeAsString(' ' + matches.map((element) => '${element.group(0)}').join(', ') + '\n', mode: FileMode.append);
|
||||
}
|
||||
}
|
||||
|
||||
static void _info(String s) {
|
||||
if (_logInfo) {
|
||||
debugPrint('[info] $s');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue