@yerofey/cryptowallet-cli 1.9.0 → 1.10.0

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/README.md CHANGED
@@ -150,6 +150,7 @@ $ cw -l
150
150
  - [ ] v17.x ⛔
151
151
  - [x] v18.x ✅
152
152
  - [x] v19.x ✅
153
+ - [x] v20.x ✅
153
154
 
154
155
  *tested on Mac M1*
155
156
 
package/cli.js CHANGED
@@ -1,52 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
3
 
4
- import { program } from 'commander';
5
4
  import chalk from 'chalk';
5
+ import { options } from './src/options.js';
6
6
  import { log, supportedChains } from './src/utils.js';
7
7
  import Method from './src/Method.js';
8
8
 
9
- program.option('-b, --chain <ticker>', 'Wallet for specific blockchain', 'ERC');
10
- program.option('-c, --chain <ticker>', 'Wallet for specific blockchain', 'ERC');
11
- program.option(
12
- '-D, --csv [filename]',
13
- 'Save result into CSV file'
14
- );
15
- program.option(
16
- '-f, --format <format>',
17
- 'Wallet format type (for cryptos with multiple wallet formats)'
18
- );
19
- program.option(
20
- '-F, --filename <filename>',
21
- 'Filename to output the data (works with -o argument)'
22
- );
23
- program.option('-g, --geek', 'Display some more info (geeky)');
24
- program.option('-l, --list', 'List all supported cryptos');
25
- program.option(
26
- '-m, --mnemonic [mnemonic]',
27
- 'Generate wallet from mnemonic string OR just a mnemonic string'
28
- );
29
- program.option(
30
- '-n, --number <number>',
31
- 'Number of wallets to generate (if supported)'
32
- );
33
- program.option('-o, --output <format>', 'Return results into some file');
34
- program.option('-p, --prefix <prefix>', 'Desired wallet prefix');
35
- program.option(
36
- '-P, --prefix-sensitive <prefix>',
37
- 'Desired wallet prefix (case-sensitive)'
38
- );
39
- program.option('-s, --suffix <suffix>', 'Desired wallet suffix');
40
- program.option(
41
- '-S, --suffix-sensitive <suffix>',
42
- 'Desired wallet suffix (case-sensitive)'
43
- );
44
- program.option('-v, --version', 'Display cryptowallet version');
45
- program.parse();
46
-
47
9
  (async () => {
48
- const options = program.opts();
49
-
50
10
  if (options.list !== undefined) {
51
11
  return new Method('list').init();
52
12
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yerofey/cryptowallet-cli",
3
- "version": "1.9.0",
3
+ "version": "1.10.0",
4
4
  "description": "Crypto wallet generator CLI tool",
5
5
  "type": "module",
6
6
  "homepage": "https://github.com/yerofey/cryptowallet-cli",
@@ -66,26 +66,26 @@
66
66
  "wallet generation"
67
67
  ],
68
68
  "dependencies": {
69
- "@binance-chain/javascript-sdk": "^4.2.0",
69
+ "@binance-chain/javascript-sdk": "^4.2.1",
70
70
  "@harmony-js/account": "^0.1.58",
71
71
  "@yerofey/dogecoin-bip84": "^0.0.5",
72
72
  "@yerofey/litecoin-bip84": "^0.0.5",
73
- "bip39": "3.0.4",
73
+ "bip39": "3.1.0",
74
74
  "bip84": "0.2.7",
75
- "chalk": "5.2.0",
75
+ "chalk": "5.3.0",
76
76
  "coininfo": "5.2.1",
77
77
  "coinkey": "3.0.0",
78
78
  "columnify": "1.6.0",
79
- "commander": "10.0.0",
79
+ "commander": "11.0.0",
80
80
  "csv-writer": "^1.6.0",
81
81
  "eth-lib": "0.1.29",
82
82
  "ethereum-bip84": "0.0.3",
83
83
  "ethereum-mnemonic-privatekey-utils": "1.0.5",
84
84
  "tezos-sign": "1.4.1",
85
- "tronweb": "5.0.0"
85
+ "tronweb": "5.3.0"
86
86
  },
87
87
  "devDependencies": {
88
- "ava": "^5.2.0",
89
- "eslint": "^8.34.0"
88
+ "ava": "^5.3.1",
89
+ "eslint": "^8.46.0"
90
90
  }
91
91
  }
package/src/CW.js CHANGED
@@ -3,11 +3,17 @@ import { Wallet } from './Wallet.js';
3
3
 
4
4
  class CW {
5
5
  constructor(chain, options = {}) {
6
+ this.chain = chain;
7
+ this.options = this._prepareOptions(chain, options);
8
+ }
9
+
10
+ _prepareOptions(chain, options) {
6
11
  const csvFilename = 'cw-output';
12
+
7
13
  if (options.csv !== undefined) {
8
14
  options.output = 'csv';
9
15
 
10
- if (typeof options.csv === 'string' && (options.csv).length > 0) {
16
+ if (typeof options.csv === 'string' && options.csv.length > 0) {
11
17
  options.filename = options.csv;
12
18
  }
13
19
  }
@@ -26,15 +32,7 @@ class CW {
26
32
  suffixIsCaseSensitive: options.suffixSensitive !== undefined,
27
33
  };
28
34
 
29
- for (const key of Object.keys(defaultValues)) {
30
- // eslint-disable-next-line no-prototype-builtins
31
- if (!options.hasOwnProperty(key)) {
32
- options[key] = defaultValues[key];
33
- }
34
- }
35
-
36
- this.chain = chain;
37
- this.options = options;
35
+ return { ...defaultValues, ...options };
38
36
  }
39
37
 
40
38
  async init() {
@@ -42,10 +40,7 @@ class CW {
42
40
  this.row = chainData.row || {};
43
41
 
44
42
  const w = await new Wallet(this).init();
45
-
46
- for (const key of Object.keys(w)) {
47
- this[key] = w[key];
48
- }
43
+ Object.assign(this, w);
49
44
 
50
45
  return this;
51
46
  }
package/src/Chain.js CHANGED
@@ -2,38 +2,43 @@ import path from 'node:path';
2
2
  import { loadJson } from './utils.js';
3
3
 
4
4
  class Chain {
5
- constructor(chain, format) {
5
+ constructor(chain, format = '') {
6
6
  this.chain = chain;
7
7
  this.format = format;
8
+ this.row = null;
8
9
  }
9
10
 
10
11
  async init() {
11
- // eslint-disable-next-line no-undef
12
- const content = await loadJson(`${path.dirname(import.meta.url)}/chains/${this.chain}.json`.replace('file://', ''));
13
- const data = (() => {
14
- if (content.formats !== undefined) {
15
- if (this.format != '' && this.format != content.defaultFormat) {
16
- // case-insensitive format
17
- for (const key of Object.keys(content.formats)) {
18
- if (this.format.toLowerCase() == key.toLowerCase()) {
19
- return content.formats[key];
20
- }
21
- }
22
- }
23
-
24
- return content.formats[content.defaultFormat];
25
- }
26
-
27
- return content;
28
- })();
29
-
30
- this.row = {
31
- ...content,
32
- ...data,
33
- };
34
-
12
+ const content = await this._loadChainJson();
13
+ this.row = this._parseContent(content);
35
14
  return this;
36
15
  }
16
+
17
+ async _loadChainJson() {
18
+ const filePath = `${path.dirname(import.meta.url)}/chains/${
19
+ this.chain
20
+ }.json`.replace('file://', '');
21
+ return await loadJson(filePath);
22
+ }
23
+
24
+ _parseContent(content) {
25
+ if (!content.formats) return content;
26
+
27
+ const formatKey = this._findFormatKey(content);
28
+ return { ...content, ...content.formats[formatKey] };
29
+ }
30
+
31
+ _findFormatKey(content) {
32
+ if (!this.format || this.format === content.defaultFormat)
33
+ return content.defaultFormat;
34
+
35
+ const normalizedFormat = this.format.toLowerCase();
36
+ const matchingKey = Object.keys(content.formats).find(
37
+ (key) => key.toLowerCase() === normalizedFormat
38
+ );
39
+
40
+ return matchingKey || content.defaultFormat;
41
+ }
37
42
  }
38
43
 
39
44
  export default Chain;
package/src/Method.js CHANGED
@@ -1,5 +1,11 @@
1
1
  import path from 'node:path';
2
2
  import chalk from 'chalk';
3
+ import columnify from 'columnify';
4
+ import CsvWriter from 'csv-writer';
5
+ import { log, supportedChains, loadJson } from './utils.js';
6
+ import { generateMnemonicString } from './Wallet.js';
7
+ import CW from './CW.js';
8
+
3
9
  const {
4
10
  blue,
5
11
  green,
@@ -10,366 +16,372 @@ const {
10
16
  magenta,
11
17
  white,
12
18
  } = chalk;
13
- import columnify from 'columnify';
14
- import CsvWriter from 'csv-writer';
15
- import {
16
- log,
17
- supportedChains,
18
- loadJson,
19
- } from './utils.js';
20
- import { generateMnemonicString } from './Wallet.js';
21
- import CW from './CW.js';
22
- const pkg = await loadJson(`${path.dirname(import.meta.url)}/../package.json`.replace('file://', ''));
23
- // eslint-disable-next-line no-undef
19
+
20
+ const pkg = await loadJson(
21
+ `${path.dirname(import.meta.url)}/../package.json`.replace('file://', '')
22
+ );
24
23
  const _version = pkg['version'] || 0;
25
24
 
26
25
  class Method {
27
26
  constructor(name, params = {}) {
28
27
  this.name = name;
29
28
  this.params = params;
29
+ this.callMethods = this._initializeMethods();
30
30
  }
31
31
 
32
- async init() {
33
- const callMethod = {
32
+ _initializeMethods() {
33
+ return {
34
34
  _: () => {},
35
- list: async () => {
36
- log(`🔠 All supported blockchains:\n`);
37
- let cryptos = {};
38
- for (const val of supportedChains) {
39
- // eslint-disable-next-line no-undef
40
- const data = await loadJson(`${path.dirname(import.meta.url)}/chains/${val}.json`.replace('file://', ''));
35
+ list: this._list.bind(this),
36
+ mnemonic: this._mnemonic.bind(this),
37
+ version: this._version.bind(this),
38
+ wallet: this._wallet.bind(this),
39
+ };
40
+ }
41
41
 
42
- let title = data.title || '';
43
- if (title == '' || val == 'ERC') {
44
- continue;
45
- }
46
- cryptos[blue(val)] = title;
47
- }
42
+ async _list() {
43
+ log(`🔠 All supported blockchains:\n`);
44
+ let cryptos = {};
45
+ for (const val of supportedChains) {
46
+ // eslint-disable-next-line no-undef
47
+ const data = await loadJson(
48
+ `${path.dirname(import.meta.url)}/chains/${val}.json`.replace(
49
+ 'file://',
50
+ ''
51
+ )
52
+ );
53
+
54
+ let title = data.title || '';
55
+ if (title == '' || val == 'ERC') {
56
+ continue;
57
+ }
58
+ cryptos[blue(val)] = title;
59
+ }
60
+ log(
61
+ columnify(cryptos, {
62
+ showHeaders: false,
63
+ columnSplitter: ' - ',
64
+ })
65
+ );
66
+ log();
67
+ log(`ℹ️ Use flag "-c TICKER" to select specific blockchain`);
68
+ }
69
+
70
+ _mnemonic() {
71
+ log(
72
+ `✨ ${green('Done!')} ${blueBright(
73
+ 'Here is your randomly generated 12 words mnemonic string:'
74
+ )}\n`
75
+ );
76
+ log(`📄 ${generateMnemonicString()}`);
77
+ log();
78
+ log(
79
+ greenBright(
80
+ 'ℹ️ You can import this wallet into MetaMask, Trust Wallet and many other wallet apps'
81
+ )
82
+ );
83
+ }
84
+
85
+ _version() {
86
+ log(_version);
87
+ }
88
+
89
+ async _wallet() {
90
+ const chain = this.params.chain;
91
+ const options = this.params.options;
92
+
93
+ const cw = await new CW(chain, options).init();
94
+
95
+ let chainFullName =
96
+ (cw.row.name || chain) +
97
+ (cw.wallet.format !== undefined && cw.wallet.format != ''
98
+ ? ' (' + cw.wallet.format + ')'
99
+ : '');
100
+
101
+ if (cw.options.prefix && !cw.prefixFound) {
102
+ log(
103
+ `😢 ${yellow(
104
+ 'Sorry, ' + chainFullName + ' does not support prefix yet...'
105
+ )}`
106
+ );
107
+ }
108
+
109
+ if (cw.options.suffix && !cw.suffixFound) {
110
+ log(
111
+ `😢 ${yellow(
112
+ 'Sorry, ' + chainFullName + ' does not support suffix yet...'
113
+ )}`
114
+ );
115
+ }
116
+
117
+ if (cw.options.mnemonic != '' && cw.wallet.mnemonic == undefined) {
118
+ log(
119
+ `😢 ${yellow(
120
+ 'Sorry, ' + chainFullName + ' does not support mnemonic yet...'
121
+ )}`
122
+ );
123
+ }
124
+
125
+ if (cw.wallet.error !== undefined) {
126
+ log(`⛔️ ${red(`Error: ${cw.wallet.error}`)}`);
127
+ return;
128
+ }
129
+
130
+ let linesCount = 0;
131
+ const outputFormats = ['csv'];
132
+ const displayAsText =
133
+ cw.options.output === undefined ||
134
+ !outputFormats.includes(cw.options.output);
135
+
136
+ // prefix, suffix
137
+ if (displayAsText) {
138
+ if (cw.prefixFound && cw.suffixFound) {
48
139
  log(
49
- columnify(cryptos, {
50
- showHeaders: false,
51
- columnSplitter: ' - ',
52
- })
140
+ `✨ ${green('Done!')} ${blueBright(
141
+ 'Here is your brand new ' +
142
+ chainFullName +
143
+ ' wallet with "' +
144
+ cw.options.prefix +
145
+ '" prefix and "' +
146
+ cw.options.suffix +
147
+ '" suffix:'
148
+ )}\n`
53
149
  );
54
- log();
55
- log(`ℹ️ Use flag "-c TICKER" to select specific blockchain`);
56
- },
57
- mnemonic: () => {
150
+ } else if (cw.prefixFound) {
58
151
  log(
59
152
  `✨ ${green('Done!')} ${blueBright(
60
- 'Here is your randomly generated 12 words mnemonic string:'
153
+ 'Here is your brand new ' +
154
+ chainFullName +
155
+ ' wallet with "' +
156
+ cw.options.prefix +
157
+ '" prefix:'
61
158
  )}\n`
62
159
  );
63
- log(`📄 ${generateMnemonicString()}`);
64
- log();
160
+ } else if (cw.suffixFound) {
65
161
  log(
66
- greenBright(
67
- 'ℹ️ You can import this wallet into MetaMask, Trust Wallet and many other wallet apps'
68
- )
162
+ `✨ ${green('Done!')} ${blueBright(
163
+ 'Here is your brand new ' +
164
+ chainFullName +
165
+ ' wallet with "' +
166
+ cw.options.suffix +
167
+ '" suffix:'
168
+ )}\n`
69
169
  );
70
- },
71
- version: () => {
72
- log(_version);
73
- },
74
- wallet: async () => {
75
- const chain = this.params.chain;
76
- const options = this.params.options;
77
-
78
- const cw = await new CW(chain, options).init();
79
-
80
- let chainFullName =
81
- (cw.row.name || chain) +
82
- (cw.wallet.format !== undefined && cw.wallet.format != ''
83
- ? ' (' + cw.wallet.format + ')'
84
- : '');
85
-
86
- if (cw.options.prefix && !cw.prefixFound) {
87
- log(
88
- `😢 ${yellow(
89
- 'Sorry, ' + chainFullName + ' does not support prefix yet...'
90
- )}`
91
- );
92
- }
93
-
94
- if (cw.options.suffix && !cw.suffixFound) {
95
- log(
96
- `😢 ${yellow(
97
- 'Sorry, ' + chainFullName + ' does not support suffix yet...'
98
- )}`
99
- );
100
- }
101
-
102
- if (cw.options.mnemonic != '' && cw.wallet.mnemonic == undefined) {
103
- log(
104
- `😢 ${yellow(
105
- 'Sorry, ' + chainFullName + ' does not support mnemonic yet...'
106
- )}`
107
- );
108
- }
109
-
110
- if (cw.wallet.error !== undefined) {
111
- log(`⛔️ ${red(`Error: ${cw.wallet.error}`)}`);
112
- return;
113
- }
170
+ } else {
171
+ log(
172
+ `✨ ${green('Done!')} ${blueBright(
173
+ 'Here is your brand new ' + chainFullName + ' wallet:'
174
+ )}\n`
175
+ );
176
+ }
177
+ linesCount += 1;
178
+ }
114
179
 
115
- let linesCount = 0;
116
- const outputFormats = ['csv'];
117
- const displayAsText =
118
- cw.options.output === undefined ||
119
- !outputFormats.includes(cw.options.output);
180
+ // result
181
+ let outputData = {};
182
+ if (cw.wallet.addresses !== undefined) {
183
+ // private key
184
+ if (cw.wallet.privateExtendedKey && cw.options.geek) {
185
+ log(`🔐 ${cw.wallet.privateExtendedKey}`);
186
+ linesCount += 1;
187
+ }
188
+ // mnemonic
189
+ if (cw.wallet.mnemonic) {
190
+ log(`📄 ${cw.wallet.mnemonic}`);
191
+ linesCount += 1;
192
+ }
193
+ // addresses
194
+ if (displayAsText) {
195
+ for (const item of cw.wallet.addresses) {
196
+ if (cw.wallet.addresses.length > 1) {
197
+ log();
198
+ log(`🆔 ${item.index}`);
199
+ }
120
200
 
121
- // prefix, suffix
122
- if (displayAsText) {
123
- if (cw.prefixFound && cw.suffixFound) {
124
- log(
125
- `✨ ${green('Done!')} ${blueBright(
126
- 'Here is your brand new ' +
127
- chainFullName +
128
- ' wallet with "' +
129
- cw.options.prefix +
130
- '" prefix and "' +
131
- cw.options.suffix +
132
- '" suffix:'
133
- )}\n`
201
+ if (
202
+ cw.prefixFound &&
203
+ cw.prefixFoundInWallets.includes(item.address) &&
204
+ cw.suffixFound &&
205
+ cw.suffixFoundInWallets.includes(item.address)
206
+ ) {
207
+ // highlight found prefix
208
+ const addressCutPrefixLength =
209
+ cw.row.startsWith.length + cw.options.prefix.length;
210
+ const addressFirstPart = item.address.slice(
211
+ cw.row.startsWith.length,
212
+ addressCutPrefixLength
213
+ );
214
+ const addressLastPart = item.address.slice(
215
+ item.address.length - cw.options.suffix.length
134
216
  );
135
- } else if (cw.prefixFound) {
136
217
  log(
137
- `✨ ${green('Done!')} ${blueBright(
138
- 'Here is your brand new ' +
139
- chainFullName +
140
- ' wallet with "' +
141
- cw.options.prefix +
142
- '" prefix:'
143
- )}\n`
218
+ `👛 ${cw.row.startsWith}${magenta(
219
+ addressFirstPart
220
+ )}${item.address.substring(
221
+ cw.row.startsWith.length + addressFirstPart.length,
222
+ item.address.length - addressLastPart.length
223
+ )}${magenta(addressLastPart)}`
144
224
  );
145
- } else if (cw.suffixFound) {
225
+ } else if (
226
+ cw.prefixFound &&
227
+ cw.prefixFoundInWallets.includes(item.address)
228
+ ) {
229
+ // highlight found prefix
230
+ const addressCutLength =
231
+ cw.row.startsWith.length + cw.options.prefix.length;
146
232
  log(
147
- `✨ ${green('Done!')} ${blueBright(
148
- 'Here is your brand new ' +
149
- chainFullName +
150
- ' wallet with "' +
151
- cw.options.suffix +
152
- '" suffix:'
153
- )}\n`
233
+ `👛 ${cw.row.startsWith}${magenta(
234
+ item.address.slice(cw.row.startsWith.length, addressCutLength)
235
+ )}${item.address.slice(addressCutLength)}`
154
236
  );
155
- } else {
237
+ } else if (
238
+ cw.suffixFound &&
239
+ cw.suffixFoundInWallets.includes(item.address)
240
+ ) {
241
+ // highlight found suffix
156
242
  log(
157
- `✨ ${green('Done!')} ${blueBright(
158
- 'Here is your brand new ' + chainFullName + ' wallet:'
159
- )}\n`
243
+ `👛 ${item.address.slice(
244
+ 0,
245
+ item.address.length - cw.options.suffix.length
246
+ )}${magenta(
247
+ item.address.slice(
248
+ item.address.length - cw.options.suffix.length
249
+ )
250
+ )}`
160
251
  );
252
+ } else {
253
+ log(`👛 ${item.address}`);
161
254
  }
162
- linesCount += 1;
255
+ log(`🔑 ${item.privateKey}`);
163
256
  }
257
+ } else {
258
+ outputData.wallets = cw.wallet.addresses;
259
+ }
164
260
 
165
- // result
166
- let outputData = {};
167
- if (cw.wallet.addresses !== undefined) {
168
- // private key
169
- if (cw.wallet.privateExtendedKey && cw.options.geek) {
170
- log(`🔐 ${cw.wallet.privateExtendedKey}`);
171
- linesCount += 1;
172
- }
173
- // mnemonic
174
- if (cw.wallet.mnemonic) {
175
- log(`📄 ${cw.wallet.mnemonic}`);
176
- linesCount += 1;
177
- }
178
- // addresses
179
- if (displayAsText) {
180
- for (const item of cw.wallet.addresses) {
181
- if (cw.wallet.addresses.length > 1) {
182
- log();
183
- log(`🆔 ${item.index}`);
184
- }
261
+ if (displayAsText && cw.row.path !== undefined && cw.options.geek) {
262
+ log();
263
+ log(`🗂 wallet address path: ${cw.row.path}'/0'/0/ID`);
264
+ linesCount += 1;
265
+ }
185
266
 
186
- if (
187
- cw.prefixFound &&
188
- cw.prefixFoundInWallets.includes(item.address) &&
189
- cw.suffixFound &&
190
- cw.suffixFoundInWallets.includes(item.address)
191
- ) {
192
- // highlight found prefix
193
- const addressCutPrefixLength =
194
- cw.row.startsWith.length + cw.options.prefix.length;
195
- const addressFirstPart = item.address.slice(
196
- cw.row.startsWith.length,
197
- addressCutPrefixLength
198
- );
199
- const addressLastPart = item.address.slice(
200
- item.address.length - cw.options.suffix.length
201
- );
202
- log(
203
- `👛 ${cw.row.startsWith}${magenta(
204
- addressFirstPart
205
- )}${item.address.substring(
206
- cw.row.startsWith.length + addressFirstPart.length,
207
- item.address.length - addressLastPart.length
208
- )}${magenta(addressLastPart)}`
209
- );
210
- } else if (
211
- cw.prefixFound &&
212
- cw.prefixFoundInWallets.includes(item.address)
213
- ) {
214
- // highlight found prefix
215
- const addressCutLength =
216
- cw.row.startsWith.length + cw.options.prefix.length;
217
- log(
218
- `👛 ${cw.row.startsWith}${magenta(
219
- item.address.slice(
220
- cw.row.startsWith.length,
221
- addressCutLength
222
- )
223
- )}${item.address.slice(addressCutLength)}`
224
- );
225
- } else if (
226
- cw.suffixFound &&
227
- cw.suffixFoundInWallets.includes(item.address)
228
- ) {
229
- // highlight found suffix
230
- log(
231
- `👛 ${item.address.slice(
232
- 0,
233
- item.address.length - cw.options.suffix.length
234
- )}${magenta(
235
- item.address.slice(
236
- item.address.length - cw.options.suffix.length
237
- )
238
- )}`
239
- );
240
- } else {
241
- log(`👛 ${item.address}`);
242
- }
243
- log(`🔑 ${item.privateKey}`);
267
+ // generate csv
268
+ if (!displayAsText) {
269
+ const filename =
270
+ cw.options.csvOutputFilename ||
271
+ cw.options.filename.split('.')[0] ||
272
+ 'cw-output';
273
+ // eslint-disable-next-line no-undef
274
+ const createCsvWriter = CsvWriter.createObjectCsvWriter;
275
+ const csvWriter = createCsvWriter({
276
+ path: `${filename}.csv`,
277
+ header: [
278
+ {
279
+ id: 'index',
280
+ title: 'index',
281
+ },
282
+ {
283
+ id: 'address',
284
+ title: 'address',
285
+ },
286
+ {
287
+ id: 'privateKey',
288
+ title: 'privateKey',
289
+ },
290
+ ],
291
+ });
292
+ csvWriter
293
+ .writeRecords(outputData.wallets)
294
+ .then(() =>
295
+ log(
296
+ `${linesCount > 0 ? '\n' : ''}🟠 ${yellow(
297
+ `Don't forget to save the data above manually, because it is not in the output file`
298
+ )} \n✨ ${green('Done!')} ${blueBright(
299
+ `The output successfully saved into "./${filename}.csv" file`
300
+ )}`
301
+ )
302
+ )
303
+ .catch(() =>
304
+ log(
305
+ `${linesCount > 0 ? '\n' : ''}⛔️ ${red(
306
+ `Error: failed to generate a file`
307
+ )}`
308
+ )
309
+ );
310
+ }
311
+ }
244
312
 
245
- }
246
- } else {
247
- outputData.wallets = cw.wallet.addresses;
248
- }
313
+ if (displayAsText) {
314
+ if (
315
+ cw.row.formats !== undefined ||
316
+ cw.row.network == 'EVM' ||
317
+ cw.row.apps ||
318
+ cw.wallet.tested !== undefined
319
+ ) {
320
+ log();
321
+ }
249
322
 
250
- if (displayAsText && cw.row.path !== undefined && cw.options.geek) {
251
- log();
252
- log(`🗂 wallet address path: ${cw.row.path}'/0'/0/ID`);
253
- linesCount += 1;
254
- }
323
+ if (cw.wallet.tested !== undefined) {
324
+ log(
325
+ red(
326
+ '‼️ This wallet generation format was not tested yet, do not use it!'
327
+ )
328
+ );
329
+ }
255
330
 
256
- // generate csv
257
- if (!displayAsText) {
258
- const filename = cw.options.csvOutputFilename || cw.options.filename.split('.')[0] || 'cw-output';
259
- // eslint-disable-next-line no-undef
260
- const createCsvWriter = CsvWriter.createObjectCsvWriter;
261
- const csvWriter = createCsvWriter({
262
- path: `${filename}.csv`,
263
- header: [
264
- {
265
- id: 'index',
266
- title: 'index',
267
- },
268
- {
269
- id: 'address',
270
- title: 'address',
271
- },
272
- {
273
- id: 'privateKey',
274
- title: 'privateKey',
275
- },
276
- ],
277
- });
278
- csvWriter
279
- .writeRecords(outputData.wallets)
280
- .then(() =>
281
- log(
282
- `${linesCount > 0 ? '\n' : ''}🟠 ${yellow(
283
- `Don't forget to save the data above manually, because it is not in the output file`
284
- )} \n✨ ${green('Done!')} ${blueBright(
285
- `The output successfully saved into "./${filename}.csv" file`
286
- )}`
287
- )
288
- )
289
- .catch(() =>
290
- log(
291
- `${linesCount > 0 ? '\n' : ''}⛔️ ${red(
292
- `Error: failed to generate a file`
293
- )}`
294
- )
295
- );
296
- }
331
+ if (
332
+ cw.row.formats !== undefined &&
333
+ Object.keys(cw.row.formats).length > 1
334
+ ) {
335
+ let formatsString = '';
336
+ for (const val of Object.keys(cw.row.formats)) {
337
+ formatsString += blue(val) + ', ';
297
338
  }
339
+ log(
340
+ yellow(
341
+ '*️⃣ You can create different wallet formats: ' +
342
+ formatsString.substring(0, formatsString.length - 2) +
343
+ ' (use it with ' +
344
+ white('-f') +
345
+ ' flag)'
346
+ )
347
+ );
348
+ }
298
349
 
299
- if (displayAsText) {
300
- if (
301
- cw.row.formats !== undefined ||
302
- cw.row.network == 'EVM' ||
303
- cw.row.apps ||
304
- cw.wallet.tested !== undefined
305
- ) {
306
- log();
307
- }
308
-
309
- if (cw.wallet.tested !== undefined) {
310
- log(
311
- red(
312
- '‼️ This wallet generation format was not tested yet, do not use it!'
313
- )
314
- );
315
- }
350
+ if (cw.row.network == 'EVM' || false) {
351
+ log(
352
+ yellow(
353
+ '🆒 You can use this wallet in Ethereum, Binance Smart Chain, Polygon and few more networks (EVM compatible)'
354
+ )
355
+ );
356
+ }
316
357
 
317
- if (
318
- cw.row.formats !== undefined &&
319
- Object.keys(cw.row.formats).length > 1
320
- ) {
321
- let formatsString = '';
322
- for (const val of Object.keys(cw.row.formats)) {
323
- formatsString += blue(val) + ', ';
324
- }
325
- log(
326
- yellow(
327
- '*️⃣ You can create different wallet formats: ' +
328
- formatsString.substring(0, formatsString.length - 2) +
329
- ' (use it with ' +
330
- white('-f') +
331
- ' flag)'
332
- )
333
- );
334
- }
358
+ if (cw.row.apps !== undefined) {
359
+ let apps = {
360
+ metamask: 'MetaMask',
361
+ tronlink: 'TronLink',
362
+ trustwallet: 'Trust Wallet',
363
+ 'harmony-chrome-ext': 'Harmony Chrome Extension Wallet',
364
+ 'binance-chain-wallet': 'Binance Chain Wallet',
365
+ };
366
+ let appsArray = [];
335
367
 
336
- if (cw.row.network == 'EVM' || false) {
337
- log(
338
- yellow(
339
- '🆒 You can use this wallet in Ethereum, Binance Smart Chain, Polygon and few more networks (EVM compatible)'
340
- )
341
- );
368
+ for (let key of Object.keys(apps)) {
369
+ if (cw.row.apps.includes(key)) {
370
+ appsArray.push(apps[key]);
342
371
  }
372
+ }
343
373
 
344
- if (cw.row.apps !== undefined) {
345
- let apps = {
346
- metamask: 'MetaMask',
347
- tronlink: 'TronLink',
348
- trustwallet: 'Trust Wallet',
349
- 'harmony-chrome-ext': 'Harmony Chrome Extension Wallet',
350
- 'binance-chain-wallet': 'Binance Chain Wallet',
351
- };
352
- let appsArray = [];
353
-
354
- for (let key of Object.keys(apps)) {
355
- if (cw.row.apps.includes(key)) {
356
- appsArray.push(apps[key]);
357
- }
358
- }
359
-
360
- let appsString = appsArray.join(', ');
361
- if (cw.row.apps || false) {
362
- appsString += ' and many other wallet apps';
363
- }
364
- log(
365
- greenBright('ℹ️ You can import this wallet into ' + appsString)
366
- );
367
- }
374
+ let appsString = appsArray.join(', ');
375
+ if (cw.row.apps || false) {
376
+ appsString += ' and many other wallet apps';
368
377
  }
369
- },
370
- };
378
+ log(greenBright('ℹ️ You can import this wallet into ' + appsString));
379
+ }
380
+ }
381
+ }
371
382
 
372
- return (callMethod[this.name] || callMethod['_'])();
383
+ async init() {
384
+ return (this.callMethods[this.name] || this.callMethods['_'])();
373
385
  }
374
386
  }
375
387
 
package/src/Wallet.js CHANGED
@@ -1,35 +1,24 @@
1
1
  import { log } from './utils.js';
2
2
  import chalk from 'chalk';
3
- const { red } = chalk;
4
3
  import CoinKey from 'coinkey';
5
4
  import CoinInfo from 'coininfo';
6
5
  import bip39 from 'bip39';
7
6
  import bip84 from 'bip84';
8
- const {
9
- fromMnemonic,
10
- fromZPrv,
11
- } = bip84;
7
+ const { fromMnemonic, fromZPrv } = bip84;
12
8
  import ethereumBip from 'ethereum-bip84';
13
- const {
14
- fromMnemonic: fromMnemonicEthereum,
15
- fromZPrv: fromZPrvEthereum,
16
- } = ethereumBip;
9
+ const { fromMnemonic: fromMnemonicEthereum, fromZPrv: fromZPrvEthereum } =
10
+ ethereumBip;
17
11
  import dogecoinBip from '@yerofey/dogecoin-bip84';
18
- const {
19
- fromMnemonic: fromMnemonicDoge,
20
- fromZPrv: fromZPrvDoge
21
- } = dogecoinBip;
12
+ const { fromMnemonic: fromMnemonicDoge, fromZPrv: fromZPrvDoge } = dogecoinBip;
22
13
  import litecoinBip from '@yerofey/litecoin-bip84';
23
- const {
24
- fromMnemonic: fromMnemonicLite,
25
- fromZPrv: fromZPrvLite,
26
- } = litecoinBip;
14
+ const { fromMnemonic: fromMnemonicLite, fromZPrv: fromZPrvLite } = litecoinBip;
27
15
  import { Account } from 'eth-lib/lib/index.js';
28
16
  import { Wallet as HarmonyWallet } from '@harmony-js/account';
29
17
  import pkutils from 'ethereum-mnemonic-privatekey-utils';
30
18
  import bCrypto from '@binance-chain/javascript-sdk/lib/crypto/index.js';
31
19
  import tronWeb from 'tronweb';
32
20
  import tezos from 'tezos-sign';
21
+ const { red } = chalk;
33
22
 
34
23
  class Wallet {
35
24
  constructor(cw) {
@@ -312,8 +301,9 @@ class Wallet {
312
301
  };
313
302
  }
314
303
 
315
- const _fromMnemonic = (chain == 'DOGE') ? fromMnemonicDoge : fromMnemonicLite;
316
- const _fromZPrv = (chain == 'DOGE') ? fromZPrvDoge : fromZPrvLite;
304
+ const _fromMnemonic =
305
+ chain == 'DOGE' ? fromMnemonicDoge : fromMnemonicLite;
306
+ const _fromZPrv = chain == 'DOGE' ? fromZPrvDoge : fromZPrvLite;
317
307
  const mnemonic = mnemonicString || bip39.generateMnemonic();
318
308
  const root = new _fromMnemonic(mnemonic, '');
319
309
  const child = root.deriveAccount(0);
@@ -487,7 +477,4 @@ function generateMnemonicString() {
487
477
  return bip39.generateMnemonic();
488
478
  }
489
479
 
490
- const _generateMnemonicString = generateMnemonicString;
491
- export { _generateMnemonicString as generateMnemonicString };
492
- const _Wallet = Wallet;
493
- export { _Wallet as Wallet };
480
+ export { generateMnemonicString, Wallet };
package/src/options.js ADDED
@@ -0,0 +1,43 @@
1
+ import { program } from 'commander';
2
+
3
+
4
+ program.option('-b, --chain <ticker>', 'Wallet for specific blockchain', 'ERC');
5
+ program.option('-c, --chain <ticker>', 'Wallet for specific blockchain', 'ERC');
6
+ program.option(
7
+ '-D, --csv [filename]',
8
+ 'Save result into CSV file'
9
+ );
10
+ program.option(
11
+ '-f, --format <format>',
12
+ 'Wallet format type (for cryptos with multiple wallet formats)'
13
+ );
14
+ program.option(
15
+ '-F, --filename <filename>',
16
+ 'Filename to output the data (works with -o argument)'
17
+ );
18
+ program.option('-g, --geek', 'Display some more info (geeky)');
19
+ program.option('-l, --list', 'List all supported cryptos');
20
+ program.option(
21
+ '-m, --mnemonic [mnemonic]',
22
+ 'Generate wallet from mnemonic string OR just a mnemonic string'
23
+ );
24
+ program.option(
25
+ '-n, --number <number>',
26
+ 'Number of wallets to generate (if supported)'
27
+ );
28
+ program.option('-o, --output <format>', 'Return results into some file');
29
+ program.option('-p, --prefix <prefix>', 'Desired wallet prefix');
30
+ program.option(
31
+ '-P, --prefix-sensitive <prefix>',
32
+ 'Desired wallet prefix (case-sensitive)'
33
+ );
34
+ program.option('-s, --suffix <suffix>', 'Desired wallet suffix');
35
+ program.option(
36
+ '-S, --suffix-sensitive <suffix>',
37
+ 'Desired wallet suffix (case-sensitive)'
38
+ );
39
+ program.option('-v, --version', 'Display cryptowallet version');
40
+ program.parse();
41
+
42
+ export const options = program.opts();
43
+ export const zeroOptions = Object.keys(options).length === 0;
package/src/utils.js CHANGED
@@ -21,12 +21,8 @@ const loadFile = async (filename, defaultValue = {}) => {
21
21
  };
22
22
 
23
23
  const loadJson = async (filename) => {
24
- return JSON.parse(
25
- await readFile(
26
- new URL(filename, import.meta.url)
27
- )
28
- );
29
- }
24
+ return JSON.parse(await readFile(new URL(filename, import.meta.url)));
25
+ };
30
26
 
31
27
  const objectHasAllKeys = (obj, keysArray) =>
32
28
  // eslint-disable-next-line no-prototype-builtins
@@ -34,17 +30,11 @@ const objectHasAllKeys = (obj, keysArray) =>
34
30
 
35
31
  let supportedChains = [];
36
32
  // eslint-disable-next-line no-undef
37
- const chainsFolder = `${path.dirname(decodeURIComponent(import.meta.url))}/chains/`.replace('file://', '');
38
- filesList(chainsFolder).forEach((item) => {
39
- const name = item.replace(chainsFolder, '').replace('.json', '');
40
- supportedChains.push(name);
41
- });
33
+ const chainsFolder = `${path.dirname(
34
+ decodeURIComponent(import.meta.url)
35
+ )}/chains/`.replace('file://', '');
36
+ supportedChains = filesList(chainsFolder).map((item) =>
37
+ item.replace(chainsFolder, '').replace('.json', '')
38
+ );
42
39
 
43
- const _log = log;
44
- export { _log as log };
45
- export { loadFile };
46
- export { loadJson };
47
- const _objectHasAllKeys = objectHasAllKeys;
48
- export { _objectHasAllKeys as objectHasAllKeys };
49
- const _supportedChains = supportedChains;
50
- export { _supportedChains as supportedChains };
40
+ export { log, loadFile, loadJson, objectHasAllKeys, supportedChains };