Line data Source code
1 : library generic_transaction;
2 :
3 : import 'dart:convert';
4 : import 'dart:typed_data';
5 : import 'package:convert/convert.dart';
6 : import 'package:walletkit_dart/src/common/http_repository.dart';
7 : import 'package:walletkit_dart/src/crypto/utxo/entities/payments/p2h.dart';
8 : import 'package:walletkit_dart/src/crypto/utxo/utils/pubkey_to_address.dart';
9 : import 'package:walletkit_dart/walletkit_dart.dart';
10 :
11 : part '../../crypto/evm/entities/transactions/evm_transaction.dart';
12 : part '../../crypto/utxo/entities/transactions/utxo_transaction.dart';
13 : part '../../crypto/tron/entities/tron_transaction.dart';
14 :
15 : sealed class GenericTransaction implements Comparable<GenericTransaction> {
16 : final String hash;
17 : final int block;
18 : final int confirmations;
19 : final int timeMilli;
20 : final CoinEntity token;
21 : final Amount amount;
22 : final Amount? fee;
23 : final String sender;
24 : final String recipient;
25 : final TransactionTransferMethod transferMethod;
26 : final ConfirmationStatus status;
27 :
28 11 : const GenericTransaction({
29 : required this.hash,
30 : required this.block,
31 : required this.confirmations,
32 : required this.timeMilli,
33 : required this.amount,
34 : required this.fee,
35 : required this.sender,
36 : required this.recipient,
37 : required this.transferMethod,
38 : required this.token,
39 : required this.status,
40 : });
41 :
42 0 : EVMTransaction? get evmTx =>
43 0 : this is EVMTransaction ? this as EVMTransaction : null;
44 :
45 12 : BigInt get value => amount.value;
46 :
47 0 : BigInt get totalValue => value + (fee?.value ?? BigInt.zero);
48 :
49 2 : @override
50 4 : String toString() => "Transaction: $hash";
51 :
52 24 : bool get isPending => status == ConfirmationStatus.pending;
53 :
54 0 : bool get isConfirmed => status == ConfirmationStatus.confirmed;
55 :
56 0 : bool get isFailed => status == ConfirmationStatus.failed;
57 :
58 0 : DateTime get dateTime => DateTime.fromMillisecondsSinceEpoch(timeMilli);
59 :
60 7 : @override
61 : int compareTo(GenericTransaction other) {
62 7 : if (isPending) {
63 0 : if (other.isPending) return 0;
64 0 : return -1;
65 : }
66 7 : if (other.isPending) return 1;
67 28 : return -timeMilli.compareTo(other.timeMilli);
68 : }
69 :
70 8 : @override
71 64 : int get hashCode => hash.hashCode ^ token.hashCode ^ block.hashCode;
72 :
73 0 : @override
74 : bool operator ==(Object other) {
75 : if (identical(this, other)) return true;
76 :
77 0 : return other is GenericTransaction &&
78 0 : other.hash == hash &&
79 0 : other.token == token &&
80 0 : other.block == block;
81 : }
82 :
83 : Map<String, dynamic> toJson();
84 :
85 0 : factory GenericTransaction.fromJson(Map json) {
86 : return switch (json) {
87 : {
88 0 : 'hash': String _,
89 0 : 'block': int _,
90 0 : 'confirmations': int _,
91 0 : 'timeMilli': int _,
92 0 : 'amount': Map _,
93 0 : 'fee': Map? _,
94 0 : 'sender': String _,
95 0 : 'recipient': String _,
96 0 : 'transferMethod': int _,
97 0 : 'status': int _,
98 0 : 'token': Map _,
99 0 : 'input': String _,
100 0 : 'decodedInput': Map? _,
101 : } =>
102 0 : EVMTransaction.fromJson(json),
103 : {
104 0 : 'hash': String _,
105 0 : 'block': int _,
106 0 : 'confirmations': int _,
107 0 : 'timeMilli': int _,
108 0 : 'amount': Map _,
109 0 : 'fee': Map? _,
110 0 : 'sender': String _,
111 0 : 'recipient': String _,
112 0 : 'transferMethod': int _,
113 0 : 'status': int _,
114 0 : 'token': Map _,
115 0 : 'id': String _,
116 0 : 'version': int _,
117 0 : 'inputs': JsonList _,
118 0 : 'outputs': JsonList _,
119 : } =>
120 0 : UTXOTransaction.fromJson(json),
121 0 : _ => throw UnimplementedError("Unknown json: $json"),
122 : };
123 : }
124 : }
125 :
126 : enum ConfirmationStatus {
127 : notSubmitted("not_submitted"),
128 :
129 : /// Transaction is not confirmed yet
130 : pending("pending"),
131 :
132 : /// Transaction is confirmed
133 : confirmed("confirmed"),
134 :
135 : /// Transaction is failed
136 : failed("failed");
137 :
138 : /// TODO: When is a transaction failed?
139 9 : static ConfirmationStatus fromConfirmations(int? confirmations) {
140 : if (confirmations == null) return ConfirmationStatus.pending;
141 9 : if (confirmations <= 0) return ConfirmationStatus.pending;
142 :
143 : return ConfirmationStatus.confirmed;
144 : }
145 :
146 1 : static ConfirmationStatus fromReceiptStatus(int status) {
147 1 : if (status == 0) return ConfirmationStatus.failed;
148 1 : if (status == 1) return ConfirmationStatus.confirmed;
149 :
150 : return ConfirmationStatus.pending;
151 : }
152 :
153 0 : static ConfirmationStatus fromBool(bool? valid) {
154 : if (valid == null) return ConfirmationStatus.pending;
155 : if (valid) return ConfirmationStatus.confirmed;
156 : return ConfirmationStatus.failed;
157 : }
158 :
159 2 : static ConfirmationStatus fromJson(int status) => values[status];
160 :
161 : final String displayName;
162 :
163 : const ConfirmationStatus(this.displayName);
164 : }
165 :
166 : enum TransactionTransferMethod {
167 : receive("receive"),
168 :
169 : send("send"),
170 :
171 : own("own"),
172 :
173 : unknown("unknown");
174 :
175 1 : static TransactionTransferMethod fromAddress(
176 : String address,
177 : String recipient,
178 : String sender,
179 : ) {
180 3 : if (address.toLowerCase() == sender.toLowerCase() &&
181 3 : address.toLowerCase() == recipient.toLowerCase())
182 : return TransactionTransferMethod.own;
183 1 : if (address == recipient) return TransactionTransferMethod.receive;
184 : return TransactionTransferMethod.send;
185 : }
186 :
187 : final String displayName;
188 :
189 : const TransactionTransferMethod(this.displayName);
190 :
191 2 : static TransactionTransferMethod fromJson(int index) => values[index];
192 : }
|