@yerofey/cryptowallet-cli 1.38.2 → 1.39.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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2021 Yerofey S.
3
+ Copyright (c) 2025 Yerofey S.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![Minimum Node.js version](https://badgen.net/npm/node/@yerofey/cryptowallet-cli)](https://npmjs.com/@yerofey/cryptowallet-cli)
5
5
  [![NPM package version](https://badgen.net/npm/v/@yerofey/cryptowallet-cli)](https://npmjs.com/package/@yerofey/cryptowallet-cli)
6
6
 
7
- > CW: crypto wallet generator CLI tool
7
+ > cw: crypto wallet generator CLI tool
8
8
 
9
9
  ![Screenshot](https://i.imgur.com/uWuT4lF.png)
10
10
 
@@ -44,7 +44,7 @@ $ bun add -g @yerofey/cryptowallet-cli
44
44
  ## Usage
45
45
 
46
46
  ```bash
47
- # generate random EVM-compatible wallet (for Ethereum, Polygon, any L1/L2 EVM-compatible chain, etc.)
47
+ # generate random EVM-compatible wallet (for Ethereum, Base, and any L1/L2/L3 EVM-compatible chain, etc.)
48
48
  $ cw
49
49
 
50
50
  # generate random wallet and copy the mnemonic to the clipboard
@@ -56,9 +56,6 @@ $ cw -c btc
56
56
  # generate random mnemonic string (12 words) to import in any wallet app
57
57
  $ cw -m
58
58
 
59
- # generate random wallet faster (use all available CPU cores)
60
- $ cw -t
61
-
62
59
  # generate random mnemonic string of a specific length (12, 15, 18, 21 or 24 words)
63
60
  $ cw -m 12
64
61
  $ cw -m 15
@@ -125,7 +122,7 @@ $ cw -l
125
122
 
126
123
  ## Blockchains & tickers supported
127
124
 
128
- - `EVM` (Ethereum, Base, Arbitrum, Optimism, Polygon, L2/L3, etc.) **default**
125
+ - `EVM` (Ethereum, Base, or any EVM L1/L2/L3, etc.) **default**
129
126
  - `BTC` (Bitcoin) [legacy, segwit, bech32, taproot]
130
127
  - `ETH` (Ethereum)
131
128
  - `SOL` (Solana)
@@ -156,11 +153,11 @@ $ cw -l
156
153
  - `NBT` (NIX Bridge Token)
157
154
  - `PLS` (PulseChain)
158
155
 
159
- *all other cryptos that are tokens in the ecosystems like Ethereum, Binance Smart Chain or Polygon and others chains are supported as well (L2/L3, etc.)*
156
+ *all other cryptos that are tokens in the ecosystems like Ethereum, Base, Binance Smart Chain and others chains are supported as well (L1/L2/L3, etc.)*
160
157
 
161
158
  ## Options
162
159
 
163
- - `-b` or `-c` or `--chain`: Specify the blockchain ticker to generate a wallet for
160
+ - `-c` or `--chain`: Specify the chain/coin ticker to generate a wallet for
164
161
  - `-C` or `--copy`: Copy the generated mnemonic to the clipboard
165
162
  - `-D` or `--csv`: Save output into CSV file with custom or default name ("`cw-output.csv`") - this is a shorthand for `-o csv -F filename`
166
163
  - `-f` or `--format`: Specify the blockchain wallet format (for BTC: legacy, segwit, bech32)
@@ -181,7 +178,7 @@ $ cw -l
181
178
  - `-S` or `--suffix-sensitive`: Specify desired suffix for the wallet address (**case-sensitive**)
182
179
  - `-t` or `--threads`: Use multiple threads (cores) for faster generation (default: half of the available cores), or pass `0` to use all available cores (not recommended for laptops)
183
180
  - `-q` or `--qr`: Display QR code with the generated wallet address (works only without `-n` argument)
184
- - `-v` or `--version`: Display current version of CW tool
181
+ - `-v` or `--version`: Display current version of `cw` tool
185
182
 
186
183
  **Currently not necessary options:**
187
184
 
package/cli.js CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
3
 
4
+ import { config } from 'dotenv';
4
5
  import os from 'node:os';
5
6
  import {
6
7
  Worker,
@@ -14,9 +15,37 @@ import { exit, log, supportedChains } from './src/utils.js';
14
15
  import Method from './src/Method.js';
15
16
  import chalk from 'chalk';
16
17
 
18
+ // load environment variables
19
+ config();
20
+
17
21
  // get the current file path
18
22
  const __filename = fileURLToPath(import.meta.url);
19
23
 
24
+ // check if the app is running in development mode
25
+ const isDev = process.env.NODE_ENV === 'development';
26
+
27
+ // check if there is a need for multi-threading
28
+ const isMultiThreaded =
29
+ options.prefix ||
30
+ options.suffix ||
31
+ options['suffix-sensitive'] ||
32
+ options['prefix-sensitive'] ||
33
+ options.threads ||
34
+ isMainThread ||
35
+ workerData ||
36
+ false;
37
+
38
+ // check if the mnemonic string is requested (not provided)
39
+ const isMnemonicString =
40
+ options.mnemonic &&
41
+ (options.mnemonic === true ||
42
+ options.mnemonic === '' ||
43
+ options.mnemonic.split(' ').length === 1);
44
+
45
+ // check if the wallet generation is enabled
46
+ const isWalletGeneration =
47
+ !isMnemonicString && !options.list && !options.version && !options.donate;
48
+
20
49
  // show all supported chains
21
50
  if (options.list) {
22
51
  (async () => {
@@ -25,13 +54,8 @@ if (options.list) {
25
54
  })();
26
55
  }
27
56
 
28
- // generate mnemonic string
29
- if (
30
- options.mnemonic &&
31
- (options.mnemonic === true ||
32
- options.mnemonic === '' ||
33
- options.mnemonic.split(' ').length === 1)
34
- ) {
57
+ // generate mnemonic string (12/15/18/21/24 words)
58
+ if (isMnemonicString) {
35
59
  (async () => {
36
60
  new Method('mnemonic').init({
37
61
  mnemonic: options.mnemonic,
@@ -63,7 +87,6 @@ if (!supportedChains.includes(chain)) {
63
87
  log(chalk.red('⛔️ Error: this chain is not supported!'));
64
88
  exit(1);
65
89
  }
66
- options.b = chain; // ensure the chain is passed to the Method class
67
90
 
68
91
  // multi-threads mode (only for suffix, prefix, number)
69
92
  const allMachineThreads = os.cpus().length;
@@ -79,112 +102,119 @@ if (inputThreads > availableThreads) {
79
102
  numThreads = inputThreads;
80
103
  }
81
104
 
82
- if (isMainThread) {
83
- if (numThreads === 1) {
84
- console.log(
85
- chalk.green(
86
- '🐢 Using only 1 thread to generate a wallet, this might take a while...'
87
- ),
88
- chalk.gray(`(pass "-t ${availableThreads}" to use all available threads)`)
89
- );
90
- } else {
91
- console.log(
92
- chalk.green(
93
- `⚡ Using ${numThreads}/${allMachineThreads} threads to generate a wallet...`
94
- ),
95
- chalk.gray(`(pass "-t ${availableThreads}" to use all available threads)`)
96
- );
97
- }
98
-
99
- const workers = [];
100
-
101
- // create a shared buffer to communicate between workers
102
- const sharedBuffer = new SharedArrayBuffer(4); // 4 bytes for the flag
103
- const sharedArray = new Int32Array(sharedBuffer);
104
- sharedArray[0] = 0; // 0 - not found, 1 - found
105
-
106
- for (let i = 0; i < numThreads; i++) {
107
- const worker = new Worker(__filename, {
108
- workerData: {
109
- workerId: i,
110
- totalWorkers: numThreads,
111
- chain,
112
- options: JSON.parse(JSON.stringify(options)),
113
- sharedBuffer,
114
- },
115
- stdout: true, // enable capturing stdout
116
- });
117
-
118
- // pipe worker stdout to main process
119
- worker.stdout.on('data', (data) => {
120
- if (Atomics.load(sharedArray, 0) === 0) {
121
- process.stdout.write(data); // forward stdout to main process
122
-
123
- return data;
124
- }
125
- });
105
+ // wallet generation
106
+ if (isMultiThreaded && isWalletGeneration) {
107
+ if (isMainThread) {
108
+ if (numThreads === 1) {
109
+ console.log(
110
+ chalk.cyan(
111
+ '🐢 Using only 1 thread to generate a wallet, this might take a while...'
112
+ ),
113
+ chalk.gray(
114
+ `(pass "-t ${availableThreads}" to use all available threads)`
115
+ )
116
+ );
117
+ } else {
118
+ console.log(
119
+ chalk.cyan(
120
+ `⚡ Using ${numThreads}/${allMachineThreads} threads to generate a wallet...`
121
+ ),
122
+ chalk.gray(
123
+ `(pass "-t ${availableThreads}" to use all available threads)`
124
+ )
125
+ );
126
+ }
126
127
 
127
- worker.on('message', (message) => {
128
- if (Atomics.load(sharedArray, 0) === 0) {
129
- // set the shared flag to 1 to stop all workers
130
- Atomics.store(sharedArray, 0, 1);
128
+ const workers = [];
129
+
130
+ // create a shared buffer to communicate between workers
131
+ const sharedBuffer = new SharedArrayBuffer(4); // 4 bytes for the flag
132
+ const sharedArray = new Int32Array(sharedBuffer);
133
+ sharedArray[0] = 0; // 0 - not found, 1 - found
134
+
135
+ for (let i = 0; i < numThreads; i++) {
136
+ const worker = new Worker(__filename, {
137
+ workerData: {
138
+ workerId: i,
139
+ totalWorkers: numThreads,
140
+ chain,
141
+ options: JSON.parse(JSON.stringify(options)),
142
+ sharedBuffer,
143
+ },
144
+ stdout: true, // enable capturing stdout
145
+ });
131
146
 
132
- // print the log output from the worker
133
- process.stdout.write(message.log);
147
+ // pipe worker stdout to main process
148
+ worker.stdout.on('data', (data) => {
149
+ if (Atomics.load(sharedArray, 0) === 0) {
150
+ process.stdout.write(data); // forward stdout to main process
134
151
 
135
- // terminate all workers
136
- workers.forEach((w) => w.terminate());
152
+ return data;
153
+ }
154
+ });
137
155
 
138
- process.exit(0);
139
- }
140
- });
156
+ worker.on('message', (message) => {
157
+ if (Atomics.load(sharedArray, 0) === 0) {
158
+ // set the shared flag to 1 to stop all workers
159
+ Atomics.store(sharedArray, 0, 1);
141
160
 
142
- worker.on('error', (err) =>
143
- console.error(`❌ Worker error: ${err.message}`)
144
- );
161
+ // print the log output from the worker
162
+ process.stdout.write(message.log);
145
163
 
146
- workers.push(worker);
147
- }
148
- } else {
149
- // worker thread (multi-threaded mode)
150
- (async () => {
151
- try {
152
- // read shared flag before starting work
153
- const sharedArray = new Int32Array(workerData.sharedBuffer);
154
- if (Atomics.load(sharedArray, 0) === 1) {
155
- process.exit(0); // exit early if a wallet has already been found
156
- }
164
+ // terminate all workers
165
+ workers.forEach((w) => w.terminate());
157
166
 
158
- // create a new Method instance
159
- const method = new Method('wallet', {
160
- b: workerData.chain,
161
- chain: workerData.chain,
162
- options: workerData.options,
167
+ process.exit(0);
168
+ }
163
169
  });
164
170
 
165
- // capture stdout logs in a buffer
166
- let logOutput = '';
167
- const originalWrite = process.stdout.write;
168
- process.stdout.write = (chunk, encoding, callback) => {
169
- logOutput += chunk.toString();
170
- if (callback) callback();
171
- };
171
+ worker.on('error', (err) =>
172
+ console.error(`❌ Worker error: ${err.message}`)
173
+ );
172
174
 
173
- // print the wallet to stdout
174
- await method.init();
175
-
176
- // restore stdout
177
- process.stdout.write = originalWrite;
178
-
179
- // check the shared flag again before sending the result
180
- if (Atomics.load(sharedArray, 0) === 1) {
181
- process.exit(0);
182
- }
183
-
184
- // send the log output to the main thread
185
- parentPort.postMessage({ log: logOutput });
186
- } catch (err) {
187
- console.error(`Worker ${workerData.workerId} failed: ${err.message}`);
175
+ workers.push(worker);
188
176
  }
189
- })();
177
+ } else {
178
+ // worker thread
179
+ (async () => {
180
+ try {
181
+ // read shared flag before starting work
182
+ const sharedArray = new Int32Array(workerData.sharedBuffer);
183
+ if (Atomics.load(sharedArray, 0) === 1) {
184
+ process.exit(0); // exit early if a wallet has already been found
185
+ }
186
+
187
+ // create a new Method instance
188
+ const method = new Method('wallet', {
189
+ b: workerData.chain,
190
+ chain: workerData.chain,
191
+ options: workerData.options,
192
+ });
193
+
194
+ // capture stdout logs in a buffer
195
+ let logOutput = '';
196
+ const originalWrite = process.stdout.write;
197
+ process.stdout.write = (chunk, encoding, callback) => {
198
+ logOutput += chunk.toString();
199
+ if (callback) callback();
200
+ };
201
+
202
+ // print the wallet to stdout
203
+ await method.init();
204
+
205
+ // restore stdout
206
+ process.stdout.write = originalWrite;
207
+
208
+ // check the shared flag again before sending the result
209
+ if (Atomics.load(sharedArray, 0) === 1) {
210
+ process.exit(0);
211
+ }
212
+
213
+ // send the log output to the main thread
214
+ parentPort.postMessage({ log: logOutput });
215
+ } catch (err) {
216
+ console.error(`Worker ${workerData.workerId} failed: ${err.message}`);
217
+ }
218
+ })();
219
+ }
190
220
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yerofey/cryptowallet-cli",
3
- "version": "1.38.2",
3
+ "version": "1.39.0",
4
4
  "description": "Crypto wallet generator CLI tool",
5
5
  "type": "module",
6
6
  "homepage": "https://github.com/yerofey/cryptowallet-cli",
@@ -133,6 +133,7 @@
133
133
  "ed25519-hd-key": "^1.3.0",
134
134
  "eth-lib": "0.1.29",
135
135
  "ethereum-bip84": "0.0.3",
136
+ "ethereum-cryptography": "^3.1.0",
136
137
  "ethereum-mnemonic-privatekey-utils": "1.0.5",
137
138
  "qrcode-terminal": "^0.12.0",
138
139
  "tezos-sign": "1.4.1",
package/src/Method.js CHANGED
@@ -544,8 +544,8 @@ class Method {
544
544
  // network
545
545
  if (cw.row.network == 'EVM' || false) {
546
546
  log(
547
- yellow(
548
- '🆒 You can use this wallet for Ethereum, BSC, Polygon, Arbitrum, Optimism and any other L2/L3 chain (EVM compatible)'
547
+ blue(
548
+ '🆒 You can use this wallet for Ethereum, Base or any other L1/L2/L3 chain (EVM compatible)'
549
549
  )
550
550
  );
551
551
  }
package/src/Wallet.js CHANGED
@@ -398,7 +398,8 @@ class Wallet {
398
398
  const mnemonic = mnemonicString || generateMnemonicString(mnemonicLength);
399
399
  const privateKey = pkutils.getPrivateKeyFromMnemonic(mnemonic);
400
400
 
401
- if (number == 1) {
401
+ const numberIsSupported = row.flags.includes('n') || false;
402
+ if (!numberIsSupported || number == 1) {
402
403
  const account = Account.fromPrivate('0x' + privateKey);
403
404
 
404
405
  addresses.push({
@@ -407,6 +408,7 @@ class Wallet {
407
408
  privateKey,
408
409
  });
409
410
  } else {
411
+ // ! known issue: "Cannot read properties of undefined (reading 'fromBase58')"
410
412
  // TODO: add variable for accountId
411
413
  const root = new fromMnemonicEthereum(mnemonic, '');
412
414
  const child = root.deriveAccount(0);
@@ -619,7 +621,7 @@ class Wallet {
619
621
  addresses: addresses,
620
622
  mnemonic: mnemonicString,
621
623
  });
622
- } else if (chain == 'TRX') {
624
+ } else if (chain == 'TRX' || row.network == 'TRON') {
623
625
  try {
624
626
  // Validate mnemonic
625
627
  if (mnemonicString !== '' && !bip39.validateMnemonic(mnemonicString)) {
@@ -15,7 +15,7 @@
15
15
  "startsWith": "0x",
16
16
  "prefixTest": "[0-9a-fA-F]",
17
17
  "apps": ["metamask", "trustwallet", "binance-chain-wallet"],
18
- "flags": ["f", "m", "n", "p", "s"]
18
+ "flags": ["f", "m", "p", "s"]
19
19
  },
20
20
  "ERC20": {
21
21
  "format": "ERC20",
@@ -23,7 +23,7 @@
23
23
  "startsWith": "0x",
24
24
  "prefixTest": "[0-9a-f]",
25
25
  "apps": ["metamask", "trustwallet", "binance-chain-wallet"],
26
- "flags": ["f", "m", "n", "p", "s"]
26
+ "flags": ["f", "m", "p", "s"]
27
27
  }
28
28
  }
29
29
  }
@@ -4,5 +4,5 @@
4
4
  "startsWith": "0x",
5
5
  "prefixTest": "[0-9a-fA-F]",
6
6
  "apps": ["metamask", "trustwallet"],
7
- "flags": ["m", "n", "p", "s"]
7
+ "flags": ["m", "p", "s"]
8
8
  }
@@ -8,7 +8,7 @@
8
8
  "startsWith": "0x",
9
9
  "prefixTest": "[0-9a-fA-F]",
10
10
  "apps": ["metamask", "trustwallet"],
11
- "flags": ["m", "n", "p", "s"]
11
+ "flags": ["m", "p", "s"]
12
12
  }
13
13
  }
14
14
  }
@@ -4,5 +4,5 @@
4
4
  "startsWith": "0x",
5
5
  "prefixTest": "[0-9a-fA-F]",
6
6
  "apps": ["metamask", "trustwallet"],
7
- "flags": ["m", "n", "p", "s"]
7
+ "flags": ["m", "p", "s"]
8
8
  }
@@ -4,5 +4,5 @@
4
4
  "startsWith": "0x",
5
5
  "prefixTest": "[0-9a-fA-F]",
6
6
  "apps": ["metamask", "trustwallet"],
7
- "flags": ["m", "n", "p", "s"]
7
+ "flags": ["m", "p", "s"]
8
8
  }
package/src/options.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import { program } from 'commander';
2
2
 
3
- program.option('-b <ticker>', 'Wallet for specific blockchain', 'EVM');
4
3
  program.option('-c, --chain <ticker>', 'Wallet for specific blockchain', 'EVM');
5
4
  program.option('-C, --copy', 'Copy the result to the clipboard');
6
5
  program.option('-D, --csv [filename]', 'Save result into CSV file');