wative 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/tools.ts ADDED
@@ -0,0 +1,742 @@
1
+ const chalk = require('chalk');
2
+ import { BigNumber } from 'bignumber.js';
3
+ import inquirer from 'inquirer';
4
+ import { chainAddressValidator, confirmSomething, editorSomething, getAccountChainType, hexValidator, inputSomething, numberValidator, selectSomething } from "./utils";
5
+ import { loginIn } from './account';
6
+ import { getAccountBalance, getDefaultNetworkByAddress, getEvmNetworks, getNetworkInfoByName, getNetworkTypeByName } from './network';
7
+ import { GasUtil } from './tx_gas_utils';
8
+ import { getAccountBalanceInEvm, getAccountBalanceInSolana, getAccountInfoInSolana, getCodeInEvm, getPrioritizationFee, getTokenBalanceInEvm, getTokenBalanceInSolana, getTokenInfoInEvm, getTokenInfoInSolana, getTransferTokenData } from './web3';
9
+ import { getAssetListByTokenName } from './assets';
10
+ import { ComputeBudgetProgram, PublicKey, SystemProgram, Transaction } from '@solana/web3.js';
11
+ import {
12
+ getAssociatedTokenAddressSync,
13
+ createTransferInstruction,
14
+ createAssociatedTokenAccountInstruction
15
+ } from "@solana/spl-token";
16
+
17
+ const { WativeCore } = require("wative-core");
18
+
19
+ const confirmEvmRawTransaction = async (tx_params: any) => {
20
+ let option_send_evm_raw_transaction_list: any = [
21
+ new inquirer.Separator("————Tx Detail—————-"),
22
+ `from: ${tx_params.from}`,
23
+ `to: ${tx_params.to}`,
24
+ `nonce: ${tx_params.nonce}`,
25
+ `gasPrice: ${tx_params.gasPrice}`,
26
+ `data: ${tx_params.data}`,
27
+ `value: ${tx_params.value}`,
28
+ `gas: ${tx_params.gas}`,
29
+ new inquirer.Separator("——————————————-"),
30
+ "Send it now",
31
+ ];
32
+
33
+ let selected_send_evm_raw_transaction = await selectSomething(option_send_evm_raw_transaction_list);
34
+ let option_id = option_send_evm_raw_transaction_list.indexOf(selected_send_evm_raw_transaction);
35
+
36
+ if (option_id === 1) {
37
+ tx_params.from = await inputSomething("from", chainAddressValidator);
38
+ }
39
+ if (option_id === 2) {
40
+ tx_params.to = await inputSomething("to", chainAddressValidator);
41
+ }
42
+ if (option_id === 3) {
43
+ tx_params.nonce = await inputSomething("nonce");
44
+ }
45
+ if (option_id === 4) {
46
+ tx_params.gasPrice = await inputSomething("gasPrice");
47
+ }
48
+ if (option_id === 5) {
49
+ tx_params.data = await editorSomething("data");
50
+ }
51
+ if (option_id === 6) {
52
+ tx_params.value = await inputSomething("value");
53
+ }
54
+ if (option_id === 7) {
55
+ tx_params.gas = await inputSomething("gas");
56
+ }
57
+
58
+ if (option_id === 9) {
59
+ return tx_params;
60
+ }
61
+
62
+ await confirmEvmRawTransaction(tx_params);
63
+ }
64
+
65
+ const sendEvmRawTransaction = async (chain_rpc_url: string, chain_symbols: string, account_address: string, wative_core: typeof WativeCore) => {
66
+ const to = await inputSomething("to", chainAddressValidator);
67
+ const gasUtil = new GasUtil(chain_rpc_url);
68
+ const estimateGasPrice = await gasUtil.getGasPrice();
69
+ const estimateGasPriceEthers = (new BigNumber(estimateGasPrice.toString())).dividedBy(1e9);
70
+ const _estimateGasPrice = estimateGasPriceEthers.toFixed(4, BigNumber.ROUND_FLOOR);
71
+ const inputGasPrice = await inputSomething(`Gas price (${_estimateGasPrice}), agree or enter`);
72
+ let gasPrice = inputGasPrice ? inputGasPrice : _estimateGasPrice;
73
+ gasPrice = (new BigNumber(gasPrice)).multipliedBy(1e9).toFixed(0);
74
+
75
+ let code_result = await getCodeInEvm(to, chain_rpc_url);
76
+ if (!code_result.status) {
77
+ console.log(chalk.red(code_result.output));
78
+ return;
79
+ }
80
+
81
+ let data: string;
82
+ let value: any;
83
+ if (code_result.output === "0x") {
84
+ data = "0x";
85
+
86
+ let account_balance_result = await getAccountBalanceInEvm(account_address, chain_rpc_url);
87
+ if (!account_balance_result.status) {
88
+ console.log(chalk.red(account_balance_result.output));
89
+ return;
90
+ }
91
+ let account_balance = new BigNumber(account_balance_result.output);
92
+ let tx_gas_price = new BigNumber(gasPrice);
93
+ let max_vaule = account_balance.minus(tx_gas_price.multipliedBy(21000)).toFixed(0, BigNumber.ROUND_FLOOR);
94
+ let total_balance = (new BigNumber(max_vaule)).dividedBy(1e18).toFixed(4, BigNumber.ROUND_FLOOR);
95
+
96
+ if (new BigNumber(total_balance) < new BigNumber(0)) {
97
+ console.log(chalk.red("Not enough balance"));
98
+ return
99
+ }
100
+
101
+ let option_select_vaule_list: any = [
102
+ "> Input value",
103
+ `> Total Balance (${total_balance} ${chain_symbols})`
104
+ ]
105
+ let selected_vaule = await selectSomething(option_select_vaule_list);
106
+ let vaule_id = option_select_vaule_list.indexOf(selected_vaule);
107
+ if (vaule_id === 0) {
108
+ let input_value = await inputSomething("value", numberValidator);
109
+ value = new BigNumber(input_value).multipliedBy(1e18).toFixed(0, BigNumber.ROUND_FLOOR);
110
+ } else if (vaule_id === 1) {
111
+ value = max_vaule;
112
+ }
113
+
114
+ if ((new BigNumber(value)).isGreaterThan(new BigNumber(max_vaule))) {
115
+ console.log(chalk.red("Not enough balance"));
116
+ return;
117
+ }
118
+ } else {
119
+ data = await editorSomething("data", hexValidator);
120
+ value = await inputSomething("value", numberValidator);
121
+ }
122
+
123
+ const estimateNonce = await gasUtil.getTransactionCount(account_address);
124
+ const _nonce = await inputSomething(`Nonce (${estimateNonce}), agree or enter`);
125
+ const nonce = _nonce ? _nonce : estimateNonce.toString();
126
+ let txParams: any = {
127
+ from: account_address,
128
+ to: to,
129
+ nonce: nonce,
130
+ gasPrice: gasPrice,
131
+ data: data,
132
+ value: value
133
+ };
134
+
135
+ if (data === '0x') {
136
+ txParams['gas'] = "21000";
137
+ } else {
138
+ let sendGasPrice = txParams.gasPrice;
139
+ delete txParams.gasPrice;
140
+ try {
141
+ txParams['gas'] = (await gasUtil.estimateTxGas(txParams)).toString();
142
+ } catch (err) {
143
+ console.log(
144
+ chalk.red("Error: " + err)
145
+ );
146
+ return;
147
+ }
148
+
149
+ txParams.gasPrice = sendGasPrice;
150
+ }
151
+ txParams = await confirmEvmRawTransaction(txParams);
152
+ const signed_message_result = await wative_core.account.signTransaction(
153
+ account_address,
154
+ txParams,
155
+ chain_rpc_url
156
+ );
157
+
158
+ if (!signed_message_result.status) {
159
+ console.log(chalk.red(signed_message_result.output));
160
+ return;
161
+ }
162
+ let transaction_receipt_result = await wative_core.account.sendSignedTransaction(account_address, signed_message_result.output.rawTransaction, chain_rpc_url);
163
+ if (!transaction_receipt_result.status) {
164
+ console.log(chalk.red(transaction_receipt_result.output));
165
+ return;
166
+ }
167
+
168
+ console.log(chalk.green(`Transaction hash: ${transaction_receipt_result.output.transactionHash}`));
169
+ }
170
+
171
+ export const sendSolanaRawTransaction = async (chain_rpc_url: string, chain_symbols: string, account_address: string, wative_core: typeof WativeCore) => {
172
+ const to = await inputSomething("to", chainAddressValidator);
173
+
174
+ let transaction = new Transaction().add(SystemProgram.transfer({
175
+ fromPubkey: new PublicKey(account_address),
176
+ toPubkey: new PublicKey(to),
177
+ lamports: 1
178
+ }));
179
+ transaction.add(
180
+ ComputeBudgetProgram.setComputeUnitLimit({
181
+ units: 200000
182
+ })
183
+ );
184
+ transaction.add(
185
+ ComputeBudgetProgram.setComputeUnitPrice({
186
+ microLamports: 1000
187
+ })
188
+ );
189
+
190
+ const simulate_result = await wative_core.account.simulateTransaction(
191
+ account_address,
192
+ chain_rpc_url,
193
+ transaction
194
+ );
195
+ if (!simulate_result.status) {
196
+ console.log(chalk.red(simulate_result.output));
197
+ return;
198
+ }
199
+
200
+ if (!simulate_result.output || !simulate_result.output.value || simulate_result.output.value.unitsConsumed === 0 || simulate_result.output.value.err) {
201
+ console.log(chalk.red("Simulate error"));
202
+ return;
203
+ }
204
+
205
+ const unitsConsumed = new BigNumber(simulate_result.output.value.unitsConsumed.toString());
206
+ const prioritization_fee_result = await getPrioritizationFee(chain_rpc_url);
207
+ if (!prioritization_fee_result.status) {
208
+ console.log(chalk.red(prioritization_fee_result.output));
209
+ return;
210
+ }
211
+
212
+ const prioritization_fee = new BigNumber(prioritization_fee_result.output.toString());
213
+ const used_prioritization_fee = unitsConsumed.multipliedBy(prioritization_fee).toFixed(0, BigNumber.ROUND_CEIL);
214
+
215
+ const account_balance_result = await getAccountBalanceInSolana(account_address, chain_rpc_url);
216
+ if (!account_balance_result.status) {
217
+ console.log(chalk.red(account_balance_result.output));
218
+ return;
219
+ }
220
+
221
+ const account_balance = new BigNumber(account_balance_result.output);
222
+ const max_vaule = account_balance.minus(5000).minus(used_prioritization_fee);
223
+ let total_balance = (new BigNumber(max_vaule)).dividedBy(1e9).toFixed(4, BigNumber.ROUND_FLOOR);
224
+ if (new BigNumber(total_balance) < new BigNumber(0)) {
225
+ console.log(chalk.red("Not enough balance"));
226
+ return
227
+ }
228
+
229
+ let option_select_vaule_list: any = [
230
+ "> Input value",
231
+ `> Total Balance (${total_balance} ${chain_symbols})`
232
+ ]
233
+ let selected_vaule = await selectSomething(option_select_vaule_list);
234
+ let vaule_id = option_select_vaule_list.indexOf(selected_vaule);
235
+ let transfer_amount: string = "0";
236
+ if (vaule_id === 0) {
237
+ let input_value = await inputSomething("value", numberValidator);
238
+ transfer_amount = new BigNumber(input_value).multipliedBy(1e9).toFixed(0, BigNumber.ROUND_FLOOR);
239
+ if ((new BigNumber(transfer_amount)).isGreaterThan(new BigNumber(max_vaule))) {
240
+ console.log(chalk.red("Not enough balance"));
241
+ return;
242
+ }
243
+ } else if (vaule_id === 1) {
244
+ transfer_amount = max_vaule.toString();
245
+ }
246
+
247
+ let transactions = new Transaction();
248
+ transactions.add(
249
+ ComputeBudgetProgram.setComputeUnitLimit({
250
+ units: Math.ceil(Number(unitsConsumed) * 2)
251
+ })
252
+ );
253
+ transactions.add(
254
+ ComputeBudgetProgram.setComputeUnitPrice({
255
+ microLamports: Number(prioritization_fee)
256
+ })
257
+ );
258
+ transactions.add(SystemProgram.transfer({
259
+ fromPubkey: new PublicKey(account_address),
260
+ toPubkey: new PublicKey(to),
261
+ lamports: Number(transfer_amount)
262
+ }));
263
+
264
+ const signed_message_result = await wative_core.account.signTransaction(
265
+ account_address,
266
+ transactions,
267
+ chain_rpc_url
268
+ );
269
+
270
+ if (!signed_message_result.status) {
271
+ console.log(chalk.red(signed_message_result.output));
272
+ return;
273
+ }
274
+ let transaction_receipt_result = await wative_core.account.sendSignedTransaction(account_address, signed_message_result.output, chain_rpc_url);
275
+ if (!transaction_receipt_result.status) {
276
+ console.log(chalk.red(transaction_receipt_result.output));
277
+ return;
278
+ }
279
+
280
+ console.log(chalk.green(`Transaction hash: ${transaction_receipt_result.output}`));
281
+ }
282
+
283
+ const sendEvmTokenTransaction = async (keystore_path: string, chain_rpc_url: string, chain_id: string, account_address: string, wative_core: typeof WativeCore) => {
284
+ const option_token_address_list = [
285
+ "> Input token ticker",
286
+ "> Input token contract address"
287
+ ];
288
+ let selected_token_address = await selectSomething(option_token_address_list);
289
+
290
+ let token_address: any;
291
+ let token_decimals: any;
292
+ switch (selected_token_address) {
293
+ case "> Input token ticker":
294
+ let token_name = await inputSomething("token ticker");
295
+
296
+ let token_address_list = await getAssetListByTokenName(keystore_path, chain_id, token_name);
297
+ if (token_address_list.length === 0) {
298
+ console.log(chalk.red("Token not found"));
299
+ return;
300
+ }
301
+
302
+ let option_token_address_list: string[] = [];
303
+ for (let i = 0; i < token_address_list.length; i++) {
304
+ const token_balance_result = await getTokenBalanceInEvm(account_address, token_address_list[i].address, chain_rpc_url);
305
+ if (!token_balance_result.status) {
306
+ console.log(chalk.red(token_balance_result.output));
307
+ return;
308
+ }
309
+
310
+
311
+ let raw_token_balance = new BigNumber(token_balance_result.output);
312
+ let token_balance = raw_token_balance.dividedBy(10 ** Number(token_address_list[i].decimals)).toFixed(4, BigNumber.ROUND_FLOOR);
313
+ if (token_address_list.length === 1) {
314
+ option_token_address_list.push(
315
+ `> 1. ${token_name} Balance: ${token_balance}`
316
+ );
317
+ break;
318
+ }
319
+
320
+ option_token_address_list.push(
321
+ `> ${i + 1}. ${token_name} Balance: ${token_balance}(${token_address_list[i].address})`
322
+ );
323
+
324
+ option_token_address_list.push(token_address_list[i].address);
325
+ }
326
+ let selected_token_address = await selectSomething(option_token_address_list);
327
+ const token_ticker_info = token_address_list[option_token_address_list.indexOf(selected_token_address)];
328
+ token_address = token_ticker_info.address;
329
+ token_decimals = Number(token_ticker_info.decimals);
330
+ break;
331
+ case "> Input token contract address":
332
+ token_address = await inputSomething("token contract address", chainAddressValidator);
333
+ let token_info: any = await getTokenInfoInEvm(token_address, chain_rpc_url);
334
+ if (!token_info.status) {
335
+ console.log(chalk.red(token_info.output));
336
+ return;
337
+ }
338
+ token_decimals = Number(token_info.output.decimals);
339
+ break;
340
+ }
341
+
342
+ const receipt = await inputSomething("Receipt", chainAddressValidator);
343
+ const amount = await inputSomething("Amount", numberValidator);
344
+ const gasUtil = new GasUtil(chain_rpc_url);
345
+ const estimateGasPrice = await gasUtil.getGasPrice();
346
+ const estimateGasPriceEthers = (new BigNumber(estimateGasPrice.toString())).dividedBy(1e9);
347
+ const _estimateGasPrice = estimateGasPriceEthers.toFixed(4, BigNumber.ROUND_FLOOR);
348
+ const inputGasPrice = await inputSomething(`Gas price (${_estimateGasPrice}), agree or enter`);
349
+ let gasPrice = inputGasPrice ? inputGasPrice : _estimateGasPrice;
350
+ gasPrice = (new BigNumber(gasPrice)).multipliedBy(1e9).toFixed(0);
351
+
352
+ let transfer_amount = new BigNumber(amount).multipliedBy(Math.pow(10, token_decimals)).toFixed(0);
353
+ const data = await getTransferTokenData(receipt, transfer_amount, chain_rpc_url);
354
+
355
+ const estimateNonce = await gasUtil.getTransactionCount(account_address);
356
+ const _nonce = await inputSomething(`Nonce (${estimateNonce}), agree or enter`);
357
+ const nonce = _nonce ? _nonce : estimateNonce.toString();
358
+ let txParams: any = {
359
+ from: account_address,
360
+ to: token_address,
361
+ nonce: nonce,
362
+ gasPrice: gasPrice,
363
+ data: data,
364
+ value: "0",
365
+ };
366
+
367
+ if (data === '0x') {
368
+ txParams['gas'] = "21000";
369
+ } else {
370
+ let sendGasPrice = txParams.gasPrice;
371
+ delete txParams.gasPrice;
372
+ try {
373
+ txParams['gas'] = (await gasUtil.estimateTxGas(txParams)).toString();
374
+ } catch (err: any) {
375
+ console.log(
376
+ chalk.red("Failed to estimate gas, " + err.message)
377
+ );
378
+ return;
379
+ }
380
+
381
+ txParams.gasPrice = sendGasPrice;
382
+ }
383
+
384
+ txParams = await confirmEvmRawTransaction(txParams);
385
+ const signed_message_result = await wative_core.account.signTransaction(
386
+ account_address,
387
+ txParams,
388
+ chain_rpc_url
389
+ );
390
+
391
+ if (!signed_message_result.status) {
392
+ console.log(chalk.red(signed_message_result.output));
393
+ return;
394
+ }
395
+ let transaction_receipt_result = await wative_core.account.sendSignedTransaction(account_address, signed_message_result.output.rawTransaction, chain_rpc_url);
396
+ if (!transaction_receipt_result.status) {
397
+ console.log(chalk.red(transaction_receipt_result.output));
398
+ return;
399
+ }
400
+
401
+ console.log(chalk.green(`Transaction hash: ${transaction_receipt_result.output.transactionHash}`));
402
+ }
403
+
404
+ const sendSolanaTokenTransaction = async (keystore_path: string, chain_rpc_url: string, chain_id: string, account_address: string, wative_core: typeof WativeCore) => {
405
+ const option_token_address_list = [
406
+ "> Input token ticker",
407
+ "> Input token contract address"
408
+ ];
409
+ let selected_token_address = await selectSomething(option_token_address_list);
410
+
411
+ let token_address: any;
412
+ let token_decimals: any;
413
+ switch (selected_token_address) {
414
+ case "> Input token ticker":
415
+ let token_name = await inputSomething("token ticker");
416
+
417
+ let token_address_list = await getAssetListByTokenName(keystore_path, chain_id, token_name);
418
+ if (token_address_list.length === 0) {
419
+ console.log(chalk.red("Token not found"));
420
+ return;
421
+ }
422
+
423
+ let option_token_address_list: string[] = [];
424
+ for (let i = 0; i < token_address_list.length; i++) {
425
+ const token_balance_result = await getTokenBalanceInSolana(account_address, token_address_list[i].address, chain_rpc_url);
426
+ if (!token_balance_result.status) {
427
+ console.log(chalk.red(token_balance_result.output));
428
+ return;
429
+ }
430
+
431
+ let raw_token_balance = new BigNumber(token_balance_result.output);
432
+ let token_balance = raw_token_balance.dividedBy(10 ** Number(token_address_list[i].decimals)).toFixed(4, BigNumber.ROUND_FLOOR);
433
+ if (token_address_list.length === 1) {
434
+ option_token_address_list.push(
435
+ `> 1. ${token_name} Balance: ${token_balance}`
436
+ );
437
+ break;
438
+ }
439
+
440
+ option_token_address_list.push(
441
+ `> ${i + 1}. ${token_name} Balance: ${token_balance}(${token_address_list[i].address})`
442
+ );
443
+
444
+ option_token_address_list.push(token_address_list[i].address);
445
+ }
446
+ let selected_token_address = await selectSomething(option_token_address_list);
447
+ const token_ticker_info = token_address_list[option_token_address_list.indexOf(selected_token_address)];
448
+
449
+ token_address = token_ticker_info.address;
450
+ token_decimals = Number(token_ticker_info.decimals);
451
+ break;
452
+ case "> Input token contract address":
453
+ token_address = await inputSomething("token contract address", chainAddressValidator);
454
+ let token_info: any = await getTokenInfoInSolana(token_address, chain_rpc_url);
455
+ if (!token_info.status) {
456
+ console.log(chalk.red(token_info.output));
457
+ return;
458
+ }
459
+ token_decimals = Number(token_info.output.decimals);
460
+ break;
461
+ }
462
+
463
+ const receipt = await inputSomething("Receipt", chainAddressValidator);
464
+ const amount = await inputSomething("Amount", numberValidator);
465
+
466
+ let transfer_amount = new BigNumber(amount).multipliedBy(Math.pow(10, token_decimals)).toFixed(0);
467
+ let from_token_account = getAssociatedTokenAddressSync(
468
+ new PublicKey(token_address),
469
+ new PublicKey(account_address),
470
+ true
471
+ );
472
+
473
+ const from_token_account_info_result = await getAccountInfoInSolana(from_token_account.toString(), chain_rpc_url);
474
+ if (!from_token_account_info_result.status) {
475
+ console.log(chalk.red(from_token_account_info_result.output));
476
+ return;
477
+ }
478
+
479
+ if (!from_token_account_info_result.output || from_token_account_info_result.output.owner.toString() === PublicKey.default) {
480
+ console.log(chalk.red("From token account not found"));
481
+ return;
482
+ }
483
+
484
+ let receipt_token_account = getAssociatedTokenAddressSync(
485
+ new PublicKey(token_address),
486
+ new PublicKey(receipt),
487
+ false
488
+ );
489
+ const receipt_token_account_info_result = await getAccountInfoInSolana(receipt_token_account.toString(), chain_rpc_url);
490
+ if (!receipt_token_account_info_result.status) {
491
+ console.log(chalk.red(receipt_token_account_info_result.output));
492
+ return;
493
+ }
494
+
495
+ let transaction = new Transaction();
496
+ let transactions = new Transaction();
497
+ if (!receipt_token_account_info_result.output || receipt_token_account_info_result.output.owner.toString() === PublicKey.default) {
498
+ transaction.add(
499
+ createAssociatedTokenAccountInstruction(
500
+ new PublicKey(account_address),
501
+ new PublicKey(receipt_token_account),
502
+ new PublicKey(receipt),
503
+ new PublicKey(token_address)
504
+ )
505
+ );
506
+ transactions.add(
507
+ createAssociatedTokenAccountInstruction(
508
+ new PublicKey(account_address),
509
+ new PublicKey(receipt_token_account),
510
+ new PublicKey(receipt),
511
+ new PublicKey(token_address)
512
+ )
513
+ );
514
+ }
515
+
516
+ transaction.add(
517
+ createTransferInstruction(
518
+ from_token_account,
519
+ receipt_token_account,
520
+ new PublicKey(account_address),
521
+ Number(transfer_amount)
522
+ )
523
+ );
524
+
525
+ transaction.add(
526
+ ComputeBudgetProgram.setComputeUnitLimit({
527
+ units: 200000
528
+ })
529
+ );
530
+ transaction.add(
531
+ ComputeBudgetProgram.setComputeUnitPrice({
532
+ microLamports: 1000
533
+ })
534
+ );
535
+
536
+ const simulate_result = await wative_core.account.simulateTransaction(
537
+ account_address,
538
+ chain_rpc_url,
539
+ transaction
540
+ );
541
+
542
+ if (!simulate_result.status) {
543
+ console.log(chalk.red(simulate_result.output));
544
+ return;
545
+ }
546
+
547
+ if (!simulate_result.output || !simulate_result.output.value || simulate_result.output.value.unitsConsumed === 0 || simulate_result.output.value.err) {
548
+ console.log(chalk.red("Simulate error"));
549
+ return;
550
+ }
551
+
552
+ const unitsConsumed = new BigNumber(simulate_result.output.value.unitsConsumed.toString());
553
+ const prioritization_fee_result = await getPrioritizationFee(chain_rpc_url);
554
+ if (!prioritization_fee_result.status) {
555
+ console.log(chalk.red(prioritization_fee_result.output));
556
+ return;
557
+ }
558
+
559
+ const prioritization_fee = new BigNumber(prioritization_fee_result.output.toString());
560
+
561
+ transactions.add(
562
+ createTransferInstruction(
563
+ from_token_account,
564
+ receipt_token_account,
565
+ new PublicKey(account_address),
566
+ Number(transfer_amount)
567
+ )
568
+ );
569
+
570
+ transactions.add(
571
+ ComputeBudgetProgram.setComputeUnitLimit({
572
+ units: Math.ceil(Number(unitsConsumed) * 1.2)
573
+ })
574
+ );
575
+ transactions.add(
576
+ ComputeBudgetProgram.setComputeUnitPrice({
577
+ microLamports: Number(prioritization_fee)
578
+ })
579
+ );
580
+
581
+ const signed_message_result = await wative_core.account.signTransaction(
582
+ account_address,
583
+ transactions,
584
+ chain_rpc_url
585
+ );
586
+
587
+ if (!signed_message_result.status) {
588
+ console.log(chalk.red(signed_message_result.output));
589
+ return;
590
+ }
591
+ let transaction_receipt_result = await wative_core.account.sendSignedTransaction(account_address, signed_message_result.output, chain_rpc_url);
592
+ if (!transaction_receipt_result.status) {
593
+ console.log(chalk.red(transaction_receipt_result.output));
594
+ return;
595
+ }
596
+
597
+ console.log(chalk.green(`Transaction hash: ${transaction_receipt_result.output}`));
598
+ }
599
+
600
+
601
+ const excuteTools = async (keystore_path: string, account_label: string, account_address: string, wative_core: typeof WativeCore) => {
602
+ let default_network = getDefaultNetworkByAddress(keystore_path, account_label, account_address);
603
+ let network_type = getNetworkTypeByName(keystore_path, default_network);
604
+ let account_chain_type = getAccountChainType(account_address);
605
+
606
+ if (network_type !== account_chain_type) {
607
+ if (account_chain_type === "evm") {
608
+ default_network = "Ethereum Mainnet"
609
+ }
610
+ if (account_chain_type === "solana") {
611
+ default_network = "Solana Mainnet"
612
+ }
613
+
614
+ network_type = getNetworkTypeByName(keystore_path, default_network);
615
+ }
616
+
617
+ if (network_type === "evm") {
618
+ let confirm = await confirmSomething(`Network (${default_network}), want a change?`);
619
+ if (confirm) {
620
+ const evm_networks = getEvmNetworks(keystore_path);
621
+ const selected_network = await selectSomething(evm_networks, "Select a network");
622
+ default_network = selected_network;
623
+ }
624
+ }
625
+
626
+ let account_balance = await getAccountBalance(account_address, keystore_path, default_network);
627
+
628
+ if (!account_balance.status) {
629
+ console.log(chalk.red(account_balance.output));
630
+ return;
631
+ }
632
+ const network_info = getNetworkInfoByName(keystore_path, default_network);
633
+
634
+ console.log(
635
+ chalk.green(` ${network_info.nativeCurrency.symbol} Balance: ${account_balance.output}`)
636
+ );
637
+
638
+ const option_send_tx = [
639
+ "> Send Raw Tx",
640
+ "> Send Token",
641
+ "> Back"
642
+ ];
643
+
644
+ const selected_send_tx = await selectSomething(option_send_tx);
645
+
646
+ switch (selected_send_tx) {
647
+ case "> Send Raw Tx": {
648
+ if (account_chain_type === "evm") {
649
+ await sendEvmRawTransaction(
650
+ network_info.rpcUrl,
651
+ network_info.nativeCurrency.symbol,
652
+ account_address,
653
+ wative_core
654
+ );
655
+ }
656
+
657
+ if (account_chain_type === "solana") {
658
+ await sendSolanaRawTransaction(
659
+ network_info.rpcUrl,
660
+ network_info.nativeCurrency.symbol,
661
+ account_address,
662
+ wative_core
663
+ );
664
+ }
665
+ break;
666
+ }
667
+ case "> Send Token": {
668
+ if (account_chain_type === "evm") {
669
+ await sendEvmTokenTransaction(
670
+ keystore_path,
671
+ network_info.rpcUrl,
672
+ network_info.chainId.toString(),
673
+ account_address,
674
+ wative_core
675
+ );
676
+ }
677
+
678
+ if (account_chain_type === "solana") {
679
+ await sendSolanaTokenTransaction(
680
+ keystore_path,
681
+ network_info.rpcUrl,
682
+ network_info.chainId.toString(),
683
+ account_address,
684
+ wative_core
685
+ );
686
+ }
687
+ break;
688
+ }
689
+ case "> Back": {
690
+ return;
691
+ }
692
+ }
693
+ }
694
+
695
+ export const selectToolsOptions = async (keystore_path: string, account_label: string, account_address: string, wative_core: typeof WativeCore) => {
696
+ const tools_options = [
697
+ "> SendTx",
698
+ "> SignMessage",
699
+ "> Back",
700
+ ];
701
+
702
+ const selected_tools_option = await selectSomething(tools_options);
703
+ switch (selected_tools_option) {
704
+ case "> SendTx": {
705
+ await excuteTools(keystore_path, account_label, account_address, wative_core);
706
+ break;
707
+ }
708
+ case "> SignMessage": {
709
+ const message = await editorSomething("Input the message to sign");
710
+ const signed_message = wative_core.account.signMessage(account_address, message);
711
+ if (!signed_message.status) {
712
+ console.log(chalk.red(signed_message.output));
713
+ break;
714
+ }
715
+ console.log(
716
+ chalk.green("Signature: " + signed_message.output)
717
+ );
718
+ break;
719
+ }
720
+ case "> Back": {
721
+ return;
722
+ }
723
+ }
724
+ await selectToolsOptions(keystore_path, account_label, account_address, wative_core);
725
+ }
726
+
727
+ export const showTools = async (keystore_path: string, wative_core: typeof WativeCore) => {
728
+ const account_address = await inputSomething("Input the address to send tx", chainAddressValidator);
729
+ const account_label = wative_core.account.getAccountLabel(account_address);
730
+ if (account_label === null) {
731
+ console.log(chalk.red("Account not found"));
732
+ await showTools(keystore_path, wative_core);
733
+ return;
734
+ }
735
+ let login_result = await loginIn(account_label, wative_core);
736
+ if (!login_result) {
737
+ await showTools(keystore_path, wative_core);
738
+ return;
739
+ }
740
+ await selectToolsOptions(keystore_path, account_label, account_address, wative_core);
741
+ await showTools(keystore_path, wative_core);
742
+ }