hodl-wallet 1.4.6 β†’ 1.5.4

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
@@ -41,9 +41,19 @@ Keep your favorite addresses handy. No more copy-pasting!
41
41
 
42
42
  ### 🌐 Multi-Network Support
43
43
 
44
- Seamlessly manage your assets on both BEP-20 (Binance Smart Chain) and ERC-20 (Ethereum and Polygon) networks. Switch between networks with ease!
44
+ Seamlessly manage your assets on multiple networks. HODL Wallet supports the following networks:
45
45
 
46
- ### πŸ’Ύ Export and Import HODL Files
46
+ - Binance Smart Chain
47
+ - Ethereum
48
+ - Polygon
49
+ - Optimism
50
+ - Arbitrum One
51
+ - Fantom
52
+ - Avalanche C-Chain
53
+
54
+ Each network supports its native token and popular tokens like USDT. You can easily add more tokens as needed.
55
+
56
+ ## πŸ’Ύ Export and Import HODL Files
47
57
 
48
58
  HODL Wallet now supports exporting and importing encrypted .HODL files, which securely store your wallet information.
49
59
 
@@ -83,6 +93,18 @@ We've carefully selected trusted and well-maintained dependencies for this proje
83
93
 
84
94
  ⚠️ **Important Notice**: HODL Wallet is a personal project created with the best intentions. While we strive for security, it may contain security flaws or vulnerabilities. Use at your own risk and always exercise caution with your crypto assets.
85
95
 
96
+ ## πŸ“˜ What HODL means
97
+
98
+ The term "HODL" is a cornerstone of crypto culture, and it's worth understanding its origins:
99
+
100
+ - πŸŽ‚ Born on December 18, 2013, in a Bitcoin Talk forum post
101
+ - 🍺 Originally a typo for "HOLD" in a drunk, impassioned rant about not selling Bitcoin
102
+ - πŸ”€ Later backronymed to mean "Hold On for Dear Life"
103
+ - πŸ’Ž Symbolizes a long-term investment strategy and resistance to panic selling
104
+ - 🌍 Now used across various cryptocurrency communities as a rallying cry
105
+
106
+ HODL embodies the belief in the long-term potential of cryptocurrencies, often in the face of short-term market volatility. It's more than just a misspelling; it's a philosophy that has shaped the crypto landscape.
107
+
86
108
  ## 🀝 Contributing
87
109
 
88
110
  Found a bug? Want to add a feature? We're all ears! Open an issue or submit a PR. Let's make crypto easier together.
package/index.mjs CHANGED
@@ -36,6 +36,7 @@ class Wallet {
36
36
  this.web3 = null;
37
37
  this.selectedNetwork = null;
38
38
  this.account = null;
39
+ this.networkUsage = this.db.get('networkUsage') || {};
39
40
  }
40
41
 
41
42
  async initialize() {
@@ -84,14 +85,23 @@ class Wallet {
84
85
  }
85
86
 
86
87
  async selectNetwork(networkPlugins) {
88
+ // Sort networks by usage count (descending)
89
+ const sortedNetworks = networkPlugins.sort((a, b) =>
90
+ (this.networkUsage[b.name] || 0) - (this.networkUsage[a.name] || 0)
91
+ );
92
+
87
93
  const { network } = await inquirer.prompt({
88
94
  type: 'list',
89
95
  name: 'network',
90
96
  message: 'Select the network:',
91
- choices: networkPlugins.map(plugin => plugin.name),
97
+ choices: sortedNetworks.map(plugin => plugin.name),
92
98
  });
93
99
 
94
- const selectedNetwork = networkPlugins.find(plugin => plugin.name === network);
100
+ const selectedNetwork = sortedNetworks.find(plugin => plugin.name === network);
101
+
102
+ // Increment usage count for the selected network
103
+ this.networkUsage[network] = (this.networkUsage[network] || 0) + 1;
104
+ this.db.set('networkUsage', this.networkUsage);
95
105
 
96
106
  this.selectedNetwork = selectedNetwork;
97
107
  }
@@ -291,7 +301,12 @@ class Wallet {
291
301
  }
292
302
 
293
303
  async transferFunds() {
294
- const addressBook = this.db.get('addressBook') || [];
304
+ const contacts = this.db.get('contact') || {};
305
+ const addressBook = Object.entries(contacts).map(([address, data]) => ({
306
+ address,
307
+ name: data.name
308
+ }));
309
+
295
310
  addressBook.push({ name: 'Go Back', address: '' });
296
311
 
297
312
  // Implement autocomplete for address book
@@ -327,7 +342,7 @@ class Wallet {
327
342
  const { amount } = await inquirer.prompt({
328
343
  type: 'input',
329
344
  name: 'amount',
330
- message: `Amount to transfer [${token}] (leave empty to cancel):`,
345
+ message: `Amount to transfer:`,
331
346
  validate: value => {
332
347
  if (value === '') return true;
333
348
  return !isNaN(value) && Number(value) > 0 ? true : 'Please enter a valid number or leave empty to cancel.';
@@ -338,6 +353,18 @@ class Wallet {
338
353
  return;
339
354
  }
340
355
 
356
+ // Add confirmation step
357
+ const { confirmTransaction } = await inquirer.prompt({
358
+ type: 'confirm',
359
+ name: 'confirmTransaction',
360
+ message: `Confirm transfer?`,
361
+ default: true
362
+ });
363
+
364
+ if (!confirmTransaction) {
365
+ return;
366
+ }
367
+
341
368
  try {
342
369
  let signedTx;
343
370
  if (tokens[token] && token !== this.selectedNetwork.nativeToken) {
@@ -352,7 +379,7 @@ class Wallet {
352
379
  // Add transaction to history
353
380
  this.addToTransactions(address, token, amount, receipt.transactionHash);
354
381
 
355
- if (!addressBook.some(entry => entry.address === address)) {
382
+ if (!contacts[address]) {
356
383
  await this.addToAddressBook(address);
357
384
  }
358
385
 
@@ -416,7 +443,10 @@ class Wallet {
416
443
 
417
444
  history.forEach(tx => {
418
445
  const date = this.formatDate(tx.timestamp);
419
- table.push([date, tx.recipient, tx.token, parseFloat(tx.amount).toFixed(3)]);
446
+ const contact = this.db.get('contact', tx.recipient);
447
+ const recipient = contact ? `${tx.recipient} (${contact.name})` : tx.recipient;
448
+ const amount = parseFloat(tx.amount).toFixed(3);
449
+ table.push([date, recipient, tx.token, amount]);
420
450
  table.push([{ colSpan: 4, content: this.selectedNetwork.explorer + tx.hash }]);
421
451
  });
422
452
 
@@ -431,9 +461,8 @@ class Wallet {
431
461
  });
432
462
 
433
463
  if (name.trim() !== '') {
434
- let addressBook = this.db.get('addressBook') || [];
435
- addressBook.push({ name, address });
436
- this.db.set('addressBook', addressBook);
464
+
465
+ this.db.set('contact', address, 'name', name);
437
466
 
438
467
  const table = new Table({
439
468
  head: [{ colSpan: 2, content: "Recipient saved to the address book." }],
@@ -536,9 +565,12 @@ class Wallet {
536
565
 
537
566
  const date = this.formatDate(new Date());
538
567
 
568
+ const contact = this.db.get('contact', address);
569
+ const recipient = contact ? `${address} (${contact.name})` : address;
570
+
539
571
  table.push([
540
572
  date,
541
- address,
573
+ recipient,
542
574
  token,
543
575
  parseFloat(amount).toFixed(3)
544
576
  ]);
@@ -822,9 +854,9 @@ while (true) {
822
854
  name: 'action',
823
855
  message: 'What would you like to do?',
824
856
  choices: [
825
- { name: 'Transfer Funds', value: 'transfer' },
857
+ { name: 'Transfer Funds', value: 'transferFunds' },
826
858
  { name: 'Show Balance', value: 'balance' },
827
- { name: 'Show Sent Transfers', value: 'history' },
859
+ { name: 'Show Sent Transfers', value: 'showTransactions' },
828
860
  { name: 'Account Settings', value: 'account' },
829
861
  { name: 'Exit', value: 'exit' }
830
862
  ],
@@ -834,10 +866,10 @@ while (true) {
834
866
  case 'balance':
835
867
  await wallet.showBalance();
836
868
  break;
837
- case 'transfer':
869
+ case 'transferFunds':
838
870
  await wallet.transferFunds();
839
871
  break;
840
- case 'history':
872
+ case 'showTransactions':
841
873
  await wallet.showTransactions();
842
874
  break;
843
875
  case 'account':
package/network/arb.js ADDED
@@ -0,0 +1,10 @@
1
+ module.exports = {
2
+ name: '[ERC-20] Arbitrum One',
3
+ explorer: 'https://arbiscan.io/tx/',
4
+ rpcUrl: 'https://arb1.arbitrum.io/rpc',
5
+ nativeToken: 'ETH',
6
+ tokens: {
7
+ 'USDT': '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9', // USDT on Arbitrum
8
+ 'ARB': '0x0000000000000000000000000000000000000000', // Native ETH on Arbitrum
9
+ },
10
+ };
@@ -0,0 +1,10 @@
1
+ module.exports = {
2
+ name: '[ERC-20] Avalanche C-Chain',
3
+ explorer: 'https://snowtrace.io/tx/',
4
+ rpcUrl: 'https://api.avax.network/ext/bc/C/rpc',
5
+ nativeToken: 'AVAX',
6
+ tokens: {
7
+ 'USDT': '0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7', // USDT.e on Avalanche C-Chain
8
+ 'AVAX': '0x0000000000000000000000000000000000000000', // Native AVAX
9
+ },
10
+ };
package/network/ftm.js ADDED
@@ -0,0 +1,10 @@
1
+ module.exports = {
2
+ name: '[ERC-20] Fantom',
3
+ explorer: 'https://ftmscan.com/tx/',
4
+ rpcUrl: 'https://rpc.ftm.tools/',
5
+ nativeToken: 'FTM',
6
+ tokens: {
7
+ 'USDT': '0x049d68029688eAbF473097a2fC38ef61633A3C7A', // USDT on Fantom
8
+ 'FTM': '0x0000000000000000000000000000000000000000', // Native FTM
9
+ },
10
+ };
package/network/op.js ADDED
@@ -0,0 +1,10 @@
1
+ module.exports = {
2
+ name: '[ERC-20] Optimism',
3
+ explorer: 'https://optimistic.etherscan.io/tx/',
4
+ rpcUrl: 'https://mainnet.optimism.io',
5
+ nativeToken: 'ETH',
6
+ tokens: {
7
+ 'USDT': '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58', // USDT on Optimism
8
+ 'OP': '0x0000000000000000000000000000000000000000',
9
+ },
10
+ };
package/network/pol.js CHANGED
@@ -5,6 +5,7 @@ module.exports = {
5
5
  rpcUrl: 'https://polygon-rpc.com/',
6
6
  nativeToken: 'POL',
7
7
  tokens: {
8
- 'USDT': '0xc2132D05D31c914a87C6611C10748AEb04B58e8F', // DirecciΓ³n del contrato USDT en Polygon
8
+ 'USDT': '0xc2132D05D31c914a87C6611C10748AEb04B58e8F',
9
+ 'POL': '0x0000000000000000000000000000000000000000',
9
10
  },
10
11
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hodl-wallet",
3
- "version": "1.4.6",
3
+ "version": "1.5.4",
4
4
  "description": "🧊 HODL Wallet - Fast CLI crypto wallet!",
5
5
  "author": "Martin Clasen",
6
6
  "repository": {
@@ -39,7 +39,11 @@
39
39
  "evm",
40
40
  "polygon",
41
41
  "matic",
42
- "pol",
42
+ "arbitrum",
43
+ "fantom",
44
+ "optimism",
45
+ "avalanche",
46
+ "avax",
43
47
  "clasen"
44
48
  ],
45
49
  "dependencies": {
@@ -53,4 +57,4 @@
53
57
  "inquirer-fuzzy-path": "^2.3.0",
54
58
  "web3": "^4.13.0"
55
59
  }
56
- }
60
+ }