Line data Source code
1 : import 'dart:convert';
2 : import 'dart:typed_data';
3 : import 'package:walletkit_dart/walletkit_dart.dart';
4 :
5 : class TransferIntent<T extends FeeInformation> {
6 : final CoinEntity token;
7 : final String recipient;
8 : final Amount amount;
9 :
10 : /// If null, the fee will be calculated by the network
11 : final T? feeInfo;
12 :
13 : /// For EVM represents UTF8 Data in the input field
14 : /// For Tron and UTXO not implemented
15 : final String? memo;
16 :
17 : /// Is only respected for EVM Transactions
18 : final List<AccessListItem>? accessList;
19 :
20 1 : const TransferIntent({
21 : required this.recipient,
22 : required this.amount,
23 : required this.token,
24 : required this.memo,
25 : this.accessList,
26 : this.feeInfo,
27 : });
28 :
29 0 : Amount? get fee {
30 0 : if (feeInfo is EvmFeeInformation) {
31 0 : return (feeInfo as EvmFeeInformation).maxFee;
32 : }
33 0 : if (feeInfo is TronFeeInformation) {
34 0 : return (feeInfo as TronFeeInformation).feeLimit;
35 : }
36 0 : if (feeInfo is UtxoFeeInformation) {
37 0 : return (feeInfo as UtxoFeeInformation).fee;
38 : }
39 : return null;
40 : }
41 :
42 0 : Uint8List getErc20TransferSig() {
43 0 : return (erc20TransferSig +
44 0 : recipient.substring(2).padLeft(64, '0') +
45 0 : amount.value.toHex.padLeft(64, '0'))
46 0 : .hexToBytes;
47 : }
48 :
49 0 : Amount get total {
50 0 : if (token.isERC20) {
51 0 : return fee ?? Amount.zero;
52 : }
53 0 : return amount + (fee ?? Amount.zero);
54 : }
55 :
56 0 : Amount _calcTargetAmount(Amount balance, Amount fee) {
57 0 : if ((amount + fee) > balance) {
58 0 : return balance - fee;
59 : }
60 0 : return amount;
61 : }
62 :
63 : ///
64 : /// Copy the transfer intent with a new fee
65 : /// If [balance] is provided, the target amount will be recalculated
66 : ///
67 0 : TransferIntent<T> copyWithFee<T extends FeeInformation>(
68 : T feeInfo, {
69 : Amount? balance,
70 : }) {
71 : final newTargetValue = switch ((balance, feeInfo)) {
72 0 : (Amount balance, EvmFeeInformation info) when token.isERC20 == false && info.maxFee != null =>
73 0 : _calcTargetAmount(balance, info.maxFee!),
74 0 : (Amount balance, TronFeeInformation info) when token.isERC20 == false =>
75 0 : _calcTargetAmount(balance, info.feeLimit),
76 0 : _ => amount,
77 : };
78 :
79 0 : return TransferIntent(
80 0 : recipient: recipient,
81 : amount: newTargetValue,
82 : feeInfo: feeInfo,
83 0 : token: token,
84 0 : memo: memo,
85 0 : accessList: accessList,
86 : );
87 : }
88 :
89 0 : Json toJson() {
90 0 : return {
91 0 : 'recipient': recipient,
92 0 : 'amount': amount.toJson(),
93 0 : 'token': token.toJson(),
94 0 : 'fee': feeInfo?.toJson(),
95 0 : 'memo': memo,
96 : };
97 : }
98 :
99 0 : static TransferIntent fromJson(Map json) {
100 : return switch (json) {
101 : {
102 0 : 'recipient': String recipient,
103 0 : 'amount': Map amount,
104 0 : 'token': Map token,
105 0 : 'fee': Map? fee,
106 0 : 'memo': String? memo,
107 : } =>
108 0 : TransferIntent(
109 : recipient: recipient,
110 0 : amount: Amount.fromJson(amount),
111 0 : feeInfo: fee == null ? null : FeeInformation.fromJson(fee),
112 0 : token: CoinEntity.fromJson(token),
113 : memo: memo,
114 : ),
115 0 : _ => throw FormatException('Unknown TransferIntent: $json'),
116 : };
117 : }
118 :
119 0 : TransferIntent<T> copyWith({
120 : String? memo,
121 : Amount? amount,
122 : T? feeInfo,
123 : }) {
124 0 : return TransferIntent<T>(
125 0 : recipient: recipient,
126 0 : amount: amount ?? this.amount,
127 0 : feeInfo: feeInfo ?? this.feeInfo,
128 0 : token: token,
129 0 : memo: memo ?? this.memo,
130 : );
131 : }
132 :
133 0 : Uint8List? get encodedMemo {
134 0 : if (memo == null) {
135 : return null;
136 : }
137 0 : final utf = utf8.encode(memo!);
138 :
139 : return utf;
140 : }
141 :
142 0 : TransferIntent<A> convert<A extends FeeInformation>(A FeeInfo) {
143 0 : return TransferIntent<A>(
144 0 : recipient: recipient,
145 0 : amount: amount,
146 0 : feeInfo: feeInfo as A,
147 0 : token: token,
148 0 : memo: memo,
149 : );
150 : }
151 : }
|