@yerofey/cryptowallet-cli 1.5.2 → 1.6.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/README.md +13 -0
- package/cli.js +2 -0
- package/package.json +2 -1
- package/src/CW.js +2 -0
- package/src/Method.js +123 -63
package/README.md
CHANGED
|
@@ -53,6 +53,9 @@ $ cw -c BNB -f BEP2 -m "radio bright pizza pluck family crawl palm flame forget
|
|
|
53
53
|
# generate BNB (BEP20) wallet from mnemonic string
|
|
54
54
|
$ cw -c BNB -f BEP20 -m "radio bright pizza pluck family crawl palm flame forget focus stock stadium"
|
|
55
55
|
|
|
56
|
+
# generate few wallets and save the output into a file
|
|
57
|
+
$ cw -c btc -n 10 -o csv -F out.csv
|
|
58
|
+
|
|
56
59
|
# generate just a mnemonic string (12 words) to import in any wallet app
|
|
57
60
|
$ cw -m
|
|
58
61
|
|
|
@@ -91,16 +94,26 @@ $ cw -l
|
|
|
91
94
|
## Options
|
|
92
95
|
* `-b` or `-c` or `--chain`: Specify the blockchain ticker to generate a wallet for
|
|
93
96
|
* `-f` or `--format`: Specify the blockchain wallet format (for BTC: legacy, segwit, bech32)
|
|
97
|
+
* `-F` or `--filename`: Specify a filename (without extension) to output the data (works only with `-o` argument)
|
|
94
98
|
* `-g` or `--geek`: Display some additional "geeky" info
|
|
95
99
|
* `-l` or `--list`: List all supported blockchains
|
|
96
100
|
* `-m` or `--mnemonic`: Use a bip39 mnemonic phrase (if is set) to generate wallet, or leave it empty to generate new one
|
|
97
101
|
* `-n` or `--number`: Specify number of wallets to display (works for HD wallets only, like BTC/LTC/DOGE)
|
|
102
|
+
* `-o` or `--output`: Specify a file format (currently only `csv` supported) to output the generated data
|
|
98
103
|
* `-p` or `--prefix`: Specify desired prefix for the wallet address (**case-insensitive**)
|
|
99
104
|
* `-P` or `--prefix-sensitive`: Specify desired prefix of the wallet address (**case-sensitive**)
|
|
100
105
|
* `-s` or `--suffix`: Specify desired suffix for the wallet address (**case-insensitive**)
|
|
101
106
|
* `-S` or `--suffix-sensitive`: Specify desired suffix for the wallet address (**case-sensitive**)
|
|
102
107
|
* `-v` or `--version`: Display current version of CW tool
|
|
103
108
|
|
|
109
|
+
## Tested setups
|
|
110
|
+
* Node
|
|
111
|
+
- [x] v16.12.0
|
|
112
|
+
* NPM
|
|
113
|
+
- [x] v8.1.0
|
|
114
|
+
* Yarn
|
|
115
|
+
- [x] v1.23.0
|
|
116
|
+
|
|
104
117
|
## Highlights
|
|
105
118
|
- 24+ blockchains supported
|
|
106
119
|
- Generate wallet with desired prefix/suffix
|
package/cli.js
CHANGED
|
@@ -9,10 +9,12 @@ const Method = require('./src/Method');
|
|
|
9
9
|
program.option('-b, --chain <ticker>', 'Wallet for specific blockchain', 'ERC');
|
|
10
10
|
program.option('-c, --chain <ticker>', 'Wallet for specific blockchain', 'ERC');
|
|
11
11
|
program.option('-f, --format <format>', 'Wallet format type (for cryptos with multiple wallet formats)');
|
|
12
|
+
program.option('-F, --filename <filename>', 'Filename to output the data (works with -o argument)');
|
|
12
13
|
program.option('-g, --geek', 'Display some more info (geeky)');
|
|
13
14
|
program.option('-l, --list', 'List all supported cryptos');
|
|
14
15
|
program.option('-m, --mnemonic [mnemonic]', 'Generate wallet from mnemonic string OR just a mnemonic string');
|
|
15
16
|
program.option('-n, --number <number>', 'Number of wallets to generate (if supported)');
|
|
17
|
+
program.option('-o, --output <format>', 'Return results into some file');
|
|
16
18
|
program.option('-p, --prefix <prefix>', 'Desired wallet prefix');
|
|
17
19
|
program.option('-P, --prefix-sensitive <prefix>', 'Desired wallet prefix (case-sensitive)');
|
|
18
20
|
program.option('-s, --suffix <suffix>', 'Desired wallet suffix');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yerofey/cryptowallet-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"homepage": "https://github.com/yerofey/cryptowallet-cli",
|
|
5
5
|
"author": "Yerofey S. <pm@yerofey.dev> (https://github.com/yerofey)",
|
|
6
6
|
"bin": {
|
|
@@ -67,6 +67,7 @@
|
|
|
67
67
|
"coinkey": "3.0.0",
|
|
68
68
|
"columnify": "1.5.4",
|
|
69
69
|
"commander": "8.1.0",
|
|
70
|
+
"csv-writer": "^1.6.0",
|
|
70
71
|
"eth-lib": "0.1.29",
|
|
71
72
|
"ethereum-bip84": "0.0.3",
|
|
72
73
|
"ethereum-mnemonic-privatekey-utils": "1.0.5",
|
package/src/CW.js
CHANGED
|
@@ -5,10 +5,12 @@ class CW {
|
|
|
5
5
|
constructor(chain, options = {}) {
|
|
6
6
|
const defaultValues = {
|
|
7
7
|
chain: chain || options.chain || '',
|
|
8
|
+
filename: 'output',
|
|
8
9
|
format: '',
|
|
9
10
|
geek: false,
|
|
10
11
|
mnemonic: '',
|
|
11
12
|
number: 1,
|
|
13
|
+
output: undefined,
|
|
12
14
|
prefix: options.prefixSensitive || '',
|
|
13
15
|
prefixIsCaseSensitive: options.prefixSensitive !== undefined,
|
|
14
16
|
suffix: options.suffixSensitive || '',
|
package/src/Method.js
CHANGED
|
@@ -66,98 +66,158 @@ class Method {
|
|
|
66
66
|
return;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
let linesCount = 0;
|
|
70
|
+
const outputFormats = ['csv'];
|
|
71
|
+
const displayAsText = (cw.options.output === undefined || !outputFormats.includes(cw.options.output));
|
|
72
|
+
|
|
69
73
|
// prefix, suffix
|
|
70
|
-
if (
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
if (displayAsText) {
|
|
75
|
+
if (cw.prefixFound && cw.suffixFound) {
|
|
76
|
+
log(`✨ ${chalk.green('Done!')} ${chalk.blueBright('Here is your brand new ' + chainFullName + ' wallet with "' + cw.options.prefix + '" prefix and "' + cw.options.suffix + '" suffix:')}\n`);
|
|
77
|
+
} else if (cw.prefixFound) {
|
|
78
|
+
log(`✨ ${chalk.green('Done!')} ${chalk.blueBright('Here is your brand new ' + chainFullName + ' wallet with "' + cw.options.prefix + '" prefix:')}\n`);
|
|
79
|
+
} else if (cw.suffixFound) {
|
|
80
|
+
log(`✨ ${chalk.green('Done!')} ${chalk.blueBright('Here is your brand new ' + chainFullName + ' wallet with "' + cw.options.suffix + '" suffix:')}\n`);
|
|
81
|
+
} else {
|
|
82
|
+
log(`✨ ${chalk.green('Done!')} ${chalk.blueBright('Here is your brand new ' + chainFullName + ' wallet:')}\n`);
|
|
83
|
+
}
|
|
84
|
+
linesCount += 1;
|
|
78
85
|
}
|
|
79
|
-
|
|
86
|
+
|
|
80
87
|
// result
|
|
88
|
+
let outputData = {};
|
|
81
89
|
if (cw.wallet.addresses !== undefined) {
|
|
90
|
+
// private key
|
|
82
91
|
if (cw.wallet.privateExtendedKey) {
|
|
83
92
|
log(`🔐 ${cw.wallet.privateExtendedKey}`);
|
|
93
|
+
linesCount += 1;
|
|
84
94
|
}
|
|
95
|
+
// mnemonic
|
|
85
96
|
if (cw.wallet.mnemonic) {
|
|
86
97
|
log(`📄 ${cw.wallet.mnemonic}`);
|
|
98
|
+
linesCount += 1;
|
|
87
99
|
}
|
|
88
|
-
|
|
100
|
+
// addresses
|
|
89
101
|
for (const item of cw.wallet.addresses) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
102
|
+
if (displayAsText) {
|
|
103
|
+
if (cw.wallet.addresses.length > 1) {
|
|
104
|
+
log();
|
|
105
|
+
log(`🆔 ${item.index}`);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (cw.prefixFound && cw.prefixFoundInWallets.includes(item.address) && cw.suffixFound && cw.suffixFoundInWallets.includes(item.address)) {
|
|
109
|
+
// highlight found prefix
|
|
110
|
+
const addressCutPrefixLength = cw.row.startsWith.length + cw.options.prefix.length;
|
|
111
|
+
const addressFirstPart = item.address.slice(cw.row.startsWith.length, addressCutPrefixLength);
|
|
112
|
+
const addressLastPart = item.address.slice(item.address.length - cw.options.suffix.length);
|
|
113
|
+
log(`👛 ${cw.row.startsWith}${chalk.magenta(addressFirstPart)}${item.address.substring(cw.row.startsWith.length + addressFirstPart.length, item.address.length - addressLastPart.length)}${chalk.magenta(addressLastPart)}`);
|
|
114
|
+
} else if (cw.prefixFound && cw.prefixFoundInWallets.includes(item.address)) {
|
|
115
|
+
// highlight found prefix
|
|
116
|
+
const addressCutLength = cw.row.startsWith.length + cw.options.prefix.length;
|
|
117
|
+
log(`👛 ${cw.row.startsWith}${chalk.magenta(item.address.slice(cw.row.startsWith.length, addressCutLength))}${item.address.slice(addressCutLength)}`);
|
|
118
|
+
} else if (cw.suffixFound && cw.suffixFoundInWallets.includes(item.address)) {
|
|
119
|
+
// highlight found suffix
|
|
120
|
+
log(`👛 ${item.address.slice(0, item.address.length - cw.options.suffix.length)}${chalk.magenta(item.address.slice(item.address.length - cw.options.suffix.length))}`);
|
|
121
|
+
} else {
|
|
122
|
+
log(`👛 ${item.address}`);
|
|
123
|
+
}
|
|
124
|
+
log(`🔑 ${item.privateKey}`);
|
|
108
125
|
} else {
|
|
109
|
-
|
|
126
|
+
// const createCsvWriter = csvWriter.createObjectCsvWriter;
|
|
127
|
+
// const csvWriter = createCsvWriter({
|
|
128
|
+
// path: 'out.csv',
|
|
129
|
+
// header: [
|
|
130
|
+
// {id: 'name', title: 'Name'},
|
|
131
|
+
// {id: 'surname', title: 'Surname'},
|
|
132
|
+
// {id: 'age', title: 'Age'},
|
|
133
|
+
// {id: 'gender', title: 'Gender'},
|
|
134
|
+
// ]
|
|
135
|
+
// });
|
|
136
|
+
// // TODO: build output into file
|
|
137
|
+
// log('TODO_BUILD_OUTPUT_INTO_FILE', item.address);
|
|
110
138
|
}
|
|
111
|
-
|
|
139
|
+
}
|
|
140
|
+
if (!displayAsText) {
|
|
141
|
+
outputData.wallets = cw.wallet.addresses;
|
|
112
142
|
}
|
|
113
143
|
|
|
114
|
-
if (cw.row.path !== undefined && cw.options.geek) {
|
|
144
|
+
if (displayAsText && cw.row.path !== undefined && cw.options.geek) {
|
|
115
145
|
log();
|
|
116
146
|
log(`🗂 wallet address path: ${cw.row.path}'/0'/0/ID`);
|
|
147
|
+
linesCount += 1;
|
|
117
148
|
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
if (cw.row.formats !== undefined || cw.row.network == 'EVM' || cw.row.apps || cw.wallet.tested !== undefined) {
|
|
121
|
-
log();
|
|
122
|
-
}
|
|
123
149
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
150
|
+
// generate csv
|
|
151
|
+
if (!displayAsText) {
|
|
152
|
+
const filename = (cw.options.filename.split('.')[0]) ?? 'output';
|
|
153
|
+
const createCsvWriter = require('csv-writer').createObjectCsvWriter;
|
|
154
|
+
const csvWriter = createCsvWriter({
|
|
155
|
+
path: `${filename}.csv`,
|
|
156
|
+
header: [
|
|
157
|
+
{
|
|
158
|
+
id: 'index',
|
|
159
|
+
title: 'index',
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
id: 'address',
|
|
163
|
+
title: 'address',
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
id: 'privateKey',
|
|
167
|
+
title: 'privateKey',
|
|
168
|
+
},
|
|
169
|
+
]
|
|
170
|
+
});
|
|
171
|
+
csvWriter
|
|
172
|
+
.writeRecords(outputData.wallets)
|
|
173
|
+
.then(()=> log(`${linesCount > 0 ? "\n" : ''}⚠️ ${chalk.yellow(`Don\'t forget to save the data above manually, because it is not in the output file`)} \n✨ ${chalk.green('Done!')} ${chalk.blueBright(`The output successfully saved into "${filename}.csv" file`)}`))
|
|
174
|
+
.catch(() => log(`${linesCount > 0 ? "\n" : ''}⛔️ ${chalk.red(`Error: failed to generate a file`)}`));
|
|
132
175
|
}
|
|
133
|
-
log(chalk.yellow('*️⃣ You can create different wallet formats: ' + formatsString.substring(0, formatsString.length - 2) + ' (use it with ' + chalk.white('-f') + ' flag)'));
|
|
134
176
|
}
|
|
135
177
|
|
|
136
|
-
if (
|
|
137
|
-
|
|
138
|
-
|
|
178
|
+
if (displayAsText) {
|
|
179
|
+
if (cw.row.formats !== undefined || cw.row.network == 'EVM' || cw.row.apps || cw.wallet.tested !== undefined) {
|
|
180
|
+
log();
|
|
181
|
+
}
|
|
139
182
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
"metamask": "MetaMask",
|
|
143
|
-
"tronlink": "TronLink",
|
|
144
|
-
"trustwallet": "Trust Wallet",
|
|
145
|
-
"harmony-chrome-ext": "Harmony Chrome Extension Wallet",
|
|
146
|
-
"binance-chain-wallet": "Binance Chain Wallet"
|
|
183
|
+
if (cw.wallet.tested !== undefined) {
|
|
184
|
+
log(chalk.red('‼️ This wallet generation format was not tested yet, do not use it!'));
|
|
147
185
|
}
|
|
148
|
-
let appsArray = [];
|
|
149
186
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
187
|
+
if (cw.row.formats !== undefined && Object.keys(cw.row.formats).length > 1) {
|
|
188
|
+
let formatsString = '';
|
|
189
|
+
for (const val of Object.keys(cw.row.formats)) {
|
|
190
|
+
formatsString += chalk.blue(val) + ', ';
|
|
153
191
|
}
|
|
192
|
+
log(chalk.yellow('*️⃣ You can create different wallet formats: ' + formatsString.substring(0, formatsString.length - 2) + ' (use it with ' + chalk.white('-f') + ' flag)'));
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (cw.row.network == 'EVM' || false) {
|
|
196
|
+
log(chalk.yellow('🆒 You can use this wallet in Ethereum, Binance Smart Chain, Polygon and few more networks (EVM compatible)'));
|
|
154
197
|
}
|
|
155
198
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
199
|
+
if (cw.row.apps !== undefined) {
|
|
200
|
+
let apps = {
|
|
201
|
+
"metamask": "MetaMask",
|
|
202
|
+
"tronlink": "TronLink",
|
|
203
|
+
"trustwallet": "Trust Wallet",
|
|
204
|
+
"harmony-chrome-ext": "Harmony Chrome Extension Wallet",
|
|
205
|
+
"binance-chain-wallet": "Binance Chain Wallet"
|
|
206
|
+
}
|
|
207
|
+
let appsArray = [];
|
|
208
|
+
|
|
209
|
+
for (let key of Object.keys(apps)) {
|
|
210
|
+
if (cw.row.apps.includes(key)) {
|
|
211
|
+
appsArray.push(apps[key]);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
let appsString = appsArray.join(', ');
|
|
216
|
+
if (cw.row.apps || false) {
|
|
217
|
+
appsString += ' and many other wallet apps';
|
|
218
|
+
}
|
|
219
|
+
log(chalk.greenBright('ℹ️ You can import this wallet into ' + appsString));
|
|
159
220
|
}
|
|
160
|
-
log(chalk.greenBright('ℹ️ You can import this wallet into ' + appsString));
|
|
161
221
|
}
|
|
162
222
|
}
|
|
163
223
|
}
|