Line data Source code
1 : import 'dart:math';
2 : import 'package:walletkit_dart/src/domain/predefined_assets.dart';
3 : import 'package:walletkit_dart/walletkit_dart.dart';
4 :
5 : const CoinEntity nullToken = CoinEntity(
6 : name: '',
7 : symbol: '',
8 : decimals: 0,
9 : );
10 :
11 : class CoinEntity {
12 : final String name;
13 : final String symbol;
14 : final int decimals;
15 :
16 76 : const CoinEntity({
17 : required this.name,
18 : required this.symbol,
19 : required this.decimals,
20 : });
21 :
22 0 : num get subunits => pow(10, decimals);
23 :
24 0 : String get identifier => "$name:$symbol:$decimals";
25 :
26 0 : ERC20Entity? get asEthBased =>
27 0 : this is ERC20Entity ? this as ERC20Entity : null;
28 :
29 0 : ERC1155Entity? get asERC1155 =>
30 0 : this is ERC1155Entity ? this as ERC1155Entity : null;
31 :
32 0 : bool get isEvm => this is EvmCoinEntity;
33 0 : bool get isERC20 => this is ERC20Entity;
34 0 : bool get isERC1155 => this is ERC1155Entity;
35 1 : bool get isUTXO => switch (this) {
36 5 : btcCoin || ltcCoin || zeniqCoin || bchCoin || ec8Coin => true,
37 : _ => false,
38 : };
39 :
40 9 : @override
41 72 : int get hashCode => name.hashCode ^ symbol.hashCode ^ decimals.hashCode;
42 :
43 14 : @override
44 : bool operator ==(Object other) {
45 : if (identical(this, other)) return true;
46 :
47 13 : return other is CoinEntity &&
48 13 : other is! EvmCoinEntity &&
49 39 : other.name == name &&
50 0 : other.symbol == symbol &&
51 0 : other.decimals == decimals;
52 : }
53 :
54 0 : @override
55 : String toString() {
56 0 : return '$name ($symbol)';
57 : }
58 :
59 1 : Map<String, dynamic> toJson() {
60 : return switch (this) {
61 1 : ERC20Entity ethBasedToken => {
62 0 : 'name': ethBasedToken.name,
63 0 : 'symbol': ethBasedToken.symbol,
64 0 : 'decimals': ethBasedToken.decimals,
65 0 : 'chainID': ethBasedToken.chainID,
66 0 : 'contractAddress': ethBasedToken.contractAddress,
67 0 : 'allowDeletion': ethBasedToken.allowDeletion,
68 : },
69 1 : ERC1155Entity erc1155Token => {
70 0 : 'name': erc1155Token.name,
71 0 : 'symbol': erc1155Token.symbol,
72 0 : 'contractAddress': erc1155Token.contractAddress,
73 0 : 'tokenId': erc1155Token.tokenId.toString(),
74 0 : 'allowDeletion': erc1155Token.allowDeletion,
75 0 : 'chainID': erc1155Token.chainID,
76 : },
77 1 : EvmCoinEntity evmEntity => {
78 0 : 'name': evmEntity.name,
79 0 : 'symbol': evmEntity.symbol,
80 0 : 'decimals': evmEntity.decimals,
81 0 : 'chainID': evmEntity.chainID,
82 : },
83 2 : CoinEntity tokenEntity => {
84 1 : 'name': tokenEntity.name,
85 1 : 'symbol': tokenEntity.symbol,
86 1 : 'decimals': tokenEntity.decimals,
87 : },
88 : };
89 : }
90 :
91 1 : factory CoinEntity.fromJson(Map json) {
92 : return switch (json) {
93 : {
94 2 : 'name': String name,
95 2 : 'symbol': String symbol,
96 2 : 'decimals': int decimals,
97 1 : 'chainID': int chainID,
98 1 : 'contractAddress': String contractAddress,
99 : } =>
100 0 : ERC20Entity(
101 : name: name,
102 : symbol: symbol,
103 : decimals: decimals,
104 : chainID: chainID,
105 : contractAddress: contractAddress,
106 0 : allowDeletion: json['allowDeletion'] ?? true,
107 : ),
108 : {
109 1 : "name": String name,
110 1 : "symbol": String symbol,
111 0 : "contractAddress": String contractAddress,
112 0 : "tokenId": String tokenId,
113 0 : "chainID": int chainID,
114 : } =>
115 0 : ERC1155Entity(
116 : name: name,
117 : symbol: symbol,
118 : contractAddress: contractAddress,
119 0 : tokenId: BigInt.parse(tokenId),
120 : chainID: chainID,
121 0 : allowDeletion: json['allowDeletion'] ?? true,
122 : ),
123 : {
124 1 : 'name': String name,
125 1 : 'symbol': String symbol,
126 1 : 'decimals': int decimals,
127 0 : 'chainID': int chainID,
128 : } =>
129 0 : EvmCoinEntity(
130 : name: name,
131 : symbol: symbol,
132 : decimals: decimals,
133 : chainID: chainID,
134 : ),
135 : {
136 1 : 'name': String name,
137 1 : 'symbol': String symbol,
138 1 : 'decimals': int decimals,
139 : } =>
140 1 : CoinEntity(
141 : name: name,
142 : symbol: symbol,
143 : decimals: decimals,
144 : ),
145 0 : _ => throw Exception("Invalid TokenEntity JSON"),
146 : };
147 : }
148 : }
149 :
150 : class EvmCoinEntity extends CoinEntity {
151 : final int chainID;
152 : final bool? allowDeletion;
153 :
154 0 : @override
155 0 : String get identifier => "$name:$symbol:$decimals:$chainID";
156 :
157 0 : @override
158 0 : int get hashCode => chainID.hashCode;
159 :
160 1 : @override
161 : bool operator ==(Object other) {
162 : if (identical(this, other)) return true;
163 :
164 0 : return other is EvmCoinEntity &&
165 0 : other is! ERC20Entity &&
166 0 : other is! ERC721Entity &&
167 0 : other is! ERC1155Entity &&
168 0 : other.chainID == chainID;
169 : }
170 :
171 38 : const EvmCoinEntity({
172 : required super.name,
173 : required super.symbol,
174 : required super.decimals,
175 : required this.chainID,
176 : this.allowDeletion = false,
177 : });
178 :
179 0 : EvmCoinEntity copyWith({
180 : String? name,
181 : String? symbol,
182 : int? decimals,
183 : int? chainID,
184 : bool? allowDeletion,
185 : }) {
186 0 : return EvmCoinEntity(
187 0 : name: name ?? this.name,
188 0 : symbol: symbol ?? this.symbol,
189 0 : decimals: decimals ?? this.decimals,
190 0 : chainID: chainID ?? this.chainID,
191 0 : allowDeletion: allowDeletion ?? this.allowDeletion,
192 : );
193 : }
194 : }
195 :
196 : class ERC1155Entity extends EvmCoinEntity {
197 : final String contractAddress;
198 : final BigInt tokenId;
199 :
200 1 : const ERC1155Entity({
201 : required super.name,
202 : required super.symbol,
203 : required super.chainID,
204 : required this.contractAddress,
205 : required this.tokenId,
206 : super.allowDeletion,
207 1 : }) : super(decimals: 0);
208 :
209 0 : String get lowerCaseAddress => contractAddress.toLowerCase();
210 :
211 0 : @override
212 : int get hashCode =>
213 0 : lowerCaseAddress.hashCode ^ chainID.hashCode ^ tokenId.hashCode;
214 :
215 0 : @override
216 : bool operator ==(Object other) {
217 : if (identical(this, other)) return true;
218 :
219 0 : return other is ERC1155Entity &&
220 0 : other.lowerCaseAddress == lowerCaseAddress &&
221 0 : other.chainID == chainID &&
222 0 : other.tokenId == tokenId;
223 : }
224 :
225 0 : ERC1155Entity copyWith({
226 : String? name,
227 : String? symbol,
228 : int? decimals,
229 : String? contractAddress,
230 : BigInt? tokenId,
231 : bool? allowDeletion,
232 : int? chainID,
233 : }) {
234 0 : return ERC1155Entity(
235 0 : name: name ?? this.name,
236 0 : symbol: symbol ?? this.symbol,
237 0 : contractAddress: contractAddress ?? this.contractAddress,
238 0 : tokenId: tokenId ?? this.tokenId,
239 0 : allowDeletion: allowDeletion ?? this.allowDeletion,
240 0 : chainID: chainID ?? this.chainID,
241 : );
242 : }
243 :
244 0 : factory ERC1155Entity.fromJson(
245 : Map<String, dynamic> json, {
246 : required bool allowDeletion,
247 : required int chainID,
248 : }) {
249 0 : return ERC1155Entity(
250 0 : name: json['name'],
251 0 : symbol: json['symbol'],
252 0 : contractAddress: json['contractAddress'],
253 0 : tokenId: BigInt.parse(json['tokenId']),
254 : allowDeletion: allowDeletion,
255 : chainID: chainID,
256 : );
257 : }
258 : }
259 :
260 : class ERC20Entity extends EvmCoinEntity {
261 : final String contractAddress;
262 :
263 38 : const ERC20Entity({
264 : required super.name,
265 : required super.symbol,
266 : required super.decimals,
267 : required super.chainID,
268 : required this.contractAddress,
269 : super.allowDeletion,
270 : });
271 :
272 6 : String get lowerCaseAddress => contractAddress.toLowerCase();
273 :
274 0 : @override
275 0 : String get identifier => "$name:$symbol:$decimals:$contractAddress:$chainID";
276 :
277 1 : @override
278 5 : int get hashCode => lowerCaseAddress.hashCode ^ chainID.hashCode;
279 :
280 1 : @override
281 : bool operator ==(Object other) {
282 : if (identical(this, other)) return true;
283 :
284 1 : return other is ERC20Entity &&
285 3 : other.lowerCaseAddress == lowerCaseAddress &&
286 3 : other.chainID == chainID;
287 : }
288 :
289 0 : factory ERC20Entity.fromJson(
290 : Map<String, dynamic> json, {
291 : required bool allowDeletion,
292 : required int chainID,
293 : }) {
294 0 : return ERC20Entity(
295 0 : name: json['name'],
296 0 : symbol: json['symbol'],
297 0 : decimals: json['decimals'],
298 0 : contractAddress: json['contractAddress'],
299 : allowDeletion: allowDeletion,
300 : chainID: chainID,
301 : );
302 : }
303 :
304 0 : ERC20Entity copyWith({
305 : String? name,
306 : String? symbol,
307 : int? decimals,
308 : String? contractAddress,
309 : bool? allowDeletion,
310 : int? chainID,
311 : }) {
312 0 : return ERC20Entity(
313 0 : name: name ?? this.name,
314 0 : symbol: symbol ?? this.symbol,
315 0 : decimals: decimals ?? this.decimals,
316 0 : contractAddress: contractAddress ?? this.contractAddress,
317 0 : allowDeletion: allowDeletion ?? this.allowDeletion,
318 0 : chainID: chainID ?? this.chainID,
319 : );
320 : }
321 : }
322 :
323 : class ERC721Entity extends EvmCoinEntity {
324 : final String contractAddress;
325 : final BigInt tokenId;
326 :
327 1 : const ERC721Entity({
328 : required super.name,
329 : required super.symbol,
330 : required super.chainID,
331 : required this.contractAddress,
332 : required this.tokenId,
333 1 : }) : super(decimals: 0);
334 :
335 0 : String get lowerCaseAddress => contractAddress.toLowerCase();
336 :
337 0 : @override
338 : int get hashCode =>
339 0 : lowerCaseAddress.hashCode ^ chainID.hashCode ^ tokenId.hashCode;
340 :
341 0 : @override
342 : bool operator ==(Object other) {
343 : if (identical(this, other)) return true;
344 :
345 0 : return other is ERC721Entity &&
346 0 : other.lowerCaseAddress == lowerCaseAddress &&
347 0 : other.chainID == chainID &&
348 0 : other.tokenId == tokenId;
349 : }
350 : }
|