1 | const xhr = require("axios");
|
2 | const deserializeTransaction = require("../protocol/serializer").deserializeTransaction;
|
3 | const {base64DecodeFromString, byteArray2hexStr, bytesToString} = require("../utils/bytes");
|
4 | const {Block, Transaction, Account} = require("../protocol/core/Tron_pb");
|
5 | const {AccountList, NumberMessage, WitnessList, AssetIssueList} = require("../protocol/api/api_pb");
|
6 | const {TransferContract} = require("../protocol/core/Contract_pb");
|
7 | const qs = require("qs");
|
8 | const stringToBytes = require("../lib/code").stringToBytes;
|
9 | const { signTransaction, passwordToAddress } = require("../utils/crypto");
|
10 |
|
11 | class HttpClient {
|
12 |
|
13 | constructor(options = {}) {
|
14 | this.hostname = options.hostname || "tronscan.io";
|
15 | this.port = options.port || 80;
|
16 |
|
17 | |
18 |
|
19 |
|
20 | this.url = `https://${this.hostname}`;
|
21 | if (this.port !== 80) {
|
22 | this.url+= `:${this.port}`;
|
23 | }
|
24 | }
|
25 |
|
26 | |
27 |
|
28 |
|
29 |
|
30 |
|
31 | async getNodes() {
|
32 | let {data} = await xhr.get(`${this.url}/nodeList`);
|
33 | return JSON.parse(data);
|
34 | }
|
35 | |
36 |
|
37 |
|
38 |
|
39 |
|
40 | async getLatestBlock() {
|
41 | let {data} = await xhr.get(`${this.url}/getBlockToView`);
|
42 | let currentBlock = base64DecodeFromString(data);
|
43 | let block = Block.deserializeBinary(currentBlock);
|
44 |
|
45 | return {
|
46 | number: block.getBlockHeader().getRawData().getNumber(),
|
47 | witnessId: block.getBlockHeader().getRawData().getWitnessId(),
|
48 | parentHash: byteArray2hexStr(block.getBlockHeader().getRawData().getParenthash()),
|
49 | };
|
50 | }
|
51 |
|
52 | |
53 |
|
54 |
|
55 |
|
56 |
|
57 | async getBlockByNum(blockNumber) {
|
58 | let {data} = await xhr.get(`${this.url}/getBlockByNumToView?num=${blockNumber}`);
|
59 | let currentBlock = base64DecodeFromString(data);
|
60 | let blockData = Block.deserializeBinary(currentBlock);
|
61 |
|
62 | let recentBlock = base64DecodeFromString(data);
|
63 |
|
64 | let transactions = [];
|
65 |
|
66 | for (let transaction of blockData.getTransactionsList()) {
|
67 | transactions = transactions.concat(deserializeTransaction(transaction));
|
68 | }
|
69 |
|
70 | return {
|
71 | size: recentBlock.length,
|
72 | parentHash: byteArray2hexStr(blockData.getBlockHeader().getRawData().getParenthash()),
|
73 | number: blockData.getBlockHeader().getRawData().getNumber(),
|
74 | witnessAddress: byteArray2hexStr(blockData.getBlockHeader().getRawData().getWitnessAddress()),
|
75 | time: blockData.getBlockHeader().getRawData().getTimestamp(),
|
76 | transactionsCount: blockData.getTransactionsList().length,
|
77 | contraxtType: Transaction.Contract.ContractType,
|
78 | transactions,
|
79 | };
|
80 | }
|
81 |
|
82 | |
83 |
|
84 |
|
85 |
|
86 | async getTotalNumberOfTransactions() {
|
87 | let {data} = await xhr.get(`${this.url}/getTotalTransaction`);
|
88 | let totalTransaction = base64DecodeFromString(data);
|
89 | let totalData = NumberMessage.deserializeBinary(totalTransaction);
|
90 | return totalData.getNum();
|
91 | }
|
92 |
|
93 | |
94 |
|
95 |
|
96 |
|
97 | async getAccountList() {
|
98 |
|
99 | let {data} = await xhr.get(`${this.url}/accountList`);
|
100 |
|
101 | let bytesAccountList = base64DecodeFromString(data);
|
102 | let account = AccountList.deserializeBinary(bytesAccountList);
|
103 | let accountList = account.getAccountsList();
|
104 |
|
105 | return accountList.map(account => {
|
106 | let name = bytesToString(account.getAccountName());
|
107 | let address = byteArray2hexStr(account.getAddress());
|
108 | let balance = account.getBalance();
|
109 | let balanceNum = 0;
|
110 | if (balance !== 0) {
|
111 | balanceNum = (balance / 1000000).toFixed(6);
|
112 | }
|
113 | return {
|
114 | name,
|
115 | address,
|
116 | balance,
|
117 | balanceNum,
|
118 | };
|
119 | });
|
120 | }
|
121 |
|
122 | |
123 |
|
124 |
|
125 |
|
126 |
|
127 | async getWitnesses() {
|
128 | let {data} = await xhr.get(`${this.url}/witnessList`);
|
129 |
|
130 | let bytesWitnessList = base64DecodeFromString(data);
|
131 | let witness = WitnessList.deserializeBinary(bytesWitnessList);
|
132 | let witnessList = witness.getWitnessesList();
|
133 |
|
134 | return witnessList.map(witness => {
|
135 |
|
136 | return {
|
137 | address: byteArray2hexStr(witness.getAddress()),
|
138 | url: witness.getUrl(),
|
139 | latestBlockNumber: witness.getLatestblocknum(),
|
140 | producedTotal: witness.getTotalproduced(),
|
141 | missedTotal: witness.getTotalmissed(),
|
142 | votes: witness.getVotecount(),
|
143 | };
|
144 | });
|
145 | }
|
146 |
|
147 | |
148 |
|
149 |
|
150 |
|
151 |
|
152 | async getAssetIssueList() {
|
153 | let {data} = await xhr.get(`${this.url}/getAssetIssueList`);
|
154 |
|
155 | let assetIssueListObj = AssetIssueList.deserializeBinary(base64DecodeFromString(data));
|
156 | return assetIssueListObj.getAssetissueList().map(asset => {
|
157 | return {
|
158 | name: bytesToString(asset.getName()),
|
159 | ownerAddress: byteArray2hexStr(asset.getOwnerAddress()),
|
160 | totalSupply: asset.getTotalSupply(),
|
161 | startTime: asset.getStartTime(),
|
162 | endTime: asset.getEndTime(),
|
163 | description: bytesToString(asset.getDescription()),
|
164 | num: asset.getNum(),
|
165 | trxNum: asset.getTrxNum(),
|
166 | price: asset.getTrxNum() / asset.getNum(),
|
167 | };
|
168 | });
|
169 | }
|
170 |
|
171 | |
172 |
|
173 |
|
174 |
|
175 |
|
176 |
|
177 | async getAccountBalances(address) {
|
178 | let {data} = await xhr.post(`${this.url}/queryAccount`, qs.stringify({
|
179 | address,
|
180 | }));
|
181 |
|
182 | let bytesAccountInfo = base64DecodeFromString(data);
|
183 | let accountInfo = Account.deserializeBinary(bytesAccountInfo);
|
184 | let assetMap = accountInfo.getAssetMap().toArray();
|
185 | let trxBalance = accountInfo.getBalance();
|
186 | let trxBalanceNum = (trxBalance / 1000000).toFixed(6);
|
187 |
|
188 | let balances = [{
|
189 | name: 'TRX',
|
190 | balance: trxBalanceNum
|
191 | }];
|
192 |
|
193 | for (let asset of Object.keys(assetMap)) {
|
194 | balances.push({
|
195 | name: assetMap[asset][0],
|
196 | balance: assetMap[asset][1],
|
197 | })
|
198 | }
|
199 |
|
200 | return balances;
|
201 | }
|
202 |
|
203 | |
204 |
|
205 |
|
206 |
|
207 |
|
208 |
|
209 |
|
210 | async voteForWitnesses(address, votes) {
|
211 | await xhr
|
212 | .post(`${this.url}/createVoteWitnessToView`, {
|
213 | owner: address,
|
214 | list: votes,
|
215 | });
|
216 | }
|
217 |
|
218 |
|
219 | |
220 |
|
221 |
|
222 |
|
223 |
|
224 |
|
225 |
|
226 |
|
227 | async applyForDelegate(password, url) {
|
228 | let {data} = await xhr
|
229 | .post(`${this.url}/createWitnessToView`, qs.stringify({
|
230 | address: passwordToAddress(password),
|
231 | onwerUrl: url,
|
232 | }));
|
233 |
|
234 | return await this.signTransaction(password, data);
|
235 | }
|
236 |
|
237 | async signTransaction(password, data) {
|
238 | let bytesDecode = base64DecodeFromString(data);
|
239 | let transaction = Transaction.deserializeBinary(bytesDecode);
|
240 | let transactionSigned = signTransaction(base64DecodeFromString(password), transaction);
|
241 | let transactionBytes = transactionSigned.serializeBinary();
|
242 | let transactionString = byteArray2hexStr(transactionBytes);
|
243 |
|
244 | let {data: transData} = await xhr.post(`${this.url}/transactionFromView`, qs.stringify({
|
245 | transactionData: transactionString,
|
246 | }));
|
247 |
|
248 | return transData;
|
249 | }
|
250 |
|
251 | |
252 |
|
253 |
|
254 |
|
255 |
|
256 |
|
257 |
|
258 |
|
259 |
|
260 | async send(password, token, to, amount) {
|
261 |
|
262 | if (token.toUpperCase() === 'TRX') {
|
263 | let {data} = await xhr.post(`${this.url}/sendCoinToView`, qs.stringify({
|
264 | Address: passwordToAddress(password),
|
265 | toAddress: to,
|
266 | Amount: amount
|
267 | }));
|
268 |
|
269 | return await this.signTransaction(password, data);
|
270 | } else {
|
271 | let {data} = await xhr.post(`${this.url}/TransferAssetToView`, qs.stringify({
|
272 | assetName: token,
|
273 | Address: passwordToAddress(password),
|
274 | toAddress: to,
|
275 | Amount: amount,
|
276 | }));
|
277 |
|
278 | return await this.signTransaction(password, data);
|
279 | }
|
280 | }
|
281 |
|
282 | |
283 |
|
284 |
|
285 |
|
286 |
|
287 | async createToken(password, config) {
|
288 | let {data} = await xhr.post(`${this.url}/createAssetIssueToView`, qs.stringify({
|
289 | name: config.name,
|
290 | totalSupply: config.totalSupply,
|
291 | num: config.num,
|
292 | trxNum: config.trxNum,
|
293 | startTime: Date.parse(config.startTime),
|
294 | endTime: Date.parse(config.endTime),
|
295 | description: config.description,
|
296 | url: config.url,
|
297 | ownerAddress: passwordToAddress(password),
|
298 | }));
|
299 |
|
300 | return await this.signTransaction(password, data);
|
301 | }
|
302 |
|
303 | async participateAsset(password, config) {
|
304 | let {data} = await xhr.post(`${this.url}/ParticipateAssetIssueToView`, qs.stringify({
|
305 | name: byteArray2hexStr(stringToBytes(config.name)),
|
306 | ownerAddress: passwordToAddress(password),
|
307 | toAddress: config.issuerAddress,
|
308 | amount: config.amount,
|
309 | }));
|
310 |
|
311 | return await this.signTransaction(password, data);
|
312 | }
|
313 | }
|
314 |
|
315 | module.exports = HttpClient;
|