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