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)
73 0 : when token.isERC20 == false && info.maxFee != null =>
74 0 : _calcTargetAmount(balance, info.maxFee!),
75 0 : (Amount balance, TronFeeInformation info) when token.isERC20 == false =>
76 0 : _calcTargetAmount(balance, info.feeLimit),
77 0 : _ => amount,
78 : };
79 :
80 0 : return TransferIntent(
81 0 : recipient: recipient,
82 : amount: newTargetValue,
83 : feeInfo: feeInfo,
84 0 : token: token,
85 0 : memo: memo,
86 0 : accessList: accessList,
87 : );
88 : }
89 :
90 0 : Json toJson() {
91 0 : return {
92 0 : 'recipient': recipient,
93 0 : 'amount': amount.toJson(),
94 0 : 'token': token.toJson(),
95 0 : 'fee': feeInfo?.toJson(),
96 0 : 'memo': memo,
97 : };
98 : }
99 :
100 0 : static TransferIntent fromJson(Map json) {
101 : return switch (json) {
102 : {
103 0 : 'recipient': String recipient,
104 0 : 'amount': Map amount,
105 0 : 'token': Map token,
106 0 : 'fee': Map? fee,
107 0 : 'memo': String? memo,
108 : } =>
109 0 : TransferIntent(
110 : recipient: recipient,
111 0 : amount: Amount.fromJson(amount),
112 0 : feeInfo: fee == null ? null : FeeInformation.fromJson(fee),
113 0 : token: CoinEntity.fromJson(token),
114 : memo: memo,
115 : ),
116 0 : _ => throw FormatException('Unknown TransferIntent: $json'),
117 : };
118 : }
119 :
120 0 : TransferIntent<T> copyWith({
121 : String? memo,
122 : Amount? amount,
123 : T? feeInfo,
124 : }) {
125 0 : return TransferIntent<T>(
126 0 : recipient: recipient,
127 0 : amount: amount ?? this.amount,
128 0 : feeInfo: feeInfo ?? this.feeInfo,
129 0 : token: token,
130 0 : memo: memo ?? this.memo,
131 : );
132 : }
133 :
134 0 : Uint8List? get encodedMemo {
135 0 : if (memo == null) {
136 : return null;
137 : }
138 0 : final utf = utf8.encode(memo!);
139 :
140 : return utf;
141 : }
142 :
143 0 : TransferIntent<A> convert<A extends FeeInformation>(A FeeInfo) {
144 0 : return TransferIntent<A>(
145 0 : recipient: recipient,
146 0 : amount: amount,
147 0 : feeInfo: feeInfo as A,
148 0 : token: token,
149 0 : memo: memo,
150 : );
151 : }
152 : }
|