hodl-wallet 1.6.8 → 1.7.2
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/example.jpg +0 -0
- package/index.js +180 -64
- package/network/disabled/rsk.js +14 -0
- package/package.json +4 -4
- /package/network/{old → disabled}/ton.js +0 -0
package/example.jpg
CHANGED
|
Binary file
|
package/index.js
CHANGED
|
@@ -34,23 +34,26 @@ class Wallet {
|
|
|
34
34
|
|
|
35
35
|
this.network = null;
|
|
36
36
|
this.selectedNetwork = null;
|
|
37
|
-
this.networkUsage =
|
|
37
|
+
this.networkUsage = {};
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
async initialize() {
|
|
41
41
|
try {
|
|
42
|
+
this.networkUsage = await this.db.get('networkUsage') || {};
|
|
43
|
+
|
|
42
44
|
const networkPlugins = await this.loadNetworkPlugins();
|
|
43
45
|
if (networkPlugins.length === 0) {
|
|
44
46
|
Wallet.displayError('No valid network plugins found.');
|
|
45
47
|
process.exit(1);
|
|
46
48
|
}
|
|
47
|
-
await this.selectNetwork(networkPlugins);
|
|
49
|
+
await this.selectNetwork(networkPlugins, { autoSelect: true });
|
|
48
50
|
this.network = new this.selectedNetwork.NetworkClass(this.selectedNetwork);
|
|
49
51
|
this.network.name = this.selectedNetwork.name;
|
|
50
52
|
|
|
51
53
|
await this.loadAccount();
|
|
54
|
+
const account = await this.getAccount();
|
|
52
55
|
|
|
53
|
-
if (!
|
|
56
|
+
if (!account) {
|
|
54
57
|
Wallet.displayError('Failed to initialize account.');
|
|
55
58
|
process.exit(1);
|
|
56
59
|
}
|
|
@@ -68,26 +71,28 @@ class Wallet {
|
|
|
68
71
|
}
|
|
69
72
|
}
|
|
70
73
|
|
|
71
|
-
getAccount() {
|
|
74
|
+
async getAccount() {
|
|
72
75
|
return this.db.get('account', this.network.constructor.name);
|
|
73
76
|
}
|
|
74
77
|
|
|
75
|
-
getAddress() {
|
|
78
|
+
async getAddress() {
|
|
76
79
|
return this.db.get('account', this.network.constructor.name, 'address');
|
|
77
80
|
}
|
|
78
81
|
|
|
79
|
-
getMnemonic() {
|
|
82
|
+
async getMnemonic() {
|
|
80
83
|
return this.db.get('mnemonic');
|
|
81
84
|
}
|
|
82
85
|
|
|
83
|
-
displayAccountAddress() {
|
|
86
|
+
async displayAccountAddress() {
|
|
87
|
+
|
|
84
88
|
const table = new Table({
|
|
85
|
-
head: [
|
|
89
|
+
head: [`${this.selectedNetwork.name} Address`],
|
|
86
90
|
style: {
|
|
87
91
|
head: ['green']
|
|
88
92
|
}
|
|
89
93
|
});
|
|
90
|
-
|
|
94
|
+
|
|
95
|
+
table.push([await this.getAddress()]);
|
|
91
96
|
console.log(table.toString());
|
|
92
97
|
}
|
|
93
98
|
|
|
@@ -103,30 +108,37 @@ class Wallet {
|
|
|
103
108
|
return networks.filter(network => network && network.name);
|
|
104
109
|
}
|
|
105
110
|
|
|
106
|
-
async selectNetwork(networkPlugins) {
|
|
111
|
+
async selectNetwork(networkPlugins, { autoSelect = false } = {}) {
|
|
107
112
|
// Sort networks by usage count (descending)
|
|
108
113
|
const sortedNetworks = networkPlugins.sort((a, b) =>
|
|
109
114
|
(this.networkUsage[b.name] || 0) - (this.networkUsage[a.name] || 0)
|
|
110
115
|
);
|
|
111
116
|
|
|
112
|
-
|
|
113
|
-
type: 'list',
|
|
114
|
-
name: 'network',
|
|
115
|
-
message: 'Select the network:',
|
|
116
|
-
choices: sortedNetworks.map(plugin => plugin.name),
|
|
117
|
-
});
|
|
117
|
+
let selectedNetwork;
|
|
118
118
|
|
|
119
|
-
|
|
119
|
+
if (autoSelect) {
|
|
120
|
+
// Automatically select the first network (most used)
|
|
121
|
+
selectedNetwork = sortedNetworks[0];
|
|
122
|
+
} else {
|
|
123
|
+
// Let user choose the network
|
|
124
|
+
const { network } = await inquirer.prompt({
|
|
125
|
+
type: 'list',
|
|
126
|
+
name: 'network',
|
|
127
|
+
message: 'Select the network:',
|
|
128
|
+
choices: sortedNetworks.map(plugin => plugin.name),
|
|
129
|
+
});
|
|
130
|
+
selectedNetwork = sortedNetworks.find(plugin => plugin.name === network);
|
|
131
|
+
}
|
|
120
132
|
|
|
121
133
|
// Increment usage count for the selected network
|
|
122
|
-
this.networkUsage[
|
|
123
|
-
this.db.set('networkUsage', this.networkUsage);
|
|
134
|
+
this.networkUsage[selectedNetwork.name] = (this.networkUsage[selectedNetwork.name] || 0) + 1;
|
|
135
|
+
await this.db.set('networkUsage', this.networkUsage);
|
|
124
136
|
|
|
125
137
|
this.selectedNetwork = selectedNetwork;
|
|
126
138
|
}
|
|
127
139
|
|
|
128
140
|
async loadAccount(loggedIn = false) {
|
|
129
|
-
let account = this.getAccount();
|
|
141
|
+
let account = await this.getAccount();
|
|
130
142
|
|
|
131
143
|
const mainChoices = ['Create New Account'];
|
|
132
144
|
|
|
@@ -134,6 +146,7 @@ class Wallet {
|
|
|
134
146
|
mainChoices.push('Import Options');
|
|
135
147
|
mainChoices.push('Export Options');
|
|
136
148
|
mainChoices.push('Switch Network');
|
|
149
|
+
mainChoices.push('Manage Address Book');
|
|
137
150
|
mainChoices.push('Go Back');
|
|
138
151
|
} else {
|
|
139
152
|
mainChoices.push('Import Mnemonic (12 words)');
|
|
@@ -153,6 +166,27 @@ class Wallet {
|
|
|
153
166
|
return;
|
|
154
167
|
}
|
|
155
168
|
|
|
169
|
+
if (accountAction === 'Manage Address Book') {
|
|
170
|
+
const addressBookChoices = ['Delete Address', 'Go Back'];
|
|
171
|
+
const { addressBookAction } = await inquirer.prompt({
|
|
172
|
+
type: 'list',
|
|
173
|
+
name: 'addressBookAction',
|
|
174
|
+
message: 'Select an address book option:',
|
|
175
|
+
choices: addressBookChoices,
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
if (addressBookAction === 'Go Back') {
|
|
179
|
+
return this.loadAccount(loggedIn);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
switch (addressBookAction) {
|
|
183
|
+
case 'Delete Address':
|
|
184
|
+
await this.deleteFromAddressBook();
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
|
|
156
190
|
if (accountAction === 'Import Options') {
|
|
157
191
|
const importChoices = ['Import Mnemonic (12 words)', 'Import Private-key', 'Import HODL File', 'Go Back'];
|
|
158
192
|
const { importAction } = await inquirer.prompt({
|
|
@@ -180,14 +214,14 @@ class Wallet {
|
|
|
180
214
|
return;
|
|
181
215
|
}
|
|
182
216
|
this.setAccount(account);
|
|
183
|
-
this.displayAccountAddress();
|
|
217
|
+
await this.displayAccountAddress();
|
|
184
218
|
break;
|
|
185
219
|
case 'Import Private-key':
|
|
186
220
|
await this.importPrivateKey();
|
|
187
221
|
break;
|
|
188
222
|
case 'Import HODL File':
|
|
189
223
|
this.setAccount(await this.importHODLFile());
|
|
190
|
-
this.displayAccountAddress();
|
|
224
|
+
await this.displayAccountAddress();
|
|
191
225
|
break;
|
|
192
226
|
}
|
|
193
227
|
|
|
@@ -215,7 +249,7 @@ class Wallet {
|
|
|
215
249
|
return;
|
|
216
250
|
}
|
|
217
251
|
|
|
218
|
-
|
|
252
|
+
|
|
219
253
|
if (accountAction === 'Create New Account') {
|
|
220
254
|
const confirmOverwrite = await this.confirmOverwrite();
|
|
221
255
|
if (!confirmOverwrite) return;
|
|
@@ -233,7 +267,7 @@ class Wallet {
|
|
|
233
267
|
}
|
|
234
268
|
|
|
235
269
|
async confirmOverwrite() {
|
|
236
|
-
if (this.getAccount()) {
|
|
270
|
+
if (await this.getAccount()) {
|
|
237
271
|
const { confirmOverwrite } = await inquirer.prompt({
|
|
238
272
|
type: 'confirm',
|
|
239
273
|
name: 'confirmOverwrite',
|
|
@@ -265,12 +299,14 @@ class Wallet {
|
|
|
265
299
|
}
|
|
266
300
|
|
|
267
301
|
async showBalance() {
|
|
268
|
-
|
|
302
|
+
const account = await this.getAccount();
|
|
303
|
+
|
|
304
|
+
if (!account) {
|
|
269
305
|
Wallet.displayError('Account not initialized.');
|
|
270
306
|
return;
|
|
271
307
|
}
|
|
272
308
|
|
|
273
|
-
const balances = await this.network.getTokenBalances(this.getAddress());
|
|
309
|
+
const balances = await this.network.getTokenBalances(await this.getAddress());
|
|
274
310
|
|
|
275
311
|
const table = new Table({
|
|
276
312
|
head: ['Token', 'Balance'],
|
|
@@ -286,8 +322,8 @@ class Wallet {
|
|
|
286
322
|
}
|
|
287
323
|
|
|
288
324
|
async transferFunds() {
|
|
289
|
-
const contacts = this.db.
|
|
290
|
-
const addressBook =
|
|
325
|
+
const contacts = await this.db.entries('contact', this.network.name) || [];
|
|
326
|
+
const addressBook = contacts.map(([address, data]) => ({
|
|
291
327
|
address,
|
|
292
328
|
name: data.name
|
|
293
329
|
}));
|
|
@@ -362,20 +398,21 @@ class Wallet {
|
|
|
362
398
|
|
|
363
399
|
try {
|
|
364
400
|
let signedTx;
|
|
401
|
+
const account = await this.getAccount();
|
|
365
402
|
if (token === this.selectedNetwork.nativeToken) {
|
|
366
|
-
signedTx = await this.network.handleNativeTransfer(
|
|
403
|
+
signedTx = await this.network.handleNativeTransfer(account, address, amount);
|
|
367
404
|
} else {
|
|
368
|
-
signedTx = await this.network.handleERC20Transfer(
|
|
405
|
+
signedTx = await this.network.handleERC20Transfer(account, token, address, amount);
|
|
369
406
|
}
|
|
370
407
|
|
|
371
408
|
const receipt = await this.network.sendSignedTransaction(signedTx);
|
|
372
409
|
|
|
373
410
|
spinner.succeed('Transaction confirmed!');
|
|
374
411
|
|
|
375
|
-
this.displayTransactionResult(address, token, amount, receipt.transactionHash);
|
|
412
|
+
await this.displayTransactionResult(address, token, amount, receipt.transactionHash);
|
|
376
413
|
|
|
377
414
|
// Add transaction to history
|
|
378
|
-
this.addToTransactions(address, token, amount, receipt.transactionHash);
|
|
415
|
+
await this.addToTransactions(address, token, amount, receipt.transactionHash);
|
|
379
416
|
|
|
380
417
|
if (!contacts[address]) {
|
|
381
418
|
await this.addToAddressBook(address);
|
|
@@ -417,7 +454,7 @@ class Wallet {
|
|
|
417
454
|
}).replace(/(\d{2})\/(\d{2})\/(\d{4})/, '$3-$2-$1').replace(",", "");
|
|
418
455
|
}
|
|
419
456
|
|
|
420
|
-
addToTransactions(recipient, token, amount, hash) {
|
|
457
|
+
async addToTransactions(recipient, token, amount, hash) {
|
|
421
458
|
const transaction = {
|
|
422
459
|
timestamp: new Date().toISOString(),
|
|
423
460
|
recipient,
|
|
@@ -425,11 +462,13 @@ class Wallet {
|
|
|
425
462
|
amount,
|
|
426
463
|
hash
|
|
427
464
|
};
|
|
428
|
-
|
|
465
|
+
const address = await this.getAddress();
|
|
466
|
+
this.db.add('transactions', address, this.selectedNetwork.nativeToken, transaction);
|
|
429
467
|
}
|
|
430
468
|
|
|
431
469
|
async showTransactions() {
|
|
432
|
-
const
|
|
470
|
+
const address = await this.getAddress();
|
|
471
|
+
const history = await this.db.values('transactions', address, this.selectedNetwork.nativeToken) || [];
|
|
433
472
|
|
|
434
473
|
const table = new Table({
|
|
435
474
|
head: ['Date', 'Recipient', 'Token', 'Amount'],
|
|
@@ -440,14 +479,14 @@ class Wallet {
|
|
|
440
479
|
table.push([{ colSpan: 4, content: 'No transaction history available.' }]);
|
|
441
480
|
}
|
|
442
481
|
|
|
443
|
-
|
|
482
|
+
for (const tx of history) {
|
|
444
483
|
const date = this.formatDate(tx.timestamp);
|
|
445
|
-
const contact = this.db.get('contact', this.network.name, tx.recipient);
|
|
484
|
+
const contact = await this.db.get('contact', this.network.name, tx.recipient);
|
|
446
485
|
const recipient = contact ? `${tx.recipient} (${contact.name})` : tx.recipient;
|
|
447
486
|
const amount = parseFloat(tx.amount).toFixed(3);
|
|
448
487
|
table.push([date, recipient, tx.token, amount]);
|
|
449
488
|
table.push([{ colSpan: 4, content: this.selectedNetwork.explorer + tx.hash }]);
|
|
450
|
-
}
|
|
489
|
+
}
|
|
451
490
|
|
|
452
491
|
console.log(table.toString());
|
|
453
492
|
}
|
|
@@ -460,8 +499,7 @@ class Wallet {
|
|
|
460
499
|
});
|
|
461
500
|
|
|
462
501
|
if (name.trim() !== '') {
|
|
463
|
-
|
|
464
|
-
this.db.set('contact', this.network.name, address, 'name', name);
|
|
502
|
+
await this.db.set('contact', this.network.name, address, 'name', name);
|
|
465
503
|
|
|
466
504
|
const table = new Table({
|
|
467
505
|
head: [{ colSpan: 2, content: "Recipient saved to the address book." }],
|
|
@@ -473,7 +511,56 @@ class Wallet {
|
|
|
473
511
|
}
|
|
474
512
|
}
|
|
475
513
|
|
|
476
|
-
|
|
514
|
+
async deleteFromAddressBook() {
|
|
515
|
+
const contacts = await this.db.get('contact', this.network.name) || {};
|
|
516
|
+
const addressBook = Object.entries(contacts).map(([address, data]) => ({
|
|
517
|
+
address,
|
|
518
|
+
name: data.name
|
|
519
|
+
}));
|
|
520
|
+
|
|
521
|
+
if (addressBook.length === 0) {
|
|
522
|
+
const table = new Table({
|
|
523
|
+
head: ['Address Book'],
|
|
524
|
+
style: { head: ['yellow'] },
|
|
525
|
+
});
|
|
526
|
+
table.push(['No addresses in the address book.']);
|
|
527
|
+
console.log(table.toString());
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
addressBook.push({ name: 'Go Back', address: '' });
|
|
532
|
+
|
|
533
|
+
const { addressToDelete } = await inquirer.prompt({
|
|
534
|
+
type: 'list',
|
|
535
|
+
name: 'addressToDelete',
|
|
536
|
+
message: 'Select an address to delete:',
|
|
537
|
+
choices: addressBook.map(entry => ({
|
|
538
|
+
name: entry.address ? `${entry.address} (${entry.name})` : entry.name,
|
|
539
|
+
value: entry.address
|
|
540
|
+
}))
|
|
541
|
+
});
|
|
542
|
+
|
|
543
|
+
if (!addressToDelete) return;
|
|
544
|
+
|
|
545
|
+
const { confirmDelete } = await inquirer.prompt({
|
|
546
|
+
type: 'confirm',
|
|
547
|
+
name: 'confirmDelete',
|
|
548
|
+
message: 'Are you sure you want to delete this address?',
|
|
549
|
+
default: false
|
|
550
|
+
});
|
|
551
|
+
|
|
552
|
+
if (confirmDelete) {
|
|
553
|
+
await this.db.del('contact', this.network.name, addressToDelete);
|
|
554
|
+
const table = new Table({
|
|
555
|
+
head: ['Address Book'],
|
|
556
|
+
style: { head: ['green'] },
|
|
557
|
+
});
|
|
558
|
+
table.push(['Address deleted successfully.']);
|
|
559
|
+
console.log(table.toString());
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
async displayTransactionResult(address, token, amount, hash) {
|
|
477
564
|
|
|
478
565
|
const table = new Table({
|
|
479
566
|
head: ['Date', 'Recipient', 'Token', 'Amount'],
|
|
@@ -482,7 +569,7 @@ class Wallet {
|
|
|
482
569
|
|
|
483
570
|
const date = this.formatDate(new Date());
|
|
484
571
|
|
|
485
|
-
const contact = this.db.get('contact', this.network.name, address);
|
|
572
|
+
const contact = await this.db.get('contact', this.network.name, address);
|
|
486
573
|
const recipient = contact ? `${address} (${contact.name})` : address;
|
|
487
574
|
|
|
488
575
|
table.push([date, recipient, token, parseFloat(amount).toFixed(3)]);
|
|
@@ -495,7 +582,7 @@ class Wallet {
|
|
|
495
582
|
|
|
496
583
|
}
|
|
497
584
|
|
|
498
|
-
displayAccountDetails() {
|
|
585
|
+
async displayAccountDetails() {
|
|
499
586
|
|
|
500
587
|
const table = new Table({
|
|
501
588
|
head: [{ colSpan: 2, content: 'Account Details' }],
|
|
@@ -503,12 +590,13 @@ class Wallet {
|
|
|
503
590
|
wordWrap: true
|
|
504
591
|
});
|
|
505
592
|
|
|
593
|
+
const account = await this.getAccount();
|
|
506
594
|
table.push(
|
|
507
|
-
['Address', this.getAddress()],
|
|
508
|
-
['Private-key',
|
|
595
|
+
['Address', await this.getAddress()],
|
|
596
|
+
['Private-key', account.privateKey]
|
|
509
597
|
);
|
|
510
598
|
|
|
511
|
-
const mnemonic = this.getMnemonic();
|
|
599
|
+
const mnemonic = await this.getMnemonic();
|
|
512
600
|
if (mnemonic) {
|
|
513
601
|
table.push(['Mnemonic Phrase', mnemonic]);
|
|
514
602
|
table.push(['WARNING', "Please keep your private-key and mnemonic phrase secure. Never share it."]);
|
|
@@ -523,11 +611,12 @@ class Wallet {
|
|
|
523
611
|
const networkPlugins = await this.loadNetworkPlugins();
|
|
524
612
|
await this.selectNetwork(networkPlugins);
|
|
525
613
|
this.network = new this.selectedNetwork.NetworkClass(this.selectedNetwork);
|
|
526
|
-
this.displayAccountAddress();
|
|
614
|
+
await this.displayAccountAddress();
|
|
527
615
|
}
|
|
528
616
|
|
|
529
617
|
async exportHODLFile() {
|
|
530
|
-
const
|
|
618
|
+
const address = await this.getAddress();
|
|
619
|
+
const defaultFileName = `${address.slice(-6).toUpperCase()}`;
|
|
531
620
|
let { fileName } = await inquirer.prompt({
|
|
532
621
|
type: 'input',
|
|
533
622
|
name: 'fileName',
|
|
@@ -537,7 +626,7 @@ class Wallet {
|
|
|
537
626
|
|
|
538
627
|
fileName += '.HODL';
|
|
539
628
|
|
|
540
|
-
const data = this.db.get();
|
|
629
|
+
const data = await this.db.get();
|
|
541
630
|
const encryptionKey = await UIManager.getEncryptionKey();
|
|
542
631
|
const encryptedData = Persist.encrypt(data, encryptionKey);
|
|
543
632
|
|
|
@@ -598,14 +687,14 @@ class Wallet {
|
|
|
598
687
|
|
|
599
688
|
try {
|
|
600
689
|
this.setAccount(await this.network.privateKeyToAccount(privateKey));
|
|
601
|
-
this.displayAccountAddress();
|
|
690
|
+
await this.displayAccountAddress();
|
|
602
691
|
} catch (error) {
|
|
603
692
|
Wallet.displayError('Invalid private-key.');
|
|
604
693
|
}
|
|
605
694
|
}
|
|
606
695
|
|
|
607
696
|
async createNewAccount() {
|
|
608
|
-
let existingMnemonic = this.getMnemonic();
|
|
697
|
+
let existingMnemonic = await this.getMnemonic();
|
|
609
698
|
let useMnemonic = false;
|
|
610
699
|
|
|
611
700
|
if (existingMnemonic) {
|
|
@@ -615,7 +704,7 @@ class Wallet {
|
|
|
615
704
|
message: 'Use existing mnemonic to create account?',
|
|
616
705
|
default: true
|
|
617
706
|
});
|
|
618
|
-
|
|
707
|
+
|
|
619
708
|
if (useExistingMnemonic) {
|
|
620
709
|
useMnemonic = true;
|
|
621
710
|
this.setAccount(await this.network.accountFromMnemonic(existingMnemonic));
|
|
@@ -637,8 +726,32 @@ class Wallet {
|
|
|
637
726
|
}
|
|
638
727
|
}
|
|
639
728
|
|
|
729
|
+
// Check if there are addresses in the address book
|
|
730
|
+
const addressBook = await this.db.entries('contact', this.network.name) || [];
|
|
731
|
+
|
|
732
|
+
if (addressBook.length > 0) {
|
|
733
|
+
const { deleteAddresses } = await inquirer.prompt({
|
|
734
|
+
type: 'confirm',
|
|
735
|
+
name: 'deleteAddresses',
|
|
736
|
+
message: `Do you want to delete all ${addressBook.length} addresses from the previous account?`,
|
|
737
|
+
default: false
|
|
738
|
+
});
|
|
739
|
+
|
|
740
|
+
if (deleteAddresses) {
|
|
741
|
+
|
|
742
|
+
await this.db.del('contact');
|
|
743
|
+
|
|
744
|
+
const table = new Table({
|
|
745
|
+
head: ['Address Book'],
|
|
746
|
+
style: { head: ['green'] },
|
|
747
|
+
});
|
|
748
|
+
table.push(['All addresses deleted successfully.']);
|
|
749
|
+
console.log(table.toString());
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
|
|
640
753
|
let message = 'Do you want to display sensitive information (private key';
|
|
641
|
-
if (this.getMnemonic()) {
|
|
754
|
+
if (await this.getMnemonic()) {
|
|
642
755
|
message += ' and mnemonic';
|
|
643
756
|
}
|
|
644
757
|
message += ')?';
|
|
@@ -651,9 +764,9 @@ class Wallet {
|
|
|
651
764
|
});
|
|
652
765
|
|
|
653
766
|
if (showSensitive) {
|
|
654
|
-
this.displayAccountDetails();
|
|
767
|
+
await this.displayAccountDetails();
|
|
655
768
|
} else {
|
|
656
|
-
this.displayAccountAddress();
|
|
769
|
+
await this.displayAccountAddress();
|
|
657
770
|
}
|
|
658
771
|
}
|
|
659
772
|
}
|
|
@@ -677,7 +790,7 @@ class UIManager {
|
|
|
677
790
|
return key;
|
|
678
791
|
}
|
|
679
792
|
|
|
680
|
-
static async confirmEncryptionKey(
|
|
793
|
+
static async confirmEncryptionKey() {
|
|
681
794
|
const { confirmKey } = await inquirer.prompt({
|
|
682
795
|
type: 'password',
|
|
683
796
|
name: 'confirmKey',
|
|
@@ -741,10 +854,10 @@ try {
|
|
|
741
854
|
process.exit(1);
|
|
742
855
|
}
|
|
743
856
|
|
|
744
|
-
const accountExists = wallet.getMnemonic();
|
|
857
|
+
const accountExists = await wallet.getMnemonic();
|
|
745
858
|
|
|
746
859
|
if (!accountExists) {
|
|
747
|
-
const confirmedKey = await UIManager.confirmEncryptionKey(
|
|
860
|
+
const confirmedKey = await UIManager.confirmEncryptionKey();
|
|
748
861
|
if (confirmedKey !== encryptionKey) {
|
|
749
862
|
Wallet.displayError('Passwords do not match. Please try again.');
|
|
750
863
|
process.exit(1);
|
|
@@ -753,7 +866,7 @@ if (!accountExists) {
|
|
|
753
866
|
|
|
754
867
|
try {
|
|
755
868
|
await wallet.initialize();
|
|
756
|
-
if (accountExists) wallet.displayAccountAddress();
|
|
869
|
+
if (accountExists) await wallet.displayAccountAddress();
|
|
757
870
|
} catch (error) {
|
|
758
871
|
Wallet.displayError('Failed to initialize wallet.', error);
|
|
759
872
|
process.exit(1);
|
|
@@ -764,7 +877,7 @@ process.on('exit', () => {
|
|
|
764
877
|
UIManager.displayExitPhrase();
|
|
765
878
|
});
|
|
766
879
|
|
|
767
|
-
|
|
880
|
+
async function mainMenu() {
|
|
768
881
|
const { action } = await inquirer.prompt({
|
|
769
882
|
type: 'list',
|
|
770
883
|
name: 'action',
|
|
@@ -781,17 +894,20 @@ while (true) {
|
|
|
781
894
|
switch (action) {
|
|
782
895
|
case 'transferFunds':
|
|
783
896
|
await wallet.transferFunds();
|
|
784
|
-
|
|
897
|
+
return mainMenu();
|
|
785
898
|
case 'balance':
|
|
786
899
|
await wallet.showBalance();
|
|
787
|
-
|
|
900
|
+
return mainMenu();
|
|
788
901
|
case 'showTransactions':
|
|
789
902
|
await wallet.showTransactions();
|
|
790
|
-
|
|
903
|
+
return mainMenu();
|
|
791
904
|
case 'account':
|
|
792
905
|
await wallet.loadAccount(true);
|
|
793
|
-
|
|
906
|
+
return mainMenu();
|
|
794
907
|
case 'exit':
|
|
795
908
|
process.exit();
|
|
796
909
|
}
|
|
797
910
|
}
|
|
911
|
+
|
|
912
|
+
// Start the application
|
|
913
|
+
mainMenu();
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import Web3Network from './lib/Web3Network.js';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
NetworkClass: Web3Network,
|
|
5
|
+
name: '[ERC-20] Rootstock',
|
|
6
|
+
url: 'https://public-node.rsk.co',
|
|
7
|
+
nativeToken: 'RBTC',
|
|
8
|
+
explorer: 'https://explorer.rootstock.io/tx/',
|
|
9
|
+
tokens: {
|
|
10
|
+
// 'USDT': {
|
|
11
|
+
// address: '0x833589fCD6eDb6E08B1Daf2d5F90D7ae4Dfd9F59',
|
|
12
|
+
// }
|
|
13
|
+
}
|
|
14
|
+
};
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hodl-wallet",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.2",
|
|
4
4
|
"description": "🧊 HODL Wallet - Fast CLI crypto wallet!",
|
|
5
|
-
"author": "Martin
|
|
5
|
+
"author": "Martin Clasen",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/clasen/HODL.git"
|
|
@@ -47,13 +47,13 @@
|
|
|
47
47
|
"clasen"
|
|
48
48
|
],
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"axios": "^1.
|
|
50
|
+
"axios": "^1.8.4",
|
|
51
51
|
"bip32": "^5.0.0-rc.0",
|
|
52
52
|
"bip39": "^3.1.0",
|
|
53
53
|
"bitcoinjs-lib": "^7.0.0-rc.0",
|
|
54
54
|
"cli-table3": "^0.6.5",
|
|
55
55
|
"crypto-js": "^4.2.0",
|
|
56
|
-
"deepbase": "^1.2
|
|
56
|
+
"deepbase": "^1.5.2",
|
|
57
57
|
"ecpair": "^2.1.0",
|
|
58
58
|
"hdkey": "^2.1.0",
|
|
59
59
|
"inquirer": "^9.3.7",
|
|
File without changes
|