wative 1.0.9 → 1.0.10

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/utils.ts CHANGED
@@ -3,10 +3,12 @@ const chalk = require('chalk')
3
3
  import * as figlet from 'figlet'
4
4
  import inquirer from 'inquirer'
5
5
  import * as fs from 'fs'
6
+ import * as path from "path";
6
7
 
7
8
  import { getChainIdByEvm } from "./web3";
8
9
  import { MNEMONIC_WORDS } from './config';
9
10
  import { getChainType } from './chain';
11
+ import { getBatchAccountBalance } from './assets';
10
12
 
11
13
  const USER_HOME: any = process.env.HOME || process.env.USERPROFILE
12
14
  const BASE_PATH = `${USER_HOME}/.wative`
@@ -100,6 +102,13 @@ export const tagValidator = (tag: string) => {
100
102
  return true;
101
103
  }
102
104
 
105
+ export const addrValidator = (tag: string) => {
106
+ if (tag.length < 6) {
107
+ return "Address length should be greater than 6";
108
+ }
109
+ return true;
110
+ }
111
+
103
112
  export const numberValidator = (value: string) => {
104
113
  if (isNaN(Number(value))) {
105
114
  return "Value should be a number";
@@ -230,7 +239,7 @@ export const getRpcUrl = async (chain_id: string, text: string, update: boolean
230
239
  return null
231
240
  }
232
241
 
233
- if (getChainType(chain_id) === "solana") {
242
+ if (getChainType(chain_id.toString()) === "solana") {
234
243
  return rpc_url;
235
244
  }
236
245
  const new_chain_id = await getChainIdByEvm(rpc_url);
@@ -297,7 +306,7 @@ export const getColor = async (text: string) => {
297
306
  }
298
307
 
299
308
  export const getAccountLabel = async (text: string, account_label_list: string[]) => {
300
- let reg = /^[a-zA-Z0-9]{2,20}$/g;
309
+ let reg = /^(?![-_]).*?[a-zA-Z0-9_-]{4,20}(?<![-_])$/g;
301
310
  for (let i = 0; i < 5; i++) {
302
311
  let account_label = await inputSomething(text);
303
312
  account_label = account_label.trim();
@@ -306,7 +315,7 @@ export const getAccountLabel = async (text: string, account_label_list: string[]
306
315
  console.log(chalk.red("Account label already exists"));
307
316
  continue;
308
317
  } else {
309
- return account_label.toLocaleLowerCase();
318
+ return account_label;
310
319
  }
311
320
  }
312
321
  }
@@ -360,16 +369,29 @@ const passwordValidator = function (value: string) {
360
369
  };
361
370
 
362
371
  export const inputPassword = async (text: string) => {
372
+ let count = 0;
373
+
363
374
  const questions = [
364
375
  {
365
376
  name: 'password',
366
377
  type: 'password',
367
378
  mask: '#',
368
379
  message: `${text}:`,
369
- validate: passwordValidator
380
+ validate: (fieldValue: string) => {
381
+ if (count >= 3) {
382
+ return true
383
+ }
384
+
385
+ return passwordValidator(fieldValue);
386
+ }
370
387
  }
371
388
  ]
372
- const { password } = await inquirer.prompt(questions);
389
+
390
+ let { password } = await inquirer.prompt(questions);
391
+ if (count >= 3) {
392
+ password = null;
393
+ }
394
+
373
395
  return password;
374
396
  }
375
397
 
@@ -443,4 +465,212 @@ export const getAccountChainType = (account_address: string) => {
443
465
  export const checkFileExistence = (file_path: string): boolean => {
444
466
  file_path = file_path.trim()
445
467
  return fs.existsSync(file_path);
468
+ }
469
+
470
+ export const chunkArray = (array: any, size: number) => {
471
+ let result: any = [];
472
+ for (let i = 0; i < array.length; i += size) {
473
+ result.push(array.slice(i, i + size));
474
+ }
475
+ return result;
476
+ }
477
+
478
+ export const sleep = (ms: number) => {
479
+ return new Promise((resolve) => setTimeout(resolve, ms));
480
+ }
481
+
482
+ export const formatAddr = (addr: string, force_full_addr: boolean = true) => {
483
+ if (force_full_addr) {
484
+ return addr;
485
+ }
486
+
487
+ if (addr.startsWith("0x")) {
488
+ return addr.slice(0, 8) + "..." + addr.slice(-6);
489
+ }
490
+
491
+ return addr.slice(0, 6) + "..." + addr.slice(-6);
492
+ }
493
+
494
+ export const listWithLazyBalanceLoading = async (
495
+ options: string[],
496
+ is_evm: boolean,
497
+ keystore_path: string,
498
+ asset_info_list: any,
499
+ network_info: any,
500
+ show_gas_token: boolean,
501
+ show_extended_token: boolean,
502
+ message?: string,
503
+ default_account?: any
504
+ ) => {
505
+ const questions = [
506
+ {
507
+ type: 'list',
508
+ name: 'inputText',
509
+ message: message || 'Choose an option',
510
+ choices: options,
511
+ pageSize: 30,
512
+ default: default_account,
513
+ filter: (val: string) => {
514
+ return val;
515
+ },
516
+ },
517
+ ];
518
+
519
+ const promise: any = inquirer.prompt(questions);
520
+
521
+ let selected = 0;
522
+ let round = 0;
523
+ let pre_selected: any;
524
+ while (!promise.ui.activePrompt.answers[promise.ui.activePrompt.opt.name]) {
525
+ await sleep(2000);
526
+ if (pre_selected === promise.ui.activePrompt.selected) {
527
+ continue;
528
+ }
529
+
530
+ if (selected === promise.ui.activePrompt.selected) {
531
+ round = round + 1;
532
+ } else {
533
+ round = 0;
534
+ selected = promise.ui.activePrompt.selected;
535
+ }
536
+
537
+ if (round < 5) {
538
+ continue;
539
+ }
540
+ round = 0;
541
+ const pageSize = promise.ui.activePrompt.opt.pageSize;
542
+
543
+ let accounts: any = [];
544
+ for (let i = 0; i < promise.ui.activePrompt.opt.choices.choices.length; i++) {
545
+ if (!promise.ui.activePrompt.opt.choices.choices[i].name) {
546
+ accounts.push(null);
547
+ continue;
548
+ }
549
+
550
+ let account: any = null;
551
+
552
+ if (is_evm) {
553
+ account = /0x[0-9a-fA-f]{40}/.exec(promise.ui.activePrompt.opt.choices.choices[i].name);
554
+ account = account ? account[0] : null;
555
+ } else {
556
+ let re_result = account = /\s+([0-9a-zA-Z]*)/.exec(promise.ui.activePrompt.opt.choices.choices[i].name);
557
+ account = re_result ? re_result[1] : null;
558
+
559
+ if (account === "Back") {
560
+ account = null;
561
+ }
562
+ }
563
+
564
+ if (account) {
565
+ accounts.push(account)
566
+ } else {
567
+ accounts.push(null);
568
+ }
569
+ }
570
+ accounts = accounts.concat(accounts);
571
+ let fromIndex: number, toIndex: number;
572
+ if (selected < pageSize / 2) {
573
+ if (accounts.length / 2 <= pageSize) {
574
+ fromIndex = 0;
575
+ toIndex = accounts.length / 2;
576
+ } else {
577
+ fromIndex = 0;
578
+ toIndex = pageSize;
579
+ }
580
+ } else {
581
+ if (accounts.length / 2 <= pageSize) {
582
+ fromIndex = 0;
583
+ toIndex = accounts.length / 2;
584
+ } else {
585
+ fromIndex = selected - pageSize / 2 + 1;
586
+ toIndex = selected + pageSize / 2 + 1;
587
+ }
588
+ }
589
+
590
+ let active_account: any = accounts.slice(fromIndex, toIndex);
591
+ let batchBalanceOf = await getBatchAccountBalance(
592
+ keystore_path,
593
+ active_account,
594
+ asset_info_list,
595
+ network_info.rpcUrl,
596
+ network_info.name,
597
+ show_gas_token,
598
+ show_extended_token
599
+ );
600
+
601
+ let gas_token_name = network_info.nativeCurrency.symbol;
602
+ for (let i = fromIndex; i < toIndex; i++) {
603
+ let _index = i >= accounts.length / 2 ? i - accounts.length / 2 : i;
604
+ let _choice = promise.ui.activePrompt.opt.choices.choices[_index];
605
+ if (!_choice.name) {
606
+ continue;
607
+ }
608
+
609
+ let name = _choice.name;
610
+ let account_address = accounts[i];
611
+ let token_message = '';
612
+
613
+ for (let token_name in batchBalanceOf[account_address]) {
614
+ if (!show_gas_token && token_name === gas_token_name) {
615
+ continue;
616
+ }
617
+ if (!show_extended_token && token_name !== gas_token_name) {
618
+ continue;
619
+ }
620
+
621
+ if (name.includes(token_name)) {
622
+ continue;
623
+ }
624
+
625
+ token_message += `${token_name}: ${batchBalanceOf[account_address][token_name]} `;
626
+ }
627
+
628
+ let nameList = name.split('(');
629
+ if (nameList.length > 1) {
630
+ let tag = nameList[1];
631
+ promise.ui.activePrompt.opt.choices.choices[_index].name = nameList[0] + ` ${token_message}` + `(${tag}`;
632
+ } else {
633
+ promise.ui.activePrompt.opt.choices.choices[_index].name = nameList[0] + ` ${token_message}`;
634
+ }
635
+ }
636
+ promise.ui.activePrompt.screen.render('');
637
+ promise.ui.activePrompt.render();
638
+ pre_selected = selected;
639
+ }
640
+
641
+ return promise.ui.activePrompt.answers[promise.ui.activePrompt.opt.name];
642
+ }
643
+
644
+ export const updateStorage = (keystore_path: string) => {
645
+ const network_path = path.resolve(keystore_path, 'network.json');
646
+ const networks = JSON.parse(fs.readFileSync(network_path, 'utf8'));
647
+
648
+ if (!networks.status) {
649
+ networks.status = {
650
+ fullAddr: true,
651
+ gasToken: false,
652
+ extendedToken: false
653
+ }
654
+ }
655
+
656
+ fs.writeFileSync(network_path, JSON.stringify(networks, null, 4));
657
+ let account_label_list = networks.accounts;
658
+
659
+ for (let i = 0; i < account_label_list.length; i++) {
660
+ let account_label_path = path.resolve(keystore_path, `accounts/${account_label_list[i]}.json`);
661
+ let account_info = JSON.parse(fs.readFileSync(account_label_path, 'utf8'));
662
+ if (account_info.account_type === "PP") {
663
+ continue;
664
+ }
665
+ if ("data" in account_info) {
666
+ continue;
667
+ }
668
+ account_info.data = [
669
+ {
670
+ ciphertexts: account_info.ciphertexts
671
+ }
672
+ ];
673
+ delete account_info.ciphertexts;
674
+ fs.writeFileSync(account_label_path, JSON.stringify(account_info, null, 4));
675
+ }
446
676
  }
package/src/web3.ts CHANGED
@@ -1,8 +1,11 @@
1
1
  import Web3 from 'web3';
2
- import { excutePromiseFunction } from './utils';
2
+ import { chunkArray, excutePromiseFunction, sleep } from './utils';
3
3
  import { Connection, PublicKey } from "@solana/web3.js";
4
4
  import { getMint, getAssociatedTokenAddressSync } from "@solana/spl-token"
5
- import { Metaplex } from "@metaplex-foundation/js";
5
+ import { Metaplex, token } from "@metaplex-foundation/js";
6
+ import { BigNumber } from "bignumber.js";
7
+
8
+ const chainIdAccountBalanceMap: any = {};
6
9
 
7
10
  export const getChainIdByEvm = async (rpc_url: string) => {
8
11
  let web3 = new Web3(rpc_url);
@@ -265,4 +268,101 @@ export const getAccountInfoInSolana = async (account: string, rpc_url: string) =
265
268
  status: true,
266
269
  output: result.output
267
270
  }
271
+ }
272
+
273
+ export const updateBalance = async (account_address_list: string[], token_address: string, chain_id: string, rpc_url: string, is_evm: boolean) => {
274
+ let accountBalanceMap: any;
275
+ if (chain_id in chainIdAccountBalanceMap) {
276
+ accountBalanceMap = chainIdAccountBalanceMap[chain_id][token_address] || {};
277
+ } else {
278
+ chainIdAccountBalanceMap[chain_id] = {};
279
+ accountBalanceMap = {};
280
+ }
281
+
282
+ for (const account of account_address_list) {
283
+ if (!account) {
284
+ continue;
285
+ }
286
+
287
+ if (!(account in accountBalanceMap)) {
288
+ let result: any;
289
+ if (token_address === "0") {
290
+ if (is_evm) {
291
+ result = await getAccountBalanceInEvm(account, rpc_url);
292
+ } else {
293
+ result = await getAccountBalanceInSolana(account, rpc_url);
294
+ }
295
+ } else {
296
+ if (is_evm) {
297
+ result = await getTokenBalanceInEvm(account, token_address, rpc_url);
298
+
299
+ } else {
300
+ result = await getTokenBalanceInSolana(account, token_address, rpc_url);
301
+ }
302
+ }
303
+
304
+ if (result.status) {
305
+ accountBalanceMap[account] = result.output;
306
+ }
307
+ await sleep(200);
308
+ }
309
+ }
310
+
311
+ chainIdAccountBalanceMap[chain_id][token_address] = accountBalanceMap;
312
+
313
+ return chainIdAccountBalanceMap;
314
+ }
315
+
316
+ export const getTokenBalance = (
317
+ chain_id: string,
318
+ account_address_list: any,
319
+ asset_info_list: any,
320
+ network_info: any
321
+ ) => {
322
+ let batchAccountBalanceOf: any = {};
323
+
324
+ if (!(chain_id in chainIdAccountBalanceMap)) {
325
+ return batchAccountBalanceOf;
326
+ }
327
+
328
+ asset_info_list.unshift({
329
+ address: "0",
330
+ name: network_info.nativeCurrency.name,
331
+ symbol: network_info.nativeCurrency.symbol,
332
+ decimals: network_info.nativeCurrency.decimals,
333
+ display_decimals: 4
334
+ });
335
+ let account_address_list_len = account_address_list.length;
336
+ for (let i = 0; i < account_address_list_len; i++) {
337
+ let account_address = account_address_list[i];
338
+
339
+ if (!account_address) {
340
+ continue;
341
+ }
342
+
343
+ for (let j = 0; j < asset_info_list.length; j++) {
344
+ let asset_info = asset_info_list[j];
345
+ let token_balance = "0";
346
+ if (!chainIdAccountBalanceMap[chain_id][asset_info.address]) {
347
+ continue;
348
+ }
349
+
350
+ if (account_address in chainIdAccountBalanceMap[chain_id][asset_info.address]) {
351
+ let balance = new BigNumber(chainIdAccountBalanceMap[chain_id][asset_info.address][account_address]);
352
+ token_balance = balance.dividedBy(10 ** asset_info.decimals).toFixed(asset_info.display_decimals || 4, BigNumber.ROUND_FLOOR);
353
+ }
354
+ if (!batchAccountBalanceOf[account_address]) {
355
+ batchAccountBalanceOf[account_address] = {};
356
+ }
357
+ batchAccountBalanceOf[account_address][asset_info.symbol] = token_balance;
358
+ }
359
+ }
360
+
361
+ return batchAccountBalanceOf;
362
+ }
363
+
364
+ export const deleteTokenBalance = (chain_id: string, account_address: string, token_address: string) => {
365
+ try {
366
+ delete chainIdAccountBalanceMap[chain_id][token_address][account_address];
367
+ } catch (error) { }
268
368
  }
package/rollup.config.js DELETED
@@ -1,30 +0,0 @@
1
- import { terser } from 'rollup-plugin-terser';
2
- import commonjs from '@rollup/plugin-commonjs';
3
- import typescript from 'rollup-plugin-typescript2';
4
-
5
- export default {
6
- input: 'src/index.ts',
7
- output: [
8
- {
9
- file: 'lib/index.esm.js',
10
- format: 'es',
11
- },
12
- {
13
- file: 'lib/index.umd.js',
14
- format: 'umd',
15
- name: 'demo',
16
- },
17
- ],
18
- plugins: [
19
- terser(),
20
- commonjs(),
21
- typescript({
22
- tsconfigOverride: {
23
- compilerOptions: {
24
- module: "ESNext"
25
- },
26
- include: ['src/**/*'],
27
- },
28
- })
29
- ]
30
- };