transfers for multiple destinations and send all, some refactoring

This commit is contained in:
leo1234 2024-03-18 20:15:54 +08:00
parent c74a114209
commit 5af75aa7ad
10 changed files with 43 additions and 81 deletions

View file

@ -1,6 +1,5 @@
import 'dart:ffi'; import 'dart:ffi';
import 'package:cw_zano/api/convert_utf8_to_string.dart';
import 'package:cw_zano/api/structs/utf8_box.dart'; import 'package:cw_zano/api/structs/utf8_box.dart';
import 'package:cw_zano/api/zano_api.dart'; import 'package:cw_zano/api/zano_api.dart';
import 'package:ffi/ffi.dart'; import 'package:ffi/ffi.dart';
@ -55,12 +54,18 @@ typedef _SetPassword = Pointer<Utf8> Function(int hWallet, Pointer<Utf8> passwor
typedef _stringFunction = Pointer<Utf8> Function(); typedef _stringFunction = Pointer<Utf8> Function();
class ApiCalls { class ApiCalls {
static String _convertUTF8ToString({required Pointer<Utf8> pointer}) {
final str = pointer.toDartString();
calloc.free(pointer);
return str;
}
static String _performApiCall( static String _performApiCall(
Pointer<Utf8> Function() apiCall, { Pointer<Utf8> Function() apiCall, {
List<Pointer<Utf8>>? pointersToFree, List<Pointer<Utf8>>? pointersToFree,
}) { }) {
try { try {
return convertUTF8ToString(pointer: apiCall()); return _convertUTF8ToString(pointer: apiCall());
} finally { } finally {
if (pointersToFree != null) { if (pointersToFree != null) {
for (var pointer in pointersToFree) { for (var pointer in pointersToFree) {

View file

@ -1,8 +0,0 @@
import 'dart:ffi';
import 'package:ffi/ffi.dart';
String convertUTF8ToString({required Pointer<Utf8> pointer}) {
final str = pointer.toDartString();
calloc.free(pointer);
return str;
}

View file

@ -1,34 +0,0 @@
// class AssetInfo {
// 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;
// AssetInfo(
// {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 AssetInfo.fromJson(Map<String, dynamic> json) => AssetInfo(
// assetId: json['asset_id'] as String? ?? '',
// currentSupply: json['current_supply'] as int? ?? 0,
// decimalPoint: json['decimal_point'] as int? ?? 0,
// fullName: json['full_name'] as String? ?? '',
// hiddenSupply: json['hidden_supply'] as bool,
// 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,6 +1,5 @@
import 'package:cw_core/amount_converter.dart'; import 'package:cw_core/amount_converter.dart';
import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/crypto_currency.dart';
import 'package:cw_zano/api/model/asset_info.dart';
import 'package:cw_zano/zano_asset.dart'; import 'package:cw_zano/zano_asset.dart';
class Balance { class Balance {

View file

@ -16,7 +16,7 @@ class PendingZanoTransaction with PendingTransaction {
required this.comment, required this.comment,
required this.assetId, required this.assetId,
required this.ticker, required this.ticker,
this.decimalPoint = 12, this.decimalPoint = ZanoFormatter.defaultDecimalPoint,
required this.amount, required this.amount,
}); });

View file

@ -1,20 +1,18 @@
import 'package:cw_core/amount_converter.dart';
import 'package:cw_core/balance.dart'; import 'package:cw_core/balance.dart';
import 'package:cw_core/crypto_currency.dart'; import 'package:cw_zano/zano_formatter.dart';
import 'package:cw_core/monero_amount_format.dart';
class ZanoBalance extends Balance { class ZanoBalance extends Balance {
final int total; final int total;
final int unlocked; final int unlocked;
ZanoBalance({required this.total, required this.unlocked}): super(unlocked, total-unlocked); final int decimalPoint;
ZanoBalance({required this.total, required this.unlocked, required this.decimalPoint}) : super(unlocked, total - unlocked);
@override @override
String get formattedAdditionalBalance => AmountConverter.amountIntToString(CryptoCurrency.zano, total-unlocked); String get formattedAdditionalBalance => ZanoFormatter.intAmountToString(total - unlocked, decimalPoint);
@override @override
String get formattedAvailableBalance => AmountConverter.amountIntToString(CryptoCurrency.zano, unlocked); String get formattedAvailableBalance => ZanoFormatter.intAmountToString(unlocked, decimalPoint);
@override
String get formattedFrozenBalance => '';
// @override
// String get formattedFrozenBalance => '';
} }

View file

@ -7,7 +7,6 @@ import 'package:intl/intl.dart';
class ZanoFormatter { class ZanoFormatter {
static const defaultDecimalPoint = 12; static const defaultDecimalPoint = 12;
//static const _moneroAmountLength = 12;
static final numberFormat = NumberFormat() static final numberFormat = NumberFormat()
..maximumFractionDigits = defaultDecimalPoint ..maximumFractionDigits = defaultDecimalPoint
..minimumFractionDigits = 1; ..minimumFractionDigits = 1;

View file

@ -1,8 +1,8 @@
import 'package:cw_core/format_amount.dart'; 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_direction.dart';
import 'package:cw_core/transaction_info.dart'; import 'package:cw_core/transaction_info.dart';
import 'package:cw_zano/api/model/transfer.dart'; import 'package:cw_zano/api/model/transfer.dart';
import 'package:cw_zano/zano_formatter.dart';
class ZanoTransactionInfo extends TransactionInfo { class ZanoTransactionInfo extends TransactionInfo {
ZanoTransactionInfo({ ZanoTransactionInfo({
@ -18,9 +18,10 @@ class ZanoTransactionInfo extends TransactionInfo {
required this.assetId, required this.assetId,
required this.confirmations, required this.confirmations,
required this.tokenSymbol, required this.tokenSymbol,
required this.decimalPoint,
}); });
ZanoTransactionInfo.fromTransfer(Transfer transfer, this.tokenSymbol) ZanoTransactionInfo.fromTransfer(Transfer transfer, this.tokenSymbol, this.decimalPoint)
: id = transfer.txHash, : id = transfer.txHash,
height = transfer.height, height = transfer.height,
direction = transfer.subtransfers.first.isIncome ? TransactionDirection.incoming : TransactionDirection.outgoing, direction = transfer.subtransfers.first.isIncome ? TransactionDirection.incoming : TransactionDirection.outgoing,
@ -44,6 +45,7 @@ class ZanoTransactionInfo extends TransactionInfo {
final int fee; final int fee;
final int addressIndex; final int addressIndex;
final int confirmations; final int confirmations;
final int decimalPoint;
late String recipientAddress; late String recipientAddress;
final String tokenSymbol; final String tokenSymbol;
late String assetId; late String assetId;
@ -51,7 +53,7 @@ class ZanoTransactionInfo extends TransactionInfo {
String? key; String? key;
@override @override
String amountFormatted() => '${formatAmount(moneroAmountToString(amount: amount))} $tokenSymbol'; String amountFormatted() => '${formatAmount(ZanoFormatter.intAmountToString(amount, decimalPoint))} $tokenSymbol';
@override @override
String fiatAmount() => _fiatAmount ?? ''; String fiatAmount() => _fiatAmount ?? '';
@ -60,7 +62,7 @@ class ZanoTransactionInfo extends TransactionInfo {
void changeFiatAmount(String amount) => _fiatAmount = formatAmount(amount); void changeFiatAmount(String amount) => _fiatAmount = formatAmount(amount);
@override @override
String feeFormatted() => '${formatAmount(moneroAmountToString(amount: fee))} $feeCurrency'; String feeFormatted() => '${formatAmount(ZanoFormatter.intAmountToString(fee))} $feeCurrency';
String get feeCurrency => 'ZANO'; String get feeCurrency => 'ZANO';
} }

View file

@ -3,7 +3,6 @@ import 'dart:io';
import 'package:cw_core/cake_hive.dart'; import 'package:cw_core/cake_hive.dart';
import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/monero_amount_format.dart';
import 'package:cw_core/monero_wallet_utils.dart'; import 'package:cw_core/monero_wallet_utils.dart';
import 'package:cw_core/node.dart'; import 'package:cw_core/node.dart';
import 'package:cw_core/pathForWallet.dart'; import 'package:cw_core/pathForWallet.dart';
@ -77,7 +76,7 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
Timer? _autoSaveTimer; Timer? _autoSaveTimer;
ZanoWalletBase(WalletInfo walletInfo) ZanoWalletBase(WalletInfo walletInfo)
: balance = ObservableMap.of({CryptoCurrency.zano: ZanoBalance(total: 0, unlocked: 0)}), : balance = ObservableMap.of({CryptoCurrency.zano: ZanoBalance(total: 0, unlocked: 0, decimalPoint: ZanoFormatter.defaultDecimalPoint)}),
_isTransactionUpdating = false, _isTransactionUpdating = false,
_hasSyncAfterStartup = false, _hasSyncAfterStartup = false,
walletAddresses = ZanoWalletAddresses(walletInfo), walletAddresses = ZanoWalletAddresses(walletInfo),
@ -215,10 +214,10 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
value: (item) { value: (item) {
item as Transfer; item as Transfer;
if (item.subtransfers.first.assetId == zanoAssetId) { if (item.subtransfers.first.assetId == zanoAssetId) {
return ZanoTransactionInfo.fromTransfer(item, 'ZANO'); return ZanoTransactionInfo.fromTransfer(item, 'ZANO', ZanoFormatter.defaultDecimalPoint);
} else { } else {
final tokenSymbol = zanoAssets.firstWhere((element) => element.assetId == item.subtransfers.first.assetId).ticker; final asset = zanoAssets.firstWhere((element) => element.assetId == item.subtransfers.first.assetId);
return ZanoTransactionInfo.fromTransfer(item, tokenSymbol); return ZanoTransactionInfo.fromTransfer(item, asset.ticker, asset.decimalPoint);
} }
}, },
); );
@ -229,12 +228,12 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
} }
Future<void> init(String address) async { Future<void> init(String address) async {
final boxName = "${walletInfo.name.replaceAll(" ", "_")}_${ZanoAsset.zanoAssetsBoxName}"; final boxName = '${walletInfo.name.replaceAll(' ', '_')}_${ZanoAsset.zanoAssetsBoxName}';
zanoAssetsBox = await CakeHive.openBox<ZanoAsset>(boxName); zanoAssetsBox = await CakeHive.openBox<ZanoAsset>(boxName);
print( print(
'assets in box total: ${zanoAssetsBox.length} ${zanoAssetsBox.values} active: ${zanoAssetsBox.values.where((element) => element.enabled).length} ${zanoAssetsBox.values.where((element) => element.enabled)}'); '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) { for (final asset in zanoAssetsBox.values) {
if (asset.enabled) balance[asset] = ZanoBalance(total: 0, unlocked: 0); if (asset.enabled) balance[asset] = ZanoBalance(total: 0, unlocked: 0, decimalPoint: asset.decimalPoint);
} }
await walletAddresses.init(); await walletAddresses.init();
await walletAddresses.updateAddress(address); await walletAddresses.updateAddress(address);
@ -336,11 +335,11 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
for (final item in walletInfo.wi.balances) { for (final item in walletInfo.wi.balances) {
if (item.assetInfo.ticker == 'ZANO') { if (item.assetInfo.ticker == 'ZANO') {
balance[CryptoCurrency.zano] = ZanoBalance(total: item.total, unlocked: item.unlocked); balance[CryptoCurrency.zano] = ZanoBalance(total: item.total, unlocked: item.unlocked, decimalPoint: ZanoFormatter.defaultDecimalPoint);
} else { } else {
for (final asset in balance.keys) { for (final asset in balance.keys) {
if (asset is ZanoAsset && asset.assetId == item.assetInfo.assetId) { if (asset is ZanoAsset && asset.assetId == item.assetInfo.assetId) {
balance[asset] = ZanoBalance(total: item.total, unlocked: item.unlocked); balance[asset] = ZanoBalance(total: item.total, unlocked: item.unlocked, decimalPoint: asset.decimalPoint);
} }
} }
} }
@ -410,7 +409,7 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
} catch (_) {} } catch (_) {}
final asset = ZanoAsset.copyWith(assetDescriptor, iconPath, 'ZANO', assetId: assetId, enabled: true); final asset = ZanoAsset.copyWith(assetDescriptor, iconPath, 'ZANO', assetId: assetId, enabled: true);
await zanoAssetsBox.put(asset.assetId, ZanoAsset.copyWith(asset, iconPath, 'ZANO')); await zanoAssetsBox.put(asset.assetId, ZanoAsset.copyWith(asset, iconPath, 'ZANO'));
balance[asset] = ZanoBalance(total: 0, unlocked: 0); balance[asset] = ZanoBalance(total: 0, unlocked: 0, decimalPoint: asset.decimalPoint);
return asset; return asset;
} }
@ -426,7 +425,7 @@ abstract class ZanoWalletBase extends WalletBase<ZanoBalance, ZanoTransactionHis
print('error adding zano asset'); print('error adding zano asset');
return; return;
} }
balance[asset] = ZanoBalance(total: 0, unlocked: 0); balance[asset] = ZanoBalance(total: 0, unlocked: 0, decimalPoint: asset.decimalPoint);
} else { } else {
final result = await removeAssetsWhitelist(asset.assetId); final result = await removeAssetsWhitelist(asset.assetId);
if (result == false) { if (result == false) {

View file

@ -19,6 +19,7 @@ import 'package:cw_zano/api/exceptions/wrong_seed_exception.dart';
import 'package:cw_zano/api/model/create_wallet_result.dart'; import 'package:cw_zano/api/model/create_wallet_result.dart';
import 'package:cw_zano/zano_asset.dart'; import 'package:cw_zano/zano_asset.dart';
import 'package:cw_zano/zano_balance.dart'; import 'package:cw_zano/zano_balance.dart';
import 'package:cw_zano/zano_formatter.dart';
import 'package:cw_zano/zano_wallet.dart'; import 'package:cw_zano/zano_wallet.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
@ -37,13 +38,7 @@ class ZanoRestoreWalletFromSeedCredentials extends WalletCredentials {
class ZanoRestoreWalletFromKeysCredentials extends WalletCredentials { class ZanoRestoreWalletFromKeysCredentials extends WalletCredentials {
ZanoRestoreWalletFromKeysCredentials( ZanoRestoreWalletFromKeysCredentials(
{required String name, {required String name, required String password, required this.language, required this.address, required this.viewKey, required this.spendKey, required int height})
required String password,
required this.language,
required this.address,
required this.viewKey,
required this.spendKey,
required int height})
: super(name: name, password: password, height: height); : super(name: name, password: password, height: height);
final String language; final String language;
@ -144,12 +139,19 @@ class ZanoWalletService extends WalletService<ZanoNewWalletCredentials, ZanoRest
wallet.walletAddresses.address = result.wi.address; wallet.walletAddresses.address = result.wi.address;
for (final item in result.wi.balances) { for (final item in result.wi.balances) {
if (item.assetInfo.ticker == 'ZANO') { if (item.assetInfo.ticker == 'ZANO') {
//wallet.zanoAssetId = item.assetInfo.assetId; wallet.balance[CryptoCurrency.zano] = ZanoBalance(
wallet.balance[CryptoCurrency.zano] = ZanoBalance(total: item.total, unlocked: item.unlocked); total: item.total,
unlocked: item.unlocked,
decimalPoint: ZanoFormatter.defaultDecimalPoint,
);
} else { } else {
for (final asset in wallet.balance.keys) { for (final asset in wallet.balance.keys) {
if (asset is ZanoAsset && asset.assetId == item.assetInfo.assetId) { if (asset is ZanoAsset && asset.assetId == item.assetInfo.assetId) {
wallet.balance[asset] = ZanoBalance(total: item.total, unlocked: item.unlocked); wallet.balance[asset] = ZanoBalance(
total: item.total,
unlocked: item.unlocked,
decimalPoint: asset.decimalPoint,
);
} }
} }
} }