mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-22 19:49:22 +00:00
whitelists, some refactoring
This commit is contained in:
parent
5af75aa7ad
commit
662aba5d72
26 changed files with 240 additions and 160 deletions
|
@ -1,9 +0,0 @@
|
|||
class AddRemoveAssetsWhitelistParams {
|
||||
final String assetId;
|
||||
|
||||
AddRemoveAssetsWhitelistParams({required this.assetId});
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'asset_id': assetId,
|
||||
};
|
||||
}
|
9
cw_zano/lib/api/model/asset_id_params.dart
Normal file
9
cw_zano/lib/api/model/asset_id_params.dart
Normal file
|
@ -0,0 +1,9 @@
|
|||
class AssetIdParams {
|
||||
final String assetId;
|
||||
|
||||
AssetIdParams({required this.assetId});
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'asset_id': assetId,
|
||||
};
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:cw_core/amount_converter.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_zano/zano_asset.dart';
|
||||
import 'package:cw_zano/model/zano_asset.dart';
|
||||
|
||||
class Balance {
|
||||
final ZanoAsset assetInfo;
|
||||
|
|
13
cw_zano/lib/api/model/proxy_to_daemon_params.dart
Normal file
13
cw_zano/lib/api/model/proxy_to_daemon_params.dart
Normal file
|
@ -0,0 +1,13 @@
|
|||
import 'dart:convert';
|
||||
|
||||
class ProxyToDaemonParams {
|
||||
final String body;
|
||||
final String uri;
|
||||
|
||||
ProxyToDaemonParams({required this.body, required this.uri});
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'base64_body': base64Encode(utf8.encode(body)),
|
||||
'uri': uri,
|
||||
};
|
||||
}
|
13
cw_zano/lib/api/model/proxy_to_daemon_result.dart
Normal file
13
cw_zano/lib/api/model/proxy_to_daemon_result.dart
Normal file
|
@ -0,0 +1,13 @@
|
|||
import 'dart:convert';
|
||||
|
||||
class ProxyToDaemonResult {
|
||||
final String body;
|
||||
final int responseCode;
|
||||
|
||||
ProxyToDaemonResult({required this.body, required this.responseCode});
|
||||
|
||||
factory ProxyToDaemonResult.fromJson(Map<String, dynamic> json) => ProxyToDaemonResult(
|
||||
body: utf8.decode(base64Decode(json['base64_body'] as String? ?? '')),
|
||||
responseCode: json['response_code'] as int? ?? 0,
|
||||
);
|
||||
}
|
|
@ -21,7 +21,7 @@ class TransferParams {
|
|||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'destinations': destinations,
|
||||
'fee': fee,
|
||||
'fee': fee.toInt(),
|
||||
'mixin': mixin,
|
||||
'payment_id': paymentId,
|
||||
'comment': comment,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_zano/zano_asset.dart';
|
||||
import 'package:cw_zano/model/zano_asset.dart';
|
||||
|
||||
class DefaultZanoAssets {
|
||||
final List<ZanoAsset> _defaultAssets = [
|
||||
|
|
|
@ -59,6 +59,16 @@ class ZanoAsset extends CryptoCurrency with HiveObjectMixin {
|
|||
decimals: decimalPoint,
|
||||
);
|
||||
|
||||
// ZanoAsset.copyWithCurrency(CryptoCurrency other, String? icon, String? tag, String? assetId, {bool enabled = false}):
|
||||
// ZanoAsset(assetId: assetId, );
|
||||
// // this.fullName = other.fullName ?? other.title,
|
||||
// // this.ticker = other.title,
|
||||
// // this.decimalPoint = other.decimals,
|
||||
// // this.assetId = assetId,
|
||||
// // this.iconPath = icon,
|
||||
// // this.tag = tag,
|
||||
// // this._enabled = enabled;
|
||||
|
||||
ZanoAsset.copyWith(ZanoAsset other, String? icon, String? tag, {String? assetId, bool enabled = false})
|
||||
: this.fullName = other.fullName,
|
||||
this.ticker = other.ticker,
|
|
@ -12,12 +12,23 @@ class ZanoFormatter {
|
|||
..minimumFractionDigits = 1;
|
||||
|
||||
static Decimal _intDivision({required int amount, required BigInt divider}) => (Decimal.fromInt(amount) / Decimal.fromBigInt(divider)).toDecimal();
|
||||
static Decimal _bigIntDivision({required BigInt amount, required BigInt divider}) => (Decimal.fromBigInt(amount) / Decimal.fromBigInt(divider)).toDecimal();
|
||||
static Decimal _bigIntDivision({required BigInt amount, required BigInt divider}) =>
|
||||
(Decimal.fromBigInt(amount) / Decimal.fromBigInt(divider)).toDecimal();
|
||||
|
||||
static String intAmountToString(int amount, [int decimalPoint = defaultDecimalPoint]) => numberFormat.format(DecimalIntl(
|
||||
_intDivision(amount: amount, divider: BigInt.from(pow(10, decimalPoint))),
|
||||
),);
|
||||
static String bigIntAmountToString(BigInt amount, [int decimalPoint = defaultDecimalPoint]) => numberFormat.format(DecimalIntl(
|
||||
_bigIntDivision(amount: amount, divider: BigInt.from(pow(10, decimalPoint))),
|
||||
),);
|
||||
static String intAmountToString(int amount, [int decimalPoint = defaultDecimalPoint]) => numberFormat.format(
|
||||
DecimalIntl(
|
||||
_intDivision(
|
||||
amount: amount,
|
||||
divider: BigInt.from(pow(10, decimalPoint)),
|
||||
),
|
||||
),
|
||||
).replaceAll(',', '');
|
||||
static String bigIntAmountToString(BigInt amount, [int decimalPoint = defaultDecimalPoint]) => numberFormat.format(
|
||||
DecimalIntl(
|
||||
_bigIntDivision(
|
||||
amount: amount,
|
||||
divider: BigInt.from(pow(10, decimalPoint)),
|
||||
),
|
||||
),
|
||||
).replaceAll(',', '');
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'dart:core';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cw_core/transaction_history.dart';
|
||||
import 'package:cw_zano/zano_transaction_info.dart';
|
||||
import 'package:cw_zano/model/zano_transaction_info.dart';
|
||||
|
||||
part 'zano_transaction_history.g.dart';
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'dart:convert';
|
||||
import 'package:cw_zano/api/api_calls.dart';
|
||||
import 'package:cw_zano/api/model/get_address_info_result.dart';
|
||||
import 'package:cw_zano/zano_wallet_api.dart';
|
||||
|
||||
class ZanoUtils {
|
||||
static bool validateAddress(String address) {
|
||||
|
|
|
@ -15,15 +15,15 @@ import 'package:cw_zano/api/api_calls.dart';
|
|||
import 'package:cw_zano/api/model/destination.dart';
|
||||
import 'package:cw_zano/api/model/get_wallet_status_result.dart';
|
||||
import 'package:cw_zano/api/model/transfer.dart';
|
||||
import 'package:cw_zano/api/model/zano_wallet_keys.dart';
|
||||
import 'package:cw_zano/exceptions/zano_transaction_creation_exception.dart';
|
||||
import 'package:cw_zano/pending_zano_transaction.dart';
|
||||
import 'package:cw_zano/zano_asset.dart';
|
||||
import 'package:cw_zano/zano_balance.dart';
|
||||
import 'package:cw_zano/model/zano_wallet_keys.dart';
|
||||
import 'package:cw_zano/model/zano_transaction_creation_exception.dart';
|
||||
import 'package:cw_zano/model/pending_zano_transaction.dart';
|
||||
import 'package:cw_zano/model/zano_asset.dart';
|
||||
import 'package:cw_zano/model/zano_balance.dart';
|
||||
import 'package:cw_zano/zano_formatter.dart';
|
||||
import 'package:cw_zano/zano_transaction_credentials.dart';
|
||||
import 'package:cw_zano/model/zano_transaction_credentials.dart';
|
||||
import 'package:cw_zano/zano_transaction_history.dart';
|
||||
import 'package:cw_zano/zano_transaction_info.dart';
|
||||
import 'package:cw_zano/model/zano_transaction_info.dart';
|
||||
import 'package:cw_zano/zano_wallet_addresses.dart';
|
||||
import 'package:cw_zano/zano_wallet_api.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -130,7 +130,7 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
|
|||
@override
|
||||
Future<PendingTransaction> createTransaction(Object credentials) async {
|
||||
credentials as ZanoTransactionCredentials;
|
||||
bool isZano() => credentials.currency == CryptoCurrency.zano;
|
||||
final isZano = credentials.currency == CryptoCurrency.zano;
|
||||
final outputs = credentials.outputs;
|
||||
final hasMultiDestination = outputs.length > 1;
|
||||
final unlockedBalanceZano = BigInt.from(balance[CryptoCurrency.zano]?.unlocked ?? 0);
|
||||
|
@ -138,7 +138,7 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
|
|||
final fee = BigInt.from(calculateEstimatedFee(credentials.priority));
|
||||
late BigInt totalAmount;
|
||||
void checkForEnoughBalances() {
|
||||
if (isZano()) {
|
||||
if (isZano) {
|
||||
if (totalAmount + fee > unlockedBalanceZano) {
|
||||
throw ZanoTransactionCreationException(
|
||||
"You don't have enough coins (required: ${ZanoFormatter.bigIntAmountToString(totalAmount + fee)} ZANO, unlocked ${ZanoFormatter.bigIntAmountToString(unlockedBalanceZano)} ZANO).");
|
||||
|
@ -155,7 +155,7 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
|
|||
}
|
||||
}
|
||||
|
||||
final assetId = isZano() ? zanoAssetId : (currency as ZanoAsset).assetId;
|
||||
final assetId = isZano ? zanoAssetId : (credentials.currency as ZanoAsset).assetId;
|
||||
late List<Destination> destinations;
|
||||
if (hasMultiDestination) {
|
||||
if (outputs.any((output) => output.sendAll || (output.formattedCryptoAmount ?? 0) <= 0)) {
|
||||
|
@ -173,7 +173,7 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
|
|||
} else {
|
||||
final output = outputs.first;
|
||||
if (output.sendAll) {
|
||||
if (isZano()) {
|
||||
if (isZano) {
|
||||
totalAmount = unlockedBalanceZano - fee;
|
||||
} else {
|
||||
totalAmount = unlockedBalanceCurrency;
|
||||
|
@ -413,7 +413,7 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
|
|||
return asset;
|
||||
}
|
||||
|
||||
Future<void> addRemoveZanoAsset(ZanoAsset asset) async {
|
||||
Future<void> changeZanoAssetAvailability(ZanoAsset asset) async {
|
||||
String? iconPath;
|
||||
try {
|
||||
iconPath = CryptoCurrency.all.firstWhere((element) => element.title.toUpperCase() == asset.title.toUpperCase()).iconPath;
|
||||
|
@ -422,15 +422,13 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
|
|||
if (asset.enabled) {
|
||||
final assetDescriptor = await addAssetsWhitelist(asset.assetId);
|
||||
if (assetDescriptor == null) {
|
||||
print('error adding zano asset');
|
||||
return;
|
||||
throw 'error adding zano asset';
|
||||
}
|
||||
balance[asset] = ZanoBalance(total: 0, unlocked: 0, decimalPoint: asset.decimalPoint);
|
||||
} else {
|
||||
final result = await removeAssetsWhitelist(asset.assetId);
|
||||
if (result == false) {
|
||||
print('error removing zano asset');
|
||||
return;
|
||||
throw 'error removing zano asset';
|
||||
}
|
||||
balance.removeWhere((key, _) => key is ZanoAsset && key.assetId == asset.assetId);
|
||||
}
|
||||
|
@ -439,12 +437,12 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
|
|||
Future<void> deleteZanoAsset(ZanoAsset asset) async {
|
||||
final result = await removeAssetsWhitelist(asset.assetId);
|
||||
if (result == false) return;
|
||||
await asset.delete();
|
||||
if (asset.isInBox) await asset.delete();
|
||||
balance.removeWhere((key, _) => key is ZanoAsset && key.assetId == asset.assetId);
|
||||
}
|
||||
|
||||
Future<ZanoAsset?> getZanoAsset(String assetId) async {
|
||||
return null;
|
||||
return await getAssetInfo(assetId);
|
||||
}
|
||||
|
||||
// List<ZanoTransactionInfo> _getAllTransactions(dynamic _) =>
|
||||
|
|
|
@ -2,12 +2,15 @@ import 'dart:convert';
|
|||
|
||||
import 'package:cw_core/transaction_priority.dart';
|
||||
import 'package:cw_zano/api/api_calls.dart';
|
||||
import 'package:cw_zano/api/model/add_remove_assets_whitelist_params.dart';
|
||||
import 'package:cw_zano/api/model/asset_id_params.dart';
|
||||
import 'package:cw_zano/api/model/get_address_info_result.dart';
|
||||
import 'package:cw_zano/api/model/get_recent_txs_and_info_params.dart';
|
||||
import 'package:cw_zano/api/model/get_wallet_info_result.dart';
|
||||
import 'package:cw_zano/api/model/get_wallet_status_result.dart';
|
||||
import 'package:cw_zano/api/model/proxy_to_daemon_params.dart';
|
||||
import 'package:cw_zano/api/model/proxy_to_daemon_result.dart';
|
||||
import 'package:cw_zano/api/model/transfer.dart';
|
||||
import 'package:cw_zano/zano_asset.dart';
|
||||
import 'package:cw_zano/model/zano_asset.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import 'api/model/store_result.dart';
|
||||
|
@ -47,10 +50,10 @@ mixin ZanoWalletApi {
|
|||
final result = GetWalletInfoResult.fromJson(jsonDecode(json) as Map<String, dynamic>);
|
||||
switch (_logType) {
|
||||
case _LogType.json:
|
||||
print('get_wallet_info $json');
|
||||
debugPrint('get_wallet_info $json');
|
||||
break;
|
||||
case _LogType.simple:
|
||||
print('get_wallet_info got ${result.wi.balances.length} balances: ${result.wi.balances}');
|
||||
debugPrint('get_wallet_info got ${result.wi.balances.length} balances: ${result.wi.balances}');
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -61,10 +64,11 @@ mixin ZanoWalletApi {
|
|||
final status = GetWalletStatusResult.fromJson(jsonDecode(json) as Map<String, dynamic>);
|
||||
switch (_logType) {
|
||||
case _LogType.json:
|
||||
print('get_wallet_status $json');
|
||||
debugPrint('get_wallet_status $json');
|
||||
break;
|
||||
case _LogType.simple:
|
||||
print('get_wallet_status connected: ${status.isDaemonConnected} in refresh: ${status.isInLongRefresh} wallet state: ${status.walletState}');
|
||||
debugPrint(
|
||||
'get_wallet_status connected: ${status.isDaemonConnected} in refresh: ${status.isInLongRefresh} wallet state: ${status.walletState}');
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
@ -91,13 +95,19 @@ mixin ZanoWalletApi {
|
|||
Future<List<ZanoAsset>> getAssetsWhitelist() async {
|
||||
try {
|
||||
final json = await invokeMethod('assets_whitelist_get', '{}');
|
||||
if (_logType == _LogType.json) print('assets_whitelist_get $json');
|
||||
/*if (_logType == _LogType.json)*/ debugPrint('assets_whitelist_get $json');
|
||||
final map = jsonDecode(json) as Map<String, dynamic>?;
|
||||
_checkForErrors(map);
|
||||
final assets = map?['result']?['result']?['assets'] as List<dynamic>?;
|
||||
final result = assets?.map((e) => ZanoAsset.fromJson(e as Map<String, dynamic>)).toList();
|
||||
if (_logType == _LogType.simple) print('assets_whitelist_get got ${result?.length ?? 0} assets: $result');
|
||||
return result ?? [];
|
||||
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');
|
||||
if (_logType == _LogType.simple)
|
||||
print('assets_whitelist_get got local whitelist: ${localWhitelist.length} ($localWhitelist); '
|
||||
'global whitelist: ${globalWhitelist.length} ($globalWhitelist); '
|
||||
'own assets: ${ownAssets.length} ($ownAssets)');
|
||||
return [...localWhitelist, ...globalWhitelist, ...ownAssets];
|
||||
} catch (e) {
|
||||
print(e.toString());
|
||||
return [];
|
||||
|
@ -106,7 +116,7 @@ mixin ZanoWalletApi {
|
|||
|
||||
Future<ZanoAsset?> addAssetsWhitelist(String assetId) async {
|
||||
try {
|
||||
final json = await invokeMethod('assets_whitelist_add', AddRemoveAssetsWhitelistParams(assetId: assetId));
|
||||
final json = await invokeMethod('assets_whitelist_add', AssetIdParams(assetId: assetId));
|
||||
if (_logType == _LogType.json) print('assets_whitelist_add $assetId $json');
|
||||
final map = jsonDecode(json) as Map<String, dynamic>?;
|
||||
_checkForErrors(map);
|
||||
|
@ -126,7 +136,7 @@ mixin ZanoWalletApi {
|
|||
|
||||
Future<bool> removeAssetsWhitelist(String assetId) async {
|
||||
try {
|
||||
final json = await invokeMethod('assets_whitelist_remove', AddRemoveAssetsWhitelistParams(assetId: assetId));
|
||||
final json = await invokeMethod('assets_whitelist_remove', AssetIdParams(assetId: assetId));
|
||||
if (_logType == _LogType.json) print('assets_whitelist_remove $assetId $json');
|
||||
final map = jsonDecode(json) as Map<String, dynamic>?;
|
||||
_checkForErrors(map);
|
||||
|
@ -138,6 +148,36 @@ mixin ZanoWalletApi {
|
|||
}
|
||||
}
|
||||
|
||||
Future<ProxyToDaemonResult?> _proxyToDaemon(String uri, String body) async {
|
||||
final json = await invokeMethod('proxy_to_daemon', ProxyToDaemonParams(body: body, uri: uri));
|
||||
final map = jsonDecode(json) as Map<String, dynamic>?;
|
||||
_checkForErrors(map);
|
||||
return ProxyToDaemonResult.fromJson(map!['result']['result'] as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
Future<ZanoAsset?> getAssetInfo(String assetId) async {
|
||||
final methodName = 'get_asset_info';
|
||||
final params = AssetIdParams(assetId: assetId);
|
||||
final result = await _proxyToDaemon('/json_rpc', '{"method": "$methodName","params": ${jsonEncode(params)}}');
|
||||
if (_logType == _LogType.json) print('$methodName $assetId ${result?.body}');
|
||||
if (result == null) {
|
||||
debugPrint('get_asset_info empty result');
|
||||
return null;
|
||||
}
|
||||
final map = jsonDecode(result.body) as Map<String, dynamic>?;
|
||||
if (map!['error'] != null) {
|
||||
if (_logType == _LogType.simple) print('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 (_logType == _LogType.simple) print('get_asset_info $assetId ${assetDescriptor.fullName} ${assetDescriptor.ticker}');
|
||||
return assetDescriptor;
|
||||
} else {
|
||||
if (_logType == _LogType.simple) print('get_asset_info $assetId status ${map['result']!['status']!}');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<StoreResult?> store() async {
|
||||
try {
|
||||
final json = await invokeMethod('store', '{}');
|
||||
|
@ -153,7 +193,7 @@ mixin ZanoWalletApi {
|
|||
Future<List<Transfer>> getRecentTxsAndInfo() async {
|
||||
try {
|
||||
final json = await invokeMethod('get_recent_txs_and_info', GetRecentTxsAndInfoParams(offset: 0, count: 30));
|
||||
debugPrint('get_recent_txs_and_info $json');
|
||||
//debugPrint('get_recent_txs_and_info $json');
|
||||
final map = jsonDecode(json) as Map<String, dynamic>?;
|
||||
_checkForErrors(map);
|
||||
final transfers = map?['result']?['result']?['transfers'] as List<dynamic>?;
|
||||
|
@ -168,6 +208,10 @@ mixin ZanoWalletApi {
|
|||
}
|
||||
}
|
||||
|
||||
GetAddressInfoResult getAddressInfo(String address) => GetAddressInfoResult.fromJson(
|
||||
jsonDecode(ApiCalls.getAddressInfo(address: address)) as Map<String, dynamic>,
|
||||
);
|
||||
|
||||
void _checkForErrors(Map<String, dynamic>? map) {
|
||||
if (map == null) {
|
||||
throw 'empty response';
|
||||
|
|
|
@ -17,8 +17,8 @@ import 'package:cw_zano/api/exceptions/create_wallet_exception.dart';
|
|||
import 'package:cw_zano/api/exceptions/restore_from_seed_exception.dart';
|
||||
import 'package:cw_zano/api/exceptions/wrong_seed_exception.dart';
|
||||
import 'package:cw_zano/api/model/create_wallet_result.dart';
|
||||
import 'package:cw_zano/zano_asset.dart';
|
||||
import 'package:cw_zano/zano_balance.dart';
|
||||
import 'package:cw_zano/model/zano_asset.dart';
|
||||
import 'package:cw_zano/model/zano_balance.dart';
|
||||
import 'package:cw_zano/zano_formatter.dart';
|
||||
import 'package:cw_zano/zano_wallet.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
|
|
@ -7,12 +7,12 @@ import 'package:cw_core/erc20_token.dart';
|
|||
import 'package:cw_zano/zano_utils.dart';
|
||||
|
||||
class AddressValidator extends TextValidator {
|
||||
AddressValidator({required CryptoCurrency type})
|
||||
AddressValidator({required CryptoCurrency type, bool skipZanoAddressValidation = false})
|
||||
: super(
|
||||
errorMessage: S.current.error_text_address,
|
||||
useAdditionalValidation: type == CryptoCurrency.btc
|
||||
? (String txt) => validateAddress(address: txt, network: BitcoinNetwork.mainnet)
|
||||
: type == CryptoCurrency.zano
|
||||
: type == CryptoCurrency.zano && !skipZanoAddressValidation
|
||||
? ZanoUtils.validateAddress
|
||||
: null,
|
||||
pattern: getPattern(type),
|
||||
|
@ -125,6 +125,8 @@ class AddressValidator extends TextValidator {
|
|||
return 'D([1-9a-km-zA-HJ-NP-Z]){33}';
|
||||
case CryptoCurrency.btcln:
|
||||
return '^(lnbc|LNBC)([0-9]{1,}[a-zA-Z0-9]+)';
|
||||
case CryptoCurrency.zano:
|
||||
return r'$.^'; // always false, we use additional validation then
|
||||
default:
|
||||
return '[0-9a-zA-Z]';
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ import 'package:cake_wallet/view_model/dashboard/home_settings_view_model.dart';
|
|||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/erc20_token.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cw_zano/zano_asset.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
|
@ -196,27 +195,12 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
|
|||
child: PrimaryButton(
|
||||
onPressed: () async {
|
||||
if (_formKey.currentState!.validate() && (!_showDisclaimer || _disclaimerChecked)) {
|
||||
if (widget.homeSettingsViewModel.walletType == WalletType.zano) {
|
||||
if (!await widget.homeSettingsViewModel.addAsset(_contractAddressController.text)) {
|
||||
await showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithOneAction(
|
||||
alertTitle: S.current.error,
|
||||
alertContent: 'Cannot add asset ${_contractAddressController.text}',
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () => Navigator.of(context).pop());
|
||||
});
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
await widget.homeSettingsViewModel.addToken(Erc20Token(
|
||||
name: _tokenNameController.text,
|
||||
symbol: _tokenSymbolController.text,
|
||||
contractAddress: _contractAddressController.text,
|
||||
decimal: int.parse(_tokenDecimalController.text),
|
||||
));
|
||||
}
|
||||
await widget.homeSettingsViewModel.addToken(Erc20Token(
|
||||
name: _tokenNameController.text,
|
||||
symbol: _tokenSymbolController.text,
|
||||
contractAddress: _contractAddressController.text,
|
||||
decimal: int.parse(_tokenDecimalController.text),
|
||||
));
|
||||
}
|
||||
if (context.mounted) {
|
||||
Navigator.pop(context);
|
||||
|
@ -240,9 +224,10 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
|
|||
final token = await widget.homeSettingsViewModel.getToken(_contractAddressController.text);
|
||||
|
||||
if (token != null) {
|
||||
if (_tokenNameController.text.isEmpty) _tokenNameController.text = token.name;
|
||||
if (_tokenSymbolController.text.isEmpty) _tokenSymbolController.text = token.title;
|
||||
if (_tokenDecimalController.text.isEmpty) _tokenDecimalController.text = token.decimals.toString();
|
||||
final isZano = widget.homeSettingsViewModel.walletType == WalletType.zano;
|
||||
if (_tokenNameController.text.isEmpty || isZano) _tokenNameController.text = token.name;
|
||||
if (_tokenSymbolController.text.isEmpty || isZano) _tokenSymbolController.text = token.title;
|
||||
if (_tokenDecimalController.text.isEmpty || isZano) _tokenDecimalController.text = token.decimals.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -273,60 +258,59 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
|
|||
placeholder: S.of(context).token_contract_address,
|
||||
options: [AddressTextFieldOption.paste],
|
||||
buttonColor: Theme.of(context).hintColor,
|
||||
validator: AddressValidator(type: widget.homeSettingsViewModel.nativeToken),
|
||||
// we don't use zano addresses validations here, addresses and asset ids are difference entities
|
||||
validator: AddressValidator(type: widget.homeSettingsViewModel.nativeToken, skipZanoAddressValidation: true),
|
||||
onPushPasteButton: (_) {
|
||||
_pasteText();
|
||||
},
|
||||
),
|
||||
if (widget.homeSettingsViewModel.walletType != WalletType.zano) ...[
|
||||
const SizedBox(height: 8),
|
||||
BaseTextFormField(
|
||||
controller: _tokenNameController,
|
||||
focusNode: _tokenNameFocusNode,
|
||||
onSubmit: (_) => FocusScope.of(context).requestFocus(_tokenSymbolFocusNode),
|
||||
textInputAction: TextInputAction.next,
|
||||
hintText: S.of(context).token_name,
|
||||
validator: (text) {
|
||||
if (text?.isNotEmpty ?? false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return S.of(context).field_required;
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
BaseTextFormField(
|
||||
controller: _tokenSymbolController,
|
||||
focusNode: _tokenSymbolFocusNode,
|
||||
onSubmit: (_) => FocusScope.of(context).requestFocus(_tokenDecimalFocusNode),
|
||||
textInputAction: TextInputAction.next,
|
||||
hintText: S.of(context).token_symbol,
|
||||
validator: (text) {
|
||||
if (text?.isNotEmpty ?? false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return S.of(context).field_required;
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
BaseTextFormField(
|
||||
controller: _tokenDecimalController,
|
||||
focusNode: _tokenDecimalFocusNode,
|
||||
textInputAction: TextInputAction.done,
|
||||
hintText: S.of(context).token_decimal,
|
||||
validator: (text) {
|
||||
if (text?.isEmpty ?? true) {
|
||||
return S.of(context).field_required;
|
||||
}
|
||||
if (int.tryParse(text!) == null) {
|
||||
return S.of(context).invalid_input;
|
||||
}
|
||||
|
||||
const SizedBox(height: 8),
|
||||
BaseTextFormField(
|
||||
controller: _tokenNameController,
|
||||
focusNode: _tokenNameFocusNode,
|
||||
onSubmit: (_) => FocusScope.of(context).requestFocus(_tokenSymbolFocusNode),
|
||||
textInputAction: TextInputAction.next,
|
||||
hintText: S.of(context).token_name,
|
||||
validator: (text) {
|
||||
if (text?.isNotEmpty ?? false) {
|
||||
return null;
|
||||
},
|
||||
),
|
||||
],
|
||||
}
|
||||
|
||||
return S.of(context).field_required;
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
BaseTextFormField(
|
||||
controller: _tokenSymbolController,
|
||||
focusNode: _tokenSymbolFocusNode,
|
||||
onSubmit: (_) => FocusScope.of(context).requestFocus(_tokenDecimalFocusNode),
|
||||
textInputAction: TextInputAction.next,
|
||||
hintText: S.of(context).token_symbol,
|
||||
validator: (text) {
|
||||
if (text?.isNotEmpty ?? false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return S.of(context).field_required;
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
BaseTextFormField(
|
||||
controller: _tokenDecimalController,
|
||||
focusNode: _tokenDecimalFocusNode,
|
||||
textInputAction: TextInputAction.done,
|
||||
hintText: S.of(context).token_decimal,
|
||||
validator: (text) {
|
||||
if (text?.isEmpty ?? true) {
|
||||
return S.of(context).field_required;
|
||||
}
|
||||
if (int.tryParse(text!) == null) {
|
||||
return S.of(context).invalid_input;
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
),
|
||||
SizedBox(height: 24),
|
||||
],
|
||||
),
|
||||
|
|
|
@ -317,6 +317,8 @@ class WalletListBodyState extends State<WalletListBody> {
|
|||
return polygonIcon;
|
||||
case WalletType.solana:
|
||||
return solanaIcon;
|
||||
case WalletType.zano:
|
||||
return zanoIcon;
|
||||
default:
|
||||
return nonWalletTypeIcon;
|
||||
}
|
||||
|
|
|
@ -75,7 +75,9 @@ abstract class HomeSettingsViewModelBase with Store {
|
|||
}
|
||||
|
||||
if (_balanceViewModel.wallet.type == WalletType.zano) {
|
||||
await zano!.addZanoAsset(_balanceViewModel.wallet, token);
|
||||
// TODO: assuming that token is Erc20Token
|
||||
token as Erc20Token;
|
||||
await zano!.addZanoAssetById(_balanceViewModel.wallet, token.contractAddress);
|
||||
}
|
||||
|
||||
_updateTokensList();
|
||||
|
@ -150,7 +152,7 @@ abstract class HomeSettingsViewModelBase with Store {
|
|||
}
|
||||
|
||||
if (_balanceViewModel.wallet.type == WalletType.zano) {
|
||||
await zano!.addZanoAsset(_balanceViewModel.wallet, token);
|
||||
await zano!.changeZanoAssetAvailability(_balanceViewModel.wallet, token);
|
||||
}
|
||||
|
||||
_refreshTokensList();
|
||||
|
|
|
@ -51,7 +51,7 @@ part of 'zano.dart';
|
|||
}
|
||||
}*/
|
||||
|
||||
class CWZanoWalletDetails extends ZanoWalletDetails {
|
||||
/*class CWZanoWalletDetails extends ZanoWalletDetails {
|
||||
CWZanoWalletDetails(this._wallet);
|
||||
|
||||
final Object _wallet;
|
||||
|
@ -64,14 +64,14 @@ class CWZanoWalletDetails extends ZanoWalletDetails {
|
|||
// return Account(id: acc.id, label: acc.label);
|
||||
// }
|
||||
|
||||
@computed
|
||||
@override
|
||||
ZanoBalance get balance {
|
||||
final zanoWallet = _wallet as ZanoWallet;
|
||||
final balance = zanoWallet.balance;
|
||||
return ZanoBalance(fullBalance: balance[CryptoCurrency.zano]!.total, unlockedBalance: balance[CryptoCurrency.zano]!.unlocked);
|
||||
}
|
||||
}
|
||||
// @computed
|
||||
// @override
|
||||
// ZanoBalance get balance {
|
||||
// final zanoWallet = _wallet as ZanoWallet;
|
||||
// final balance = zanoWallet.balance;
|
||||
// return ZanoBalance(fullBalance: balance[CryptoCurrency.zano]!.total, unlockedBalance: balance[CryptoCurrency.zano]!.unlocked);
|
||||
// }
|
||||
}*/
|
||||
|
||||
class CWZano extends Zano {
|
||||
/**@override
|
||||
|
@ -88,7 +88,7 @@ class CWZano extends Zano {
|
|||
Future<CryptoCurrency> addZanoAssetById(WalletBase wallet, String assetId) async => await (wallet as ZanoWallet).addZanoAssetById(assetId);
|
||||
|
||||
@override
|
||||
Future<void> addZanoAsset(WalletBase wallet, CryptoCurrency token) async => await (wallet as ZanoWallet).addRemoveZanoAsset(token as ZanoAsset);
|
||||
Future<void> changeZanoAssetAvailability(WalletBase wallet, CryptoCurrency token) async => await (wallet as ZanoWallet).changeZanoAssetAvailability(token as ZanoAsset);
|
||||
|
||||
@override
|
||||
Future<void> deleteZanoAsset(WalletBase wallet, CryptoCurrency token) async => await (wallet as ZanoWallet).deleteZanoAsset(token as ZanoAsset);
|
||||
|
@ -105,10 +105,10 @@ class CWZano extends Zano {
|
|||
return zanoWallet.transactionHistory;
|
||||
}
|
||||
|
||||
@override
|
||||
ZanoWalletDetails getZanoWalletDetails(Object wallet) {
|
||||
return CWZanoWalletDetails(wallet);
|
||||
}
|
||||
// @override
|
||||
// ZanoWalletDetails getZanoWalletDetails(Object wallet) {
|
||||
// return CWZanoWalletDetails(wallet);
|
||||
// }
|
||||
|
||||
@override
|
||||
TransactionPriority getDefaultTransactionPriority() {
|
||||
|
@ -186,10 +186,10 @@ class CWZano extends Zano {
|
|||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String formatterMoneroAmountToString({required int amount}) {
|
||||
return moneroAmountToString(amount: amount);
|
||||
}
|
||||
// @override
|
||||
// String formatterMoneroAmountToString({required int amount}) {
|
||||
// return moneroAmountToString(amount: amount);
|
||||
// }
|
||||
|
||||
@override
|
||||
double formatterMoneroAmountToDouble({required int amount}) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:cake_wallet/utils/language_list.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_zano/zano_asset.dart';
|
||||
import 'package:cw_zano/zano_transaction_credentials.dart';
|
||||
import 'package:cw_zano/model/zano_asset.dart';
|
||||
import 'package:cw_zano/model/zano_transaction_credentials.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:cw_core/wallet_credentials.dart';
|
||||
|
@ -19,7 +19,7 @@ import 'package:cw_core/monero_amount_format.dart';
|
|||
import 'package:cw_core/monero_transaction_priority.dart';
|
||||
import 'package:cw_zano/zano_wallet_service.dart';
|
||||
import 'package:cw_zano/zano_wallet.dart';
|
||||
import 'package:cw_zano/zano_transaction_info.dart';
|
||||
import 'package:cw_zano/model/zano_transaction_info.dart';
|
||||
import 'package:cw_zano/mnemonics/english.dart';
|
||||
|
||||
part 'cw_zano.dart';
|
||||
|
@ -42,7 +42,7 @@ Zano? zano = CWZano();
|
|||
// final String address;
|
||||
// }
|
||||
|
||||
class ZanoBalance extends Balance {
|
||||
/*class ZanoBalance extends Balance {
|
||||
ZanoBalance({required this.fullBalance, required this.unlockedBalance})
|
||||
: formattedFullBalance = zano!.formatterMoneroAmountToString(amount: fullBalance),
|
||||
formattedUnlockedBalance =
|
||||
|
@ -67,24 +67,24 @@ class ZanoBalance extends Balance {
|
|||
|
||||
@override
|
||||
String get formattedAdditionalBalance => formattedFullBalance;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
abstract class ZanoWalletDetails {
|
||||
/*abstract class ZanoWalletDetails {
|
||||
// FIX-ME: it's abstruct class
|
||||
// @observable
|
||||
// late Account account;
|
||||
// FIX-ME: it's abstruct class
|
||||
@observable
|
||||
late ZanoBalance balance;
|
||||
}
|
||||
}*/
|
||||
|
||||
abstract class Zano {
|
||||
/**ZanoAccountList getAccountList(Object wallet);*/
|
||||
|
||||
TransactionHistoryBase getTransactionHistory(Object wallet);
|
||||
|
||||
ZanoWalletDetails getZanoWalletDetails(Object wallet);
|
||||
//ZanoWalletDetails getZanoWalletDetails(Object wallet);
|
||||
|
||||
// String getTransactionAddress(Object wallet, int accountIndex, int addressIndex);
|
||||
|
||||
|
@ -105,7 +105,7 @@ abstract class Zano {
|
|||
WalletCredentials createZanoNewWalletCredentials({required String name, String password});
|
||||
Map<String, String> getKeys(Object wallet);
|
||||
Object createZanoTransactionCredentials({required List<Output> outputs, required TransactionPriority priority, required CryptoCurrency currency});
|
||||
String formatterMoneroAmountToString({required int amount});
|
||||
// String formatterMoneroAmountToString({required int amount});
|
||||
double formatterMoneroAmountToDouble({required int amount});
|
||||
int formatterMoneroParseAmount({required String amount});
|
||||
// Account getCurrentAccount(Object wallet);
|
||||
|
@ -116,7 +116,7 @@ abstract class Zano {
|
|||
CryptoCurrency assetOfTransaction(WalletBase wallet, TransactionInfo tx);
|
||||
List<ZanoAsset> getZanoAssets(WalletBase wallet);
|
||||
String getZanoAssetAddress(CryptoCurrency asset);
|
||||
Future<void> addZanoAsset(WalletBase wallet, CryptoCurrency token);
|
||||
Future<void> changeZanoAssetAvailability(WalletBase wallet, CryptoCurrency token);
|
||||
Future<CryptoCurrency> addZanoAssetById(WalletBase wallet, String assetId);
|
||||
Future<void> deleteZanoAsset(WalletBase wallet, CryptoCurrency token);
|
||||
Future<CryptoCurrency?> getZanoAsset(WalletBase wallet, String contractAddress);
|
||||
|
|
Loading…
Reference in a new issue