Line data Source code
1 : import 'dart:typed_data';
2 :
3 : import 'package:fixnum/fixnum.dart';
4 : import 'package:walletkit_dart/src/crypto/tron/repositories/rpc/core/any.pb.dart';
5 : import 'package:walletkit_dart/src/crypto/tron/repositories/rpc/core/contract/asset_issue_contract.pb.dart';
6 : import 'package:walletkit_dart/src/crypto/tron/repositories/rpc/core/contract/balance_contract.pb.dart';
7 : import 'package:walletkit_dart/src/crypto/tron/repositories/rpc/core/contract/smart_contract.pb.dart';
8 : import 'package:walletkit_dart/src/crypto/tron/entities/tron_parameter_type.dart';
9 : import 'package:walletkit_dart/src/utils/keccak.dart';
10 : import 'package:walletkit_dart/walletkit_dart.dart';
11 : import 'package:walletkit_dart/src/crypto/tron/repositories/rpc/core/Tron.pb.dart' as tron;
12 : import 'package:protobuf/protobuf.dart' as $pb;
13 :
14 : sealed class TronContractData {
15 3 : const TronContractData(this.type);
16 :
17 : final tron.Transaction_Contract_ContractType type;
18 :
19 1 : tron.Transaction_Contract createContract() {
20 1 : return tron.Transaction_Contract(
21 1 : type: type,
22 2 : parameter: Any.pack(contract),
23 : );
24 : }
25 :
26 : $pb.GeneratedMessage get contract;
27 :
28 1 : static TronContractData from(tron.Transaction_Contract_ContractType type, Any parameter) {
29 : return switch (type) {
30 2 : tron.Transaction_Contract_ContractType.TransferContract => TronTransferContractData.fromPB(
31 2 : parameter.unpackInto<TransferContract>(TransferContract()),
32 : ),
33 1 : tron.Transaction_Contract_ContractType.TriggerSmartContract =>
34 1 : TronTriggerSmartContractData.from(
35 2 : parameter.unpackInto<TriggerSmartContract>(TriggerSmartContract()),
36 : ),
37 1 : tron.Transaction_Contract_ContractType.TransferAssetContract =>
38 1 : TronTransferAssetContractData.fromPB(
39 2 : parameter.unpackInto<TransferAssetContract>(TransferAssetContract()),
40 : ),
41 0 : _ => throw UnsupportedError(
42 0 : "Unsupported Contract Type: $type with $parameter",
43 : ),
44 : };
45 : }
46 : }
47 :
48 : ///
49 : /// Used for Transferring of TRX
50 : ///
51 : final class TronTransferContractData extends TronContractData {
52 : final String to;
53 : final String from;
54 : final BigInt amount;
55 :
56 2 : const TronTransferContractData({
57 : required this.to,
58 : required this.from,
59 : required this.amount,
60 2 : }) : super(tron.Transaction_Contract_ContractType.TransferContract);
61 :
62 1 : factory TronTransferContractData.fromPB(
63 : TransferContract contract,
64 : ) {
65 1 : return TronTransferContractData(
66 3 : to: base58CheckFromHex(contract.toAddress.toUint8List),
67 3 : from: base58CheckFromHex(contract.ownerAddress.toUint8List),
68 3 : amount: contract.amount.toInt().toBigInt,
69 : );
70 : }
71 :
72 1 : @override
73 : TransferContract get contract {
74 1 : final contract = TransferContract(
75 2 : ownerAddress: base58ToHex(from),
76 2 : toAddress: base58ToHex(to),
77 3 : amount: Int64(amount.toInt()),
78 : );
79 :
80 : return contract;
81 : }
82 : }
83 :
84 : ///
85 : /// Used for Transferring of TRC10 Tokens
86 : ///
87 : final class TronTransferAssetContractData extends TronContractData {
88 : final String to;
89 : final String from;
90 : final String assetName;
91 : final BigInt amount;
92 :
93 1 : const TronTransferAssetContractData({
94 : required this.to,
95 : required this.from,
96 : required this.amount,
97 : required this.assetName,
98 1 : }) : super(tron.Transaction_Contract_ContractType.TransferAssetContract);
99 :
100 0 : @override
101 : TransferAssetContract get contract {
102 0 : return TransferAssetContract(
103 0 : ownerAddress: base58ToHex(from),
104 0 : toAddress: base58ToHex(to),
105 0 : assetName: assetName.hexToBytes,
106 0 : amount: Int64(amount.toInt()),
107 : );
108 : }
109 :
110 1 : factory TronTransferAssetContractData.fromPB(
111 : TransferAssetContract contract,
112 : ) {
113 1 : return TronTransferAssetContractData(
114 3 : to: base58CheckFromHex(contract.toAddress.toUint8List),
115 3 : from: base58CheckFromHex(contract.ownerAddress.toUint8List),
116 3 : amount: contract.amount.toInt().toBigInt,
117 3 : assetName: contract.assetName.toUint8List.toHex,
118 : );
119 : }
120 : }
121 :
122 : sealed class TronTriggerSmartContractData extends TronContractData {
123 : final String ownerAddress;
124 : final String contractAddress;
125 : final Uint8List data;
126 : final Int64? callValue;
127 : final Int64? callTokenValue;
128 : final Int64? token_id;
129 :
130 : final String function_selector;
131 : final List<TronParameter> parameters;
132 :
133 1 : TronTriggerSmartContractData({
134 : required this.ownerAddress,
135 : required this.contractAddress,
136 : required this.parameters,
137 : required this.function_selector,
138 : this.callValue,
139 : this.callTokenValue,
140 : this.token_id,
141 1 : }) : data = createParameter(
142 1 : getFunctionSignature(function_selector),
143 : parameters,
144 : ),
145 1 : super(tron.Transaction_Contract_ContractType.TriggerSmartContract);
146 :
147 1 : Uint8List get functionSignature {
148 2 : return data.sublist(0, 4);
149 : }
150 :
151 0 : @override
152 : TriggerSmartContract get contract {
153 0 : return TriggerSmartContract(
154 0 : ownerAddress: base58ToHex(ownerAddress),
155 0 : contractAddress: base58ToHex(contractAddress),
156 0 : data: data,
157 0 : callValue: callValue,
158 0 : callTokenValue: callTokenValue,
159 0 : tokenId: token_id,
160 : );
161 : }
162 :
163 1 : static TronTriggerSmartContractData from(
164 : TriggerSmartContract contract,
165 : ) {
166 3 : final owner = base58CheckFromHex(contract.ownerAddress.toUint8List);
167 3 : final contractAddress = base58CheckFromHex(contract.contractAddress.toUint8List);
168 :
169 2 : final data = contract.data.toUint8List;
170 1 : final functionSelector = getFunctionSelectorFromData(data);
171 :
172 : return switch (functionSelector) {
173 1 : TronTRC20TransferContractData.selector => TronTRC20TransferContractData.fromPB(
174 : data,
175 : ownerAddress: owner,
176 : contractAddress: contractAddress,
177 : ),
178 1 : _ => throw UnsupportedError(
179 1 : "Unsupported Contract Type: $functionSelector with $contract",
180 : ),
181 : };
182 : }
183 : }
184 :
185 : final class TronTRC20TransferContractData extends TronTriggerSmartContractData {
186 : final String recipient;
187 : final String ownerAddress;
188 : final String contractAddress;
189 : final Amount amount;
190 :
191 : static const selector = "transfer(address,uint256)";
192 : static const selectorHex = "a9059cbb";
193 :
194 1 : TronTRC20TransferContractData({
195 : required this.recipient,
196 : required this.ownerAddress,
197 : required this.contractAddress,
198 : required this.amount,
199 1 : }) : super(
200 : function_selector: selector,
201 : ownerAddress: ownerAddress,
202 : contractAddress: contractAddress,
203 1 : parameters: [
204 1 : TronAddressParameter(recipient),
205 2 : TronIntParameter(amount.value),
206 : ],
207 : );
208 :
209 0 : factory TronTRC20TransferContractData.fromPB(
210 : Uint8List data, {
211 : required String ownerAddress,
212 : required String contractAddress,
213 : }) {
214 0 : final paramData = decodeParams(
215 0 : data.sublist(4),
216 0 : [TronParameterType.ADDRESS, TronParameterType.INT256],
217 : );
218 :
219 0 : final recipient = paramData[0] as TronAddressParameter;
220 0 : final amount = paramData[1] as TronIntParameter;
221 :
222 0 : return TronTRC20TransferContractData(
223 0 : recipient: recipient.value,
224 : ownerAddress: "",
225 : contractAddress: "",
226 0 : amount: Amount(value: amount.value, decimals: 6),
227 : );
228 : }
229 : }
230 :
231 1 : Uint8List getFunctionSignature(String function_selector) {
232 1 : final hash = keccakUtf8(function_selector);
233 1 : return hash.sublist(0, 4);
234 : }
|