dev
dart 138 lines 5.51 KB
Raw
1 import 'package:cw_core/amount/money.dart';
2 import 'package:cw_core/crypto_currency.dart';
3 import 'package:cw_core/utils/print_verbose.dart';
4 import 'package:cw_core/zano_asset.dart';
5 import 'package:cw_zano/api/model/employed_entries.dart';
6 import 'package:cw_zano/api/model/subtransfer.dart';
7 import 'package:collection/collection.dart';
8 import 'package:cw_zano/model/zano_transaction_info.dart';
9 import 'package:cw_zano/zano_wallet.dart';
10
11 class Transfer {
12 final String comment;
13 final EmployedEntries employedEntries;
14 final int fee;
15 final int height;
16 final bool isMining;
17 final bool isMixing;
18 final bool isService;
19 final String paymentId;
20 final List<String> remoteAddresses;
21 final List<String> remoteAliases;
22 final bool showSender;
23 final List<Subtransfer> subtransfers;
24 final int timestamp;
25 final int transferInternalIndex;
26 final int txBlobSize;
27 final String txHash;
28 final int txType;
29 final int unlockTime;
30
31 Transfer({
32 required this.comment,
33 required this.employedEntries,
34 required this.fee,
35 required this.height,
36 required this.isMining,
37 required this.isMixing,
38 required this.isService,
39 required this.paymentId,
40 required this.remoteAddresses,
41 required this.remoteAliases,
42 required this.showSender,
43 required this.subtransfers,
44 required this.timestamp,
45 required this.transferInternalIndex,
46 required this.txBlobSize,
47 required this.txHash,
48 required this.txType,
49 required this.unlockTime,
50 });
51
52 factory Transfer.fromJson(Map<String, dynamic> json) => Transfer(
53 comment: json['comment'] as String? ?? '',
54 employedEntries:
55 EmployedEntries.fromJson(json['employed_entries'] as Map<String, dynamic>? ?? {}),
56 fee: json['fee'] as int? ?? 0,
57 height: json['height'] as int? ?? 0,
58 isMining: json['is_mining'] as bool? ?? false,
59 isMixing: json['is_mixing'] as bool? ?? false,
60 isService: json['is_service'] as bool? ?? false,
61 paymentId: json['payment_id'] as String? ?? '',
62 remoteAddresses: json['remote_addresses'] == null
63 ? []
64 : (json['remote_addresses'] as List<dynamic>).cast<String>(),
65 remoteAliases: json['remote_aliases'] == null
66 ? []
67 : (json['remote_aliases'] as List<dynamic>).cast<String>(),
68 showSender: json['show_sender'] as bool? ?? false,
69 subtransfers: (json['subtransfers'] as List<dynamic>? ?? [])
70 .map((e) => Subtransfer.fromJson(e as Map<String, dynamic>))
71 .toList(),
72 timestamp: json['timestamp'] as int? ?? 0,
73 transferInternalIndex: json['transfer_internal_index'] == null
74 ? 0
75 : json['transfer_internal_index'] is double
76 ? (json['transfer_internal_index'] as double).toInt()
77 : json['transfer_internal_index'] as int,
78 txBlobSize: json['tx_blob_size'] as int? ?? 0,
79 txHash: json['tx_hash'] as String? ?? '',
80 txType: json['tx_type'] as int? ?? 0,
81 unlockTime: json['unlock_time'] as int? ?? 0,
82 );
83
84 static Map<String, ZanoTransactionInfo> makeMap(
85 List<Transfer> transfers, Map<String, ZanoAsset> zanoAssets, int currentDaemonHeight) {
86 return Map.fromIterable(
87 transfers,
88 key: (item) => (item as Transfer).txHash,
89 value: (transfer) {
90 transfer as Transfer;
91 // Simple (only one subtransfer OR two subtransfers and the second is Zano, outgoing and amount equals to fee) or complex?
92 Subtransfer? single = transfer.subtransfers.singleOrNull;
93 if (transfer.subtransfers.length == 2) {
94 final zano = transfer.subtransfers
95 .firstWhereOrNull((element) => element.assetId == ZanoWalletBase.zanoAssetId);
96 if (zano != null && !zano.isIncome && zano.amount == BigInt.from(transfer.fee)) {
97 single = transfer.subtransfers
98 .firstWhere((element) => element.assetId != ZanoWalletBase.zanoAssetId);
99 }
100 }
101 bool isSimple = single != null;
102 // TODO: for complex transactions we show zano or any other transaction, will fix it later
103 if (!isSimple) {
104 single = transfer.subtransfers
105 .firstWhereOrNull((element) => element.assetId == ZanoWalletBase.zanoAssetId) ??
106 transfer.subtransfers.first;
107 }
108 if (single.assetId != ZanoWalletBase.zanoAssetId) {
109 final asset = zanoAssets[single.assetId];
110 if (asset == null) {
111 printV('unknown asset ${single.assetId}');
112 }
113 final ticker = asset == null ? '***' : asset.ticker;
114 final decimalPoint = asset == null ? 0 : asset.decimalPoint;
115 return ZanoTransactionInfo.fromTransfer(
116 transfer,
117 confirmations: currentDaemonHeight - transfer.height,
118 isIncome: single.isIncome,
119 assetId: single.assetId,
120 amount: Money(single.amount,
121 asset ?? CryptoCurrency(title: ticker, name: ticker, decimals: decimalPoint)),
122 tokenSymbol: isSimple ? ticker : '*${ticker}',
123 decimalPoint: decimalPoint,
124 );
125 }
126 final amount = single.isIncome ? single.amount : single.amount - BigInt.from(transfer.fee);
127 return ZanoTransactionInfo.fromTransfer(
128 transfer,
129 confirmations: currentDaemonHeight - transfer.height,
130 isIncome: single.isIncome,
131 assetId: single.assetId,
132 amount: Money(amount, CryptoCurrency.zano),
133 tokenSymbol: isSimple ? 'ZANO' : '*ZANO',
134 );
135 },
136 );
137 }
138 }