transfers in different assets

This commit is contained in:
leo 2024-03-16 10:55:03 +00:00
parent b2b6578972
commit c74a114209
20 changed files with 211 additions and 186 deletions

View file

@ -2,7 +2,6 @@ import 'package:decimal/decimal.dart';
import 'package:decimal/intl.dart';
import 'package:intl/intl.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:rational/rational.dart';
class AmountConverter {
static const _moneroAmountLength = 12;

View file

@ -1,38 +0,0 @@
// class AssetDescriptor {
// static const defaultDecimalPoint = 12;
// final String assetId;
// final int currentSupply;
// final int decimalPoint;
// final String fullName;
// final bool hiddenSupply;
// final String metaInfo;
// final String owner;
// final String ticker;
// final int totalMaxSupply;
// AssetDescriptor({
// required this.assetId,
// required this.currentSupply,
// required this.decimalPoint,
// required this.fullName,
// required this.hiddenSupply,
// required this.metaInfo,
// required this.owner,
// required this.ticker,
// required this.totalMaxSupply,
// });
// factory AssetDescriptor.fromJson(Map<String, dynamic> json) =>
// AssetDescriptor(
// assetId: json['asset_id'] as String? ?? '',
// currentSupply: json['current_supply'] as int? ?? 0,
// decimalPoint: json['decimal_point'] as int? ?? defaultDecimalPoint,
// fullName: json['full_name'] as String? ?? '',
// hiddenSupply: json['hidden_supply'] as bool? ?? false,
// metaInfo: json['meta_info'] as String? ?? '',
// owner: json['owner'] as String? ?? '',
// ticker: json['ticker'] as String? ?? '',
// totalMaxSupply: json['total_max_supply'] as int? ?? 0,
// );
// }

View file

@ -1,5 +1,5 @@
class Destination {
final int amount; // transfered as string
final BigInt amount; // transfered as string
final String address;
final String assetId;
@ -7,7 +7,7 @@ class Destination {
{required this.amount, required this.address, required this.assetId});
factory Destination.fromJson(Map<String, dynamic> json) => Destination(
amount: int.parse(json['amount'] as String? ?? '0'),
amount: BigInt.parse(json['amount'] as String? ?? '0'),
address: json['address'] as String? ?? '',
assetId: json['asset_id'] as String? ?? '',
);

View file

@ -1,7 +1,7 @@
import 'package:cw_zano/api/model/history.dart';
import 'package:cw_zano/api/model/transfer.dart';
class RecentHistory {
final List<History>? history;
final List<Transfer>? history;
final int lastItemIndex;
final int totalHistoryItems;
@ -12,7 +12,7 @@ class RecentHistory {
factory RecentHistory.fromJson(Map<String, dynamic> json) => RecentHistory(
history: json['history'] == null ? null : (json['history'] as List<dynamic>)
.map((e) => History.fromJson(e as Map<String, dynamic>))
.map((e) => Transfer.fromJson(e as Map<String, dynamic>))
.toList(),
lastItemIndex: json['last_item_index'] as int? ?? 0,
totalHistoryItems: json['total_history_items'] as int? ?? 0,

View file

@ -1,7 +1,7 @@
import 'package:cw_zano/api/model/employed_entries.dart';
import 'package:cw_zano/api/model/subtransfer.dart';
class History {
class Transfer {
final String comment;
final EmployedEntries employedEntries;
final int fee;
@ -21,7 +21,7 @@ class History {
final int txType;
final int unlockTime;
History({
Transfer({
required this.comment,
required this.employedEntries,
required this.fee,
@ -42,7 +42,7 @@ class History {
required this.unlockTime,
});
factory History.fromJson(Map<String, dynamic> json) => History(
factory Transfer.fromJson(Map<String, dynamic> json) => Transfer(
comment: json['comment'] as String? ?? '',
employedEntries: EmployedEntries.fromJson(
json['employed_entries'] as Map<String, dynamic>? ?? {}),

View file

@ -2,7 +2,7 @@ import 'package:cw_zano/api/model/destination.dart';
class TransferParams {
final List<Destination> destinations;
final int fee;
final BigInt fee;
final int mixin;
final String paymentId;
final String comment;
@ -31,7 +31,7 @@ class TransferParams {
factory TransferParams.fromJson(Map<String, dynamic> json) => TransferParams(
destinations: (json['destinations'] as List<dynamic>?)?.map((e) => Destination.fromJson(e as Map<String, dynamic>)).toList() ?? [],
fee: json['fee'] as int? ?? 0,
fee: BigInt.from(json['fee'] as int? ?? 0),
mixin: json['mixin'] as int? ?? 0,
paymentId: json['payment_id'] as String? ?? '',
comment: json['comment'] as String? ?? '',

View file

@ -1,13 +1,11 @@
import 'dart:convert';
import 'package:cw_core/pending_transaction.dart';
import 'package:cw_zano/api/exceptions/transfer_exception.dart';
import 'package:cw_zano/api/model/destination.dart';
import 'package:cw_zano/api/model/history.dart';
import 'package:cw_zano/api/model/transfer_params.dart';
import 'package:cw_zano/api/model/transfer_result.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/amount_converter.dart';
import 'package:cw_core/pending_transaction.dart';
import 'package:cw_zano/zano_formatter.dart';
import 'package:cw_zano/zano_wallet.dart';
class PendingZanoTransaction with PendingTransaction {
@ -16,12 +14,20 @@ class PendingZanoTransaction with PendingTransaction {
required this.destinations,
required this.fee,
required this.comment,
required this.assetId,
required this.ticker,
this.decimalPoint = 12,
required this.amount,
});
final ZanoWalletBase zanoWallet;
final List<Destination> destinations;
final int fee;
final BigInt fee;
final String comment;
final String assetId;
final String ticker;
final int decimalPoint;
final BigInt amount;
@override
String get id => transferResult?.txHash ?? '';
@ -30,10 +36,10 @@ class PendingZanoTransaction with PendingTransaction {
String get hex => '';
@override
String get amountFormatted => AmountConverter.amountIntToString(CryptoCurrency.zano, destinations.first.amount);
String get amountFormatted => '${ZanoFormatter.bigIntAmountToString(amount, decimalPoint)} $ticker';
@override
String get feeFormatted => AmountConverter.amountIntToString(CryptoCurrency.zano, fee);
String get feeFormatted => '${ZanoFormatter.bigIntAmountToString(fee)} ZANO';
TransferResult? transferResult;
@ -66,4 +72,6 @@ class PendingZanoTransaction with PendingTransaction {
}
}
}
}

View file

@ -1,5 +1,6 @@
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/hive_type_ids.dart';
import 'package:cw_zano/zano_formatter.dart';
import 'package:hive/hive.dart';
part 'zano_asset.g.dart';
@ -39,7 +40,7 @@ class ZanoAsset extends CryptoCurrency with HiveObjectMixin {
this.fullName = '',
this.ticker = '',
required this.assetId,
this.decimalPoint = defaultDecimalPoint,
this.decimalPoint = ZanoFormatter.defaultDecimalPoint,
bool enabled = true,
this.iconPath,
this.tag,
@ -83,7 +84,7 @@ class ZanoAsset extends CryptoCurrency with HiveObjectMixin {
factory ZanoAsset.fromJson(Map<String, dynamic> json) => ZanoAsset(
assetId: json['asset_id'] as String? ?? '',
currentSupply: json['current_supply'] as int? ?? 0,
decimalPoint: json['decimal_point'] as int? ?? defaultDecimalPoint,
decimalPoint: json['decimal_point'] as int? ?? ZanoFormatter.defaultDecimalPoint,
fullName: json['full_name'] as String? ?? '',
hiddenSupply: json['hidden_supply'] as bool? ?? false,
metaInfo: json['meta_info'] as String? ?? '',
@ -92,11 +93,7 @@ class ZanoAsset extends CryptoCurrency with HiveObjectMixin {
totalMaxSupply: json['total_max_supply'] as int? ?? 0,
);
@override
String toString() => '$ticker (${assetId.substring(0, 4)}...${assetId.substring(assetId.length - 4)})';
static const typeId = ZANO_ASSET_TYPE_ID;
static const zanoAssetsBoxName = 'zanoAssetsBox';
static const defaultDecimalPoint = 12;
static const defaultOwner = '0000000000000000000000000000000000000000000000000000000000000000';
}

View file

@ -0,0 +1,24 @@
import 'dart:math';
import 'package:decimal/decimal.dart';
import 'package:decimal/intl.dart';
import 'package:intl/intl.dart';
class ZanoFormatter {
static const defaultDecimalPoint = 12;
//static const _moneroAmountLength = 12;
static final numberFormat = NumberFormat()
..maximumFractionDigits = defaultDecimalPoint
..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 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))),
),);
}

View file

@ -1,10 +1,12 @@
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/monero_transaction_priority.dart';
import 'package:cw_core/output_info.dart';
class ZanoTransactionCredentials {
ZanoTransactionCredentials({required this.outputs, required this.priority, required this.assetType});
ZanoTransactionCredentials({required this.outputs, required this.priority, required this.currency});
final List<OutputInfo> outputs;
final MoneroTransactionPriority priority;
final String assetType;
final CryptoCurrency currency;
//final String assetType;
}

View file

@ -2,35 +2,37 @@ import 'package:cw_core/format_amount.dart';
import 'package:cw_core/monero_amount_format.dart';
import 'package:cw_core/transaction_direction.dart';
import 'package:cw_core/transaction_info.dart';
import 'package:cw_zano/api/model/history.dart';
import 'package:cw_zano/api/model/transfer.dart';
class ZanoTransactionInfo extends TransactionInfo {
ZanoTransactionInfo(
this.id,
this.height,
this.direction,
this.date,
this.isPending,
this.amount,
this.accountIndex,
this.addressIndex,
this.fee,
this.confirmations);
ZanoTransactionInfo({
required this.id,
required this.height,
required this.direction,
required this.date,
required this.isPending,
required this.amount,
required this.accountIndex,
required this.addressIndex,
required this.fee,
required this.assetId,
required this.confirmations,
required this.tokenSymbol,
});
ZanoTransactionInfo.fromHistory(History history)
: id = history.txHash,
height = history.height,
direction = history.subtransfers.first.isIncome ? TransactionDirection.incoming :
TransactionDirection.outgoing,
date = DateTime.fromMillisecondsSinceEpoch(history.timestamp * 1000),
ZanoTransactionInfo.fromTransfer(Transfer transfer, this.tokenSymbol)
: id = transfer.txHash,
height = transfer.height,
direction = transfer.subtransfers.first.isIncome ? TransactionDirection.incoming : TransactionDirection.outgoing,
date = DateTime.fromMillisecondsSinceEpoch(transfer.timestamp * 1000),
isPending = false,
amount = history.subtransfers.first.amount,
amount = transfer.subtransfers.first.amount,
accountIndex = 0,
addressIndex = 0,
fee = history.fee,
fee = transfer.fee,
confirmations = 1,
assetType = 'ZANO', // TODO: FIXIT:
recipientAddress = history.remoteAddresses.isNotEmpty ? history.remoteAddresses.first : '';
assetId = transfer.subtransfers.first.assetId,
recipientAddress = transfer.remoteAddresses.isNotEmpty ? transfer.remoteAddresses.first : '';
final String id;
final int height;
@ -43,13 +45,13 @@ class ZanoTransactionInfo extends TransactionInfo {
final int addressIndex;
final int confirmations;
late String recipientAddress;
late String assetType;
final String tokenSymbol;
late String assetId;
String? _fiatAmount;
String? key;
@override
String amountFormatted() =>
'${formatAmount(moneroAmountToString(amount: amount))} $assetType';
String amountFormatted() => '${formatAmount(moneroAmountToString(amount: amount))} $tokenSymbol';
@override
String fiatAmount() => _fiatAmount ?? '';
@ -58,6 +60,7 @@ class ZanoTransactionInfo extends TransactionInfo {
void changeFiatAmount(String amount) => _fiatAmount = formatAmount(amount);
@override
String feeFormatted() =>
'${formatAmount(moneroAmountToString(amount: fee))} $assetType';
String feeFormatted() => '${formatAmount(moneroAmountToString(amount: fee))} $feeCurrency';
String get feeCurrency => 'ZANO';
}

View file

@ -15,12 +15,13 @@ import 'package:cw_core/wallet_info.dart';
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/history.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/zano_formatter.dart';
import 'package:cw_zano/zano_transaction_credentials.dart';
import 'package:cw_zano/zano_transaction_history.dart';
import 'package:cw_zano/zano_transaction_info.dart';
@ -41,7 +42,7 @@ class ZanoWallet = ZanoWalletBase with _$ZanoWallet;
abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHistory, ZanoTransactionInfo> with Store, ZanoWalletApi {
static const int _autoSaveInterval = 30;
List<History> history = [];
List<Transfer> transfers = [];
//String defaultAsssetId = '';
@override
ZanoWalletAddresses walletAddresses;
@ -60,6 +61,7 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
@override
ZanoWalletKeys keys = ZanoWalletKeys(privateSpendKey: '', privateViewKey: '', publicSpendKey: '', publicViewKey: '');
static const String zanoAssetId = 'd6329b5b1f7c0805b5c345f4957554002a2f557845f64d7645dae0e051a6498a';
late final Box<ZanoAsset> zanoAssetsBox;
List<ZanoAsset> get zanoAssets => zanoAssetsBox.values.toList();
@ -128,45 +130,64 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
@override
Future<PendingTransaction> createTransaction(Object credentials) async {
final creds = credentials as ZanoTransactionCredentials;
final outputs = creds.outputs;
credentials as ZanoTransactionCredentials;
bool isZano() => credentials.currency == CryptoCurrency.zano;
final outputs = credentials.outputs;
final hasMultiDestination = outputs.length > 1;
final unlockedBalance = balance[CryptoCurrency.zano]?.unlocked ?? 0;
final fee = calculateEstimatedFee(creds.priority);
final unlockedBalanceZano = BigInt.from(balance[CryptoCurrency.zano]?.unlocked ?? 0);
final unlockedBalanceCurrency = BigInt.from(balance[credentials.currency]?.unlocked ?? 0);
final fee = BigInt.from(calculateEstimatedFee(credentials.priority));
late BigInt totalAmount;
void checkForEnoughBalances() {
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).");
}
} else {
if (fee > unlockedBalanceZano) {
throw ZanoTransactionCreationException(
"You don't have enough coins (required: ${ZanoFormatter.bigIntAmountToString(fee)} ZANO, unlocked ${ZanoFormatter.bigIntAmountToString(unlockedBalanceZano)} ZANO).");
}
if (totalAmount > unlockedBalanceCurrency) {
throw ZanoTransactionCreationException(
"You don't have enough coins (required: ${ZanoFormatter.bigIntAmountToString(totalAmount)} ${credentials.currency.title}, unlocked ${ZanoFormatter.bigIntAmountToString(unlockedBalanceZano)} ${credentials.currency.title}).");
}
}
}
final assetId = isZano() ? zanoAssetId : (currency as ZanoAsset).assetId;
late List<Destination> destinations;
if (hasMultiDestination) {
if (outputs.any((output) => output.sendAll || (output.formattedCryptoAmount ?? 0) <= 0)) {
throw ZanoTransactionCreationException("You don't have enough coins.");
}
final int totalAmount = outputs.fold(0, (acc, value) => acc + (value.formattedCryptoAmount ?? 0));
if (totalAmount + fee > unlockedBalance) {
throw ZanoTransactionCreationException(
"You don't have enough coins (required: ${moneroAmountToString(amount: totalAmount + fee)}, unlocked ${moneroAmountToString(amount: unlockedBalance)}).");
}
totalAmount = outputs.fold(BigInt.zero, (acc, value) => acc + BigInt.from(value.formattedCryptoAmount ?? 0));
checkForEnoughBalances();
destinations = outputs
.map((output) => Destination(
amount: output.formattedCryptoAmount ?? 0,
amount: BigInt.from(output.formattedCryptoAmount ?? 0),
address: output.isParsedAddress ? output.extractedAddress! : output.address,
assetId: "defaultAsssetId",
assetId: assetId,
))
.toList();
} else {
final output = outputs.first;
late int amount;
if (output.sendAll) {
amount = unlockedBalance - fee;
if (isZano()) {
totalAmount = unlockedBalanceZano - fee;
} else {
amount = output.formattedCryptoAmount!;
totalAmount = unlockedBalanceCurrency;
}
if (amount + fee > unlockedBalance) {
throw ZanoTransactionCreationException(
"You don't have enough coins (required: ${moneroAmountToString(amount: amount + fee)}, unlocked ${moneroAmountToString(amount: unlockedBalance)}).");
} else {
totalAmount = BigInt.from(output.formattedCryptoAmount!);
}
checkForEnoughBalances();
destinations = [
Destination(
amount: amount,
amount: totalAmount,
address: output.isParsedAddress ? output.extractedAddress! : output.address,
assetId: "defaultAsssetId",
assetId: assetId,
)
];
}
@ -178,18 +199,27 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
destinations: destinations,
fee: fee,
comment: outputs.first.note ?? '',
assetId: assetId,
ticker: credentials.currency.title,
amount: totalAmount,
);
}
@override
Future<Map<String, ZanoTransactionInfo>> fetchTransactions() async {
try {
await _refreshTransactions();
return history.map<ZanoTransactionInfo>((history) => ZanoTransactionInfo.fromHistory(history)).fold<Map<String, ZanoTransactionInfo>>(
<String, ZanoTransactionInfo>{},
(Map<String, ZanoTransactionInfo> acc, ZanoTransactionInfo tx) {
acc[tx.id] = tx;
return acc;
transfers = await getRecentTxsAndInfo();
return Map.fromIterable(
transfers,
key: (item) => (item as Transfer).txHash,
value: (item) {
item as Transfer;
if (item.subtransfers.first.assetId == zanoAssetId) {
return ZanoTransactionInfo.fromTransfer(item, 'ZANO');
} else {
final tokenSymbol = zanoAssets.firstWhere((element) => element.assetId == item.subtransfers.first.assetId).ticker;
return ZanoTransactionInfo.fromTransfer(item, tokenSymbol);
}
},
);
} catch (e) {
@ -286,7 +316,7 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
_cachedBlockchainHeight = 0;
_lastKnownBlockHeight = 0;
_initialSyncHeight = 0;
_updateSyncInfoTimer ??= Timer.periodic(Duration(milliseconds: /*1200*/5000), (_) async {
_updateSyncInfoTimer ??= Timer.periodic(Duration(milliseconds: /*1200*/ 5000), (_) async {
/*if (isNewTransactionExist()) {
onNewTransaction?.call();
}*/
@ -468,14 +498,6 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
}
}
Future<void> _refreshTransactions() async {
try {
history = await getRecentTxsAndInfo();
} catch (e) {
print(e.toString());
}
}
void _updateSyncProgress(GetWalletStatusResult walletStatus) {
final syncHeight = walletStatus.currentWalletHeight;
if (_initialSyncHeight <= 0) {

View file

@ -3,12 +3,12 @@ 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_descriptor.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/history.dart';
import 'package:cw_zano/api/model/transfer.dart';
import 'package:cw_zano/zano_asset.dart';
import 'package:flutter/foundation.dart';
import 'api/model/store_result.dart';
@ -150,9 +150,10 @@ mixin ZanoWalletApi {
}
}
Future<List<History>> getRecentTxsAndInfo() async {
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');
final map = jsonDecode(json) as Map<String, dynamic>?;
_checkForErrors(map);
final transfers = map?['result']?['result']?['transfers'] as List<dynamic>?;
@ -160,7 +161,7 @@ mixin ZanoWalletApi {
print('get_recent_txs_and_info empty transfers');
return [];
}
return transfers.map((e) => History.fromJson(e as Map<String, dynamic>)).toList();
return transfers.map((e) => Transfer.fromJson(e as Map<String, dynamic>)).toList();
} catch (e) {
print(e);
return [];

View file

@ -10,7 +10,6 @@ import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_service.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:cw_zano/api/api_calls.dart' as calls;
import 'package:cw_zano/api/api_calls.dart';
import 'package:cw_zano/api/consts.dart';
import 'package:cw_zano/api/exceptions/already_exists_exception.dart';
@ -21,6 +20,7 @@ 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/zano_wallet.dart';
import 'package:flutter/foundation.dart';
import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
@ -71,8 +71,8 @@ class ZanoWalletService extends WalletService<ZanoNewWalletCredentials, ZanoRest
final wallet = ZanoWallet(credentials.walletInfo!);
await wallet.connectToNode(node: Node());
final path = await pathForWallet(name: credentials.name, type: getType());
final result = ApiCalls.createWallet(language: '', path: path, password: credentials.password!);
final map = json.decode(result) as Map<String, dynamic>;
final json = ApiCalls.createWallet(language: '', path: path, password: credentials.password!);
final map = jsonDecode(json) as Map<String, dynamic>;
_checkForCreateWalletError(map);
final createWalletResult = CreateWalletResult.fromJson(map['result'] as Map<String, dynamic>);
_parseCreateWalletResult(createWalletResult, wallet);
@ -111,9 +111,9 @@ class ZanoWalletService extends WalletService<ZanoNewWalletCredentials, ZanoRest
final walletInfo = walletInfoSource.values.firstWhereOrNull((info) => info.id == WalletBase.idFor(name, getType()))!;
final wallet = ZanoWallet(walletInfo);
await wallet.connectToNode(node: Node());
final result = wallet.loadWallet(path, password);
print('load wallet result $result');
final map = json.decode(result) as Map<String, dynamic>;
final json = wallet.loadWallet(path, password);
debugPrint('load wallet result $json');
final map = jsonDecode(json) as Map<String, dynamic>;
_checkForCreateWalletError(map);
final createWalletResult = CreateWalletResult.fromJson(map['result'] as Map<String, dynamic>);
_parseCreateWalletResult(createWalletResult, wallet);
@ -144,6 +144,7 @@ class ZanoWalletService extends WalletService<ZanoNewWalletCredentials, ZanoRest
wallet.walletAddresses.address = result.wi.address;
for (final item in result.wi.balances) {
if (item.assetInfo.ticker == 'ZANO') {
//wallet.zanoAssetId = item.assetInfo.assetId;
wallet.balance[CryptoCurrency.zano] = ZanoBalance(total: item.total, unlocked: item.unlocked);
} else {
for (final asset in wallet.balance.keys) {
@ -154,7 +155,7 @@ class ZanoWalletService extends WalletService<ZanoNewWalletCredentials, ZanoRest
}
}
if (result.recentHistory.history != null) {
wallet.history = result.recentHistory.history!;
wallet.transfers = result.recentHistory.history!;
}
}
@ -197,8 +198,8 @@ class ZanoWalletService extends WalletService<ZanoNewWalletCredentials, ZanoRest
final wallet = ZanoWallet(credentials.walletInfo!);
await wallet.connectToNode(node: Node());
final path = await pathForWallet(name: credentials.name, type: getType());
final result = ApiCalls.restoreWalletFromSeed(path: path, password: credentials.password!, seed: credentials.mnemonic);
final map = json.decode(result) as Map<String, dynamic>;
final json = ApiCalls.restoreWalletFromSeed(path: path, password: credentials.password!, seed: credentials.mnemonic);
final map = jsonDecode(json) as Map<String, dynamic>;
if (map['result'] != null) {
final createWalletResult = CreateWalletResult.fromJson(map['result'] as Map<String, dynamic>);
_parseCreateWalletResult(createWalletResult, wallet);

View file

@ -185,7 +185,7 @@ packages:
source: hosted
version: "2.2.4"
decimal:
dependency: transitive
dependency: "direct main"
description:
name: decimal
sha256: "24a261d5d5c87e86c7651c417a5dbdf8bcd7080dd592533910e8d0505a279f21"

View file

@ -18,6 +18,7 @@ dependencies:
mobx: ^2.0.7+4
flutter_mobx: ^2.0.6+1
intl: ^0.18.0
decimal: ^2.3.3
cw_core:
path: ../cw_core

View file

@ -116,7 +116,7 @@ class TransactionListItem extends ActionListItem with Keyable {
);
break;
case WalletType.zano:
final asset = zano!.assetOfTransaction(transaction);
final asset = zano!.assetOfTransaction(balanceViewModel.wallet, transaction);
final price = balanceViewModel.fiatConvertationStore.prices[asset];
amount = calculateFiatAmountRaw(
cryptoAmount: zano!.formatterMoneroAmountToDouble(amount: transaction.amount),

View file

@ -46,7 +46,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
void onWalletChange(wallet) {
currencies = wallet.balance.keys.toList();
selectedCryptoCurrency = wallet.currency;
hasMultipleTokens = isEVMCompatibleChain(wallet.type) || wallet.type == WalletType.solana;
hasMultipleTokens = isEVMCompatibleChain(wallet.type) || wallet.type == WalletType.solana || wallet.type == WalletType.zano;
}
SendViewModelBase(
@ -60,7 +60,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
currencies = appStore.wallet!.balance.keys.toList(),
selectedCryptoCurrency = appStore.wallet!.currency,
hasMultipleTokens = isEVMCompatibleChain(appStore.wallet!.type) ||
appStore.wallet!.type == WalletType.solana,
appStore.wallet!.type == WalletType.solana || appStore.wallet!.type == WalletType.zano,
outputs = ObservableList<Output>(),
_settingsStore = appStore.settingsStore,
fiatFromSettings = appStore.settingsStore.fiatCurrency,
@ -387,12 +387,8 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
return solana!
.createSolanaTransactionCredentials(outputs, currency: selectedCryptoCurrency);
case WalletType.zano:
final priority = _settingsStore.priority[wallet.type];
if (priority == null) {
throw Exception('Priority is null for wallet type: ${wallet.type}');
}
return zano!.createZanoTransactionCreationCredentials(
outputs: outputs, priority: priority, assetType: selectedCryptoCurrency.title);
return zano!.createZanoTransactionCredentials(
outputs: outputs, priority: priority!, currency: selectedCryptoCurrency);
default:
throw Exception('Unexpected wallet type: ${wallet.type}');
}

View file

@ -80,21 +80,18 @@ class CWZano extends Zano {
}*/
List<ZanoAsset> getZanoAssets(WalletBase wallet) {
final zanoWallet = wallet as ZanoWallet;
return zanoWallet.zanoAssets;
wallet as ZanoWallet;
return wallet.zanoAssets;
}
@override
Future<CryptoCurrency> addZanoAssetById(WalletBase wallet, String assetId) async =>
await (wallet as ZanoWallet).addZanoAssetById(assetId);
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> addZanoAsset(WalletBase wallet, CryptoCurrency token) async => await (wallet as ZanoWallet).addRemoveZanoAsset(token as ZanoAsset);
@override
Future<void> deleteZanoAsset(WalletBase wallet, CryptoCurrency token) async =>
await (wallet as ZanoWallet).deleteZanoAsset(token as ZanoAsset);
Future<void> deleteZanoAsset(WalletBase wallet, CryptoCurrency token) async => await (wallet as ZanoWallet).deleteZanoAsset(token as ZanoAsset);
@override
Future<ZanoAsset?> getZanoAsset(WalletBase wallet, String assetId) async {
@ -136,12 +133,20 @@ class CWZano extends Zano {
@override
WalletCredentials createZanoRestoreWalletFromKeysCredentials(
{required String name, required String spendKey, required String viewKey, required String address, required String password, required String language, required int height}) {
return ZanoRestoreWalletFromKeysCredentials(name: name, spendKey: spendKey, viewKey: viewKey, address: address, password: password, language: language, height: height);
{required String name,
required String spendKey,
required String viewKey,
required String address,
required String password,
required String language,
required int height}) {
return ZanoRestoreWalletFromKeysCredentials(
name: name, spendKey: spendKey, viewKey: viewKey, address: address, password: password, language: language, height: height);
}
@override
WalletCredentials createZanoRestoreWalletFromSeedCredentials({required String name, required String password, required int height, required String mnemonic}) {
WalletCredentials createZanoRestoreWalletFromSeedCredentials(
{required String name, required String password, required int height, required String mnemonic}) {
return ZanoRestoreWalletFromSeedCredentials(name: name, password: password, height: height, mnemonic: mnemonic);
}
@ -163,7 +168,7 @@ class CWZano extends Zano {
}
@override
Object createZanoTransactionCreationCredentials({required List<Output> outputs, required TransactionPriority priority, required String assetType}) {
Object createZanoTransactionCredentials({required List<Output> outputs, required TransactionPriority priority, required CryptoCurrency currency}) {
return ZanoTransactionCredentials(
outputs: outputs
.map((out) => OutputInfo(
@ -177,7 +182,8 @@ class CWZano extends Zano {
formattedCryptoAmount: out.formattedCryptoAmount))
.toList(),
priority: priority as MoneroTransactionPriority,
assetType: assetType);
currency: currency,
);
}
@override
@ -231,10 +237,13 @@ class CWZano extends Zano {
// }
@override
CryptoCurrency assetOfTransaction(TransactionInfo tx) {
final transaction = tx as ZanoTransactionInfo;
final asset = CryptoCurrency.fromString(transaction.assetType);
return asset;
CryptoCurrency assetOfTransaction(WalletBase wallet, TransactionInfo transaction) {
transaction as ZanoTransactionInfo;
if (transaction.tokenSymbol == CryptoCurrency.zano.title) {
return CryptoCurrency.zano;
}
wallet as ZanoWallet;
return wallet.zanoAssets.firstWhere((element) => element.ticker == transaction.tokenSymbol);
}
String getZanoAssetAddress(CryptoCurrency asset) => (asset as ZanoAsset).assetId;

View file

@ -104,7 +104,7 @@ abstract class Zano {
WalletCredentials createZanoRestoreWalletFromSeedCredentials({required String name, required String password, required int height, required String mnemonic});
WalletCredentials createZanoNewWalletCredentials({required String name, String password});
Map<String, String> getKeys(Object wallet);
Object createZanoTransactionCreationCredentials({required List<Output> outputs, required TransactionPriority priority, required String assetType});
Object createZanoTransactionCredentials({required List<Output> outputs, required TransactionPriority priority, required CryptoCurrency currency});
String formatterMoneroAmountToString({required int amount});
double formatterMoneroAmountToDouble({required int amount});
int formatterMoneroParseAmount({required String amount});
@ -113,7 +113,7 @@ abstract class Zano {
void onStartup();
int getTransactionInfoAccountId(TransactionInfo tx);
WalletService createZanoWalletService(Box<WalletInfo> walletInfoSource);
CryptoCurrency assetOfTransaction(TransactionInfo tx);
CryptoCurrency assetOfTransaction(WalletBase wallet, TransactionInfo tx);
List<ZanoAsset> getZanoAssets(WalletBase wallet);
String getZanoAssetAddress(CryptoCurrency asset);
Future<void> addZanoAsset(WalletBase wallet, CryptoCurrency token);