tetsuo-blockchain-wallet 1.2.3 → 1.2.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/dist/cli.js CHANGED
@@ -94,16 +94,16 @@ function saveWallets(store) {
94
94
  async function createWallet(rl) {
95
95
  const name = await question(rl, 'Wallet name: ');
96
96
  if (!name.trim()) {
97
- console.log(chalk_1.default.red(' Wallet name cannot be empty'));
97
+ console.log(chalk_1.default.red('[ERROR] Wallet name cannot be empty'));
98
98
  return;
99
99
  }
100
100
  try {
101
- console.log(chalk_1.default.yellow(' Generating wallet...'));
101
+ console.log(chalk_1.default.yellow('[...] Generating wallet...'));
102
102
  const wallet = await (0, index_1.generateWallet)();
103
103
  const store = loadWallets();
104
104
  const exists = store.wallets.some(w => w.name === name);
105
105
  if (exists) {
106
- console.log(chalk_1.default.red(' Wallet with this name already exists'));
106
+ console.log(chalk_1.default.red('[ERROR] Wallet with this name already exists'));
107
107
  return;
108
108
  }
109
109
  store.wallets.push({
@@ -118,21 +118,21 @@ async function createWallet(rl) {
118
118
  store.selectedWallet = name;
119
119
  }
120
120
  saveWallets(store);
121
- console.log(chalk_1.default.green(' Wallet created successfully!'));
122
- console.log(chalk_1.default.cyan('\n📝 Mnemonic (BACKUP THIS):'));
121
+ console.log(chalk_1.default.green('[OK] Wallet created successfully!'));
122
+ console.log(chalk_1.default.cyan('\n[NOTE] Mnemonic (BACKUP THIS):'));
123
123
  console.log(chalk_1.default.yellow(wallet.mnemonic));
124
- console.log(chalk_1.default.cyan('\n📍 Address:'));
124
+ console.log(chalk_1.default.cyan('\n[ADDR] Address:'));
125
125
  console.log(chalk_1.default.yellow(wallet.address));
126
126
  }
127
127
  catch (error) {
128
- console.log(chalk_1.default.red(`✗ Error: ${error.message}`));
128
+ console.log(chalk_1.default.red(`[ERROR] Error: ${error.message}`));
129
129
  }
130
130
  }
131
131
  async function importWallet(rl) {
132
132
  const name = await question(rl, 'Wallet name: ');
133
133
  const type = await question(rl, 'Import from (mnemonic/privatekey): ');
134
134
  if (!name.trim()) {
135
- console.log(chalk_1.default.red(' Wallet name cannot be empty'));
135
+ console.log(chalk_1.default.red('[ERROR] Wallet name cannot be empty'));
136
136
  return;
137
137
  }
138
138
  try {
@@ -140,25 +140,25 @@ async function importWallet(rl) {
140
140
  if (type.toLowerCase() === 'mnemonic') {
141
141
  const mnemonic = await question(rl, 'Enter mnemonic (12 words): ');
142
142
  if (!(0, index_1.isValidMnemonic)(mnemonic)) {
143
- console.log(chalk_1.default.red(' Invalid mnemonic'));
143
+ console.log(chalk_1.default.red('[ERROR] Invalid mnemonic'));
144
144
  return;
145
145
  }
146
- console.log(chalk_1.default.yellow(' Importing wallet...'));
146
+ console.log(chalk_1.default.yellow('[...] Importing wallet...'));
147
147
  wallet = await (0, index_1.importFromMnemonic)(mnemonic);
148
148
  }
149
149
  else if (type.toLowerCase() === 'privatekey') {
150
150
  const privateKey = await question(rl, 'Enter private key (hex): ');
151
- console.log(chalk_1.default.yellow(' Importing wallet...'));
151
+ console.log(chalk_1.default.yellow('[...] Importing wallet...'));
152
152
  wallet = (0, index_1.importFromPrivateKey)(privateKey);
153
153
  }
154
154
  else {
155
- console.log(chalk_1.default.red(' Invalid import type'));
155
+ console.log(chalk_1.default.red('[ERROR] Invalid import type'));
156
156
  return;
157
157
  }
158
158
  const store = loadWallets();
159
159
  const exists = store.wallets.some(w => w.name === name);
160
160
  if (exists) {
161
- console.log(chalk_1.default.red(' Wallet with this name already exists'));
161
+ console.log(chalk_1.default.red('[ERROR] Wallet with this name already exists'));
162
162
  return;
163
163
  }
164
164
  store.wallets.push({
@@ -173,12 +173,12 @@ async function importWallet(rl) {
173
173
  store.selectedWallet = name;
174
174
  }
175
175
  saveWallets(store);
176
- console.log(chalk_1.default.green(' Wallet imported successfully!'));
177
- console.log(chalk_1.default.cyan('📍 Address:'));
176
+ console.log(chalk_1.default.green('[OK] Wallet imported successfully!'));
177
+ console.log(chalk_1.default.cyan('[ADDR] Address:'));
178
178
  console.log(chalk_1.default.yellow(wallet.address));
179
179
  }
180
180
  catch (error) {
181
- console.log(chalk_1.default.red(`✗ Error: ${error.message}`));
181
+ console.log(chalk_1.default.red(`[ERROR] Error: ${error.message}`));
182
182
  }
183
183
  }
184
184
  async function listWallets() {
@@ -187,10 +187,10 @@ async function listWallets() {
187
187
  console.log(chalk_1.default.yellow('No wallets found. Create one first!'));
188
188
  return;
189
189
  }
190
- console.log(chalk_1.default.cyan('\n📊 Your Wallets:'));
190
+ console.log(chalk_1.default.cyan('\n[INFO] Your Wallets:'));
191
191
  console.log('─'.repeat(80));
192
192
  store.wallets.forEach((wallet, index) => {
193
- const selected = store.selectedWallet === wallet.name ? ' ' : '';
193
+ const selected = store.selectedWallet === wallet.name ? ' [SELECTED]' : '';
194
194
  const created = new Date(wallet.createdAt).toLocaleDateString();
195
195
  console.log(`${index + 1}. ${chalk_1.default.bold(wallet.name)}${selected}`);
196
196
  console.log(` Address: ${chalk_1.default.green(wallet.address)}`);
@@ -211,24 +211,24 @@ async function selectWallet(rl) {
211
211
  if (index >= 0 && index < store.wallets.length) {
212
212
  store.selectedWallet = store.wallets[index].name;
213
213
  saveWallets(store);
214
- console.log(chalk_1.default.green(`✓ Selected: ${store.wallets[index].name}`));
214
+ console.log(chalk_1.default.green(`[OK] Selected: ${store.wallets[index].name}`));
215
215
  }
216
216
  else {
217
- console.log(chalk_1.default.red(' Invalid selection'));
217
+ console.log(chalk_1.default.red('[ERROR] Invalid selection'));
218
218
  }
219
219
  }
220
220
  async function getBalance() {
221
221
  const store = loadWallets();
222
222
  const wallet = store.wallets.find(w => w.name === store.selectedWallet);
223
223
  if (!wallet) {
224
- console.log(chalk_1.default.red(' No wallet selected'));
224
+ console.log(chalk_1.default.red('[ERROR] No wallet selected'));
225
225
  return;
226
226
  }
227
227
  try {
228
- console.log(chalk_1.default.yellow(' Fetching balance...'));
228
+ console.log(chalk_1.default.yellow('[...] Fetching balance...'));
229
229
  const rpc = (0, index_1.createRPCClient)(RPC_URL);
230
230
  const balance = await rpc.getBalance(wallet.address);
231
- console.log(chalk_1.default.cyan('\n💰 Balance Information:'));
231
+ console.log(chalk_1.default.cyan('\n[BALANCE] Balance Information:'));
232
232
  console.log('─'.repeat(50));
233
233
  console.log(chalk_1.default.yellow(' Wallet: ') + chalk_1.default.white(wallet.name));
234
234
  console.log(chalk_1.default.yellow(' Address: ') + chalk_1.default.white(wallet.address));
@@ -236,27 +236,27 @@ async function getBalance() {
236
236
  console.log('─'.repeat(50));
237
237
  }
238
238
  catch (error) {
239
- console.log(chalk_1.default.red(`✗ Error: ${error.message}`));
239
+ console.log(chalk_1.default.red(`[ERROR] Error: ${error.message}`));
240
240
  }
241
241
  }
242
242
  async function getTransactions() {
243
243
  const store = loadWallets();
244
244
  const wallet = store.wallets.find(w => w.name === store.selectedWallet);
245
245
  if (!wallet) {
246
- console.log(chalk_1.default.red(' No wallet selected'));
246
+ console.log(chalk_1.default.red('[ERROR] No wallet selected'));
247
247
  return;
248
248
  }
249
249
  try {
250
- console.log(chalk_1.default.yellow(' Fetching transactions...'));
250
+ console.log(chalk_1.default.yellow('[...] Fetching transactions...'));
251
251
  const rpc = (0, index_1.createRPCClient)(RPC_URL);
252
252
  const transactions = await rpc.getTransactionHistory(wallet.address);
253
253
  if (transactions.length === 0) {
254
- console.log(chalk_1.default.cyan('\n📋 Transaction History:'));
254
+ console.log(chalk_1.default.cyan('\n[HISTORY] Transaction History:'));
255
255
  console.log(chalk_1.default.yellow(' Wallet: ') + wallet.name);
256
256
  console.log(chalk_1.default.yellow('No transactions found'));
257
257
  return;
258
258
  }
259
- console.log(chalk_1.default.cyan('\n📋 Transaction History:'));
259
+ console.log(chalk_1.default.cyan('\n[HISTORY] Transaction History:'));
260
260
  console.log(chalk_1.default.yellow(' Wallet: ') + wallet.name);
261
261
  console.log('─'.repeat(80));
262
262
  transactions.forEach((tx) => {
@@ -268,17 +268,17 @@ async function getTransactions() {
268
268
  console.log('─'.repeat(80));
269
269
  }
270
270
  catch (error) {
271
- console.log(chalk_1.default.red(`✗ Error: ${error.message}`));
271
+ console.log(chalk_1.default.red(`[ERROR] Error: ${error.message}`));
272
272
  }
273
273
  }
274
274
  async function receiveTokens() {
275
275
  const store = loadWallets();
276
276
  const wallet = store.wallets.find(w => w.name === store.selectedWallet);
277
277
  if (!wallet) {
278
- console.log(chalk_1.default.red(' No wallet selected'));
278
+ console.log(chalk_1.default.red('[ERROR] No wallet selected'));
279
279
  return;
280
280
  }
281
- console.log(chalk_1.default.cyan('\n📍 Receive Address:'));
281
+ console.log(chalk_1.default.cyan('\n[ADDR] Receive Address:'));
282
282
  console.log(chalk_1.default.green(wallet.address));
283
283
  console.log(chalk_1.default.yellow('\nShare this address to receive TETSUO'));
284
284
  }
@@ -286,34 +286,34 @@ async function sendTokens(rl) {
286
286
  const store = loadWallets();
287
287
  const wallet = store.wallets.find(w => w.name === store.selectedWallet);
288
288
  if (!wallet) {
289
- console.log(chalk_1.default.red(' No wallet selected'));
289
+ console.log(chalk_1.default.red('[ERROR] No wallet selected'));
290
290
  return;
291
291
  }
292
292
  const toAddress = await question(rl, 'Recipient address: ');
293
293
  if (!(0, index_1.isValidAddress)(toAddress)) {
294
- console.log(chalk_1.default.red(' Invalid recipient address'));
294
+ console.log(chalk_1.default.red('[ERROR] Invalid recipient address'));
295
295
  return;
296
296
  }
297
297
  const amount = await question(rl, 'Amount (TETSUO): ');
298
298
  const numAmount = parseFloat(amount);
299
299
  if (isNaN(numAmount) || numAmount <= 0) {
300
- console.log(chalk_1.default.red(' Invalid amount'));
300
+ console.log(chalk_1.default.red('[ERROR] Invalid amount'));
301
301
  return;
302
302
  }
303
303
  try {
304
- console.log(chalk_1.default.yellow('\n Preparing transaction...'));
304
+ console.log(chalk_1.default.yellow('\n[...] Preparing transaction...'));
305
305
  const rpc = (0, index_1.createRPCClient)(RPC_URL);
306
306
  // Get UTXOs
307
307
  console.log(chalk_1.default.yellow(' Fetching UTXOs...'));
308
308
  const utxos = await rpc.getUTXOs(wallet.address);
309
309
  if (utxos.length === 0) {
310
- console.log(chalk_1.default.red(' No UTXOs available to spend'));
310
+ console.log(chalk_1.default.red('[ERROR] No UTXOs available to spend'));
311
311
  return;
312
312
  }
313
313
  // Build transaction
314
314
  const txData = (0, index_1.buildTransaction)(wallet.address, toAddress, numAmount, utxos, wallet.address);
315
315
  // Show transaction details
316
- console.log(chalk_1.default.cyan('\n📋 Transaction Details:'));
316
+ console.log(chalk_1.default.cyan('\n[HISTORY] Transaction Details:'));
317
317
  console.log('─'.repeat(60));
318
318
  console.log(chalk_1.default.yellow(' From: ') + wallet.address);
319
319
  console.log(chalk_1.default.yellow(' To: ') + toAddress);
@@ -324,11 +324,11 @@ async function sendTokens(rl) {
324
324
  // Ask for confirmation
325
325
  const confirm = await question(rl, chalk_1.default.cyan('\nConfirm transaction? (yes/no): '));
326
326
  if (confirm.toLowerCase() !== 'yes' && confirm.toLowerCase() !== 'y') {
327
- console.log(chalk_1.default.yellow(' Transaction cancelled'));
327
+ console.log(chalk_1.default.yellow('[CANCEL] Transaction cancelled'));
328
328
  return;
329
329
  }
330
330
  // Create and sign transaction
331
- console.log(chalk_1.default.yellow('\n Signing transaction...'));
331
+ console.log(chalk_1.default.yellow('\n[...] Signing transaction...'));
332
332
  const txHex = (0, index_1.createTransactionHex)(txData.inputs, txData.outputs);
333
333
  const signedTxHex = (0, index_1.signTransaction)(txHex, wallet.privateKey, txData.inputs, utxos);
334
334
  // Broadcast or use server fallback
@@ -343,8 +343,8 @@ async function sendTokens(rl) {
343
343
  // Fallback: Use server to sign and broadcast
344
344
  txid = await rpc.signAndBroadcast(txHex, wallet.privateKey);
345
345
  }
346
- console.log(chalk_1.default.green('\n Transaction sent successfully!'));
347
- console.log(chalk_1.default.cyan('\n📊 Transaction Info:'));
346
+ console.log(chalk_1.default.green('\n[OK] Transaction sent successfully!'));
347
+ console.log(chalk_1.default.cyan('\n[INFO] Transaction Info:'));
348
348
  console.log('─'.repeat(60));
349
349
  console.log(chalk_1.default.yellow(' TXID: ') + chalk_1.default.green(txid));
350
350
  console.log(chalk_1.default.yellow(' Amount: ') + chalk_1.default.green(numAmount.toFixed(8) + ' TETSUO'));
@@ -353,17 +353,17 @@ async function sendTokens(rl) {
353
353
  console.log(chalk_1.default.cyan('\nCheck transaction status at: https://tetsuoarena.com/tx/' + txid));
354
354
  }
355
355
  catch (error) {
356
- console.log(chalk_1.default.red('\n Error: ' + error.message));
356
+ console.log(chalk_1.default.red('\n[ERROR] Error: ' + error.message));
357
357
  }
358
358
  }
359
359
  async function walletData() {
360
360
  const store = loadWallets();
361
361
  const wallet = store.wallets.find(w => w.name === store.selectedWallet);
362
362
  if (!wallet) {
363
- console.log(chalk_1.default.red(' No wallet selected'));
363
+ console.log(chalk_1.default.red('[ERROR] No wallet selected'));
364
364
  return;
365
365
  }
366
- console.log(chalk_1.default.cyan('\n📊 Wallet Data:'));
366
+ console.log(chalk_1.default.cyan('\n[INFO] Wallet Data:'));
367
367
  console.log('─'.repeat(80));
368
368
  console.log(`Name: ${chalk_1.default.yellow(wallet.name)}`);
369
369
  console.log(`Address: ${chalk_1.default.green(wallet.address)}`);
@@ -379,7 +379,7 @@ async function deleteWallet(rl) {
379
379
  const store = loadWallets();
380
380
  const wallet = store.wallets.find(w => w.name === store.selectedWallet);
381
381
  if (!wallet) {
382
- console.log(chalk_1.default.red(' No wallet selected'));
382
+ console.log(chalk_1.default.red('[ERROR] No wallet selected'));
383
383
  return;
384
384
  }
385
385
  const confirm = await question(rl, `Delete ${wallet.name}? (yes/no): `);
@@ -392,17 +392,17 @@ async function deleteWallet(rl) {
392
392
  store.selectedWallet = store.wallets[0]?.name;
393
393
  }
394
394
  saveWallets(store);
395
- console.log(chalk_1.default.green(' Wallet deleted'));
395
+ console.log(chalk_1.default.green('[OK] Wallet deleted'));
396
396
  }
397
397
  async function configureRPC(rl) {
398
398
  const config = loadConfig();
399
- console.log(chalk_1.default.cyan('\n⚙️ RPC Configuration:'));
399
+ console.log(chalk_1.default.cyan('\n[CONFIG] RPC Configuration:'));
400
400
  console.log(`Current RPC URL: ${chalk_1.default.green(RPC_URL)}`);
401
401
  const newUrl = await question(rl, 'Enter new RPC URL (or press Enter to keep current): ');
402
402
  if (newUrl.trim()) {
403
403
  RPC_URL = newUrl.trim();
404
404
  saveConfig({ rpcUrl: RPC_URL });
405
- console.log(chalk_1.default.green(' RPC URL updated!'));
405
+ console.log(chalk_1.default.green('[OK] RPC URL updated!'));
406
406
  console.log(`New URL: ${chalk_1.default.green(RPC_URL)}`);
407
407
  }
408
408
  else {
@@ -423,9 +423,18 @@ async function main() {
423
423
  output: process.stdout
424
424
  });
425
425
  console.clear();
426
- console.log(chalk_1.default.green.bold('\n═══════════════════════════════'));
427
- console.log(chalk_1.default.green.bold(' TETSUO Wallet CLI'));
428
- console.log(chalk_1.default.green.bold('═══════════════════════════════\n'));
426
+ console.log(chalk_1.default.cyan.bold(`
427
+ TTTTTTTTT EEEEEEEE TTTTTTTT SSSSSSS UUUU UUUU OOOOOOO
428
+ TTT EEEE TTT SSSS UUUU UUUU OOOOOOO
429
+ TTT EEEEE TTT SSSSS UUUU UUUU OOOOO
430
+ TTT EEEE TTT SSS UUUU UUUU OOOOOOO
431
+ TTT EEEEEEEE TTT SSSSSSS UUUUUUUU OOOOOOO
432
+
433
+ WALLET : SECURE BLOCKCHAIN TRANSACTIONS
434
+ `));
435
+ console.log(chalk_1.default.cyan.bold('═══════════════════════════════'));
436
+ console.log(chalk_1.default.cyan.bold(' TETSUO BLOCKCHAIN WALLET'));
437
+ console.log(chalk_1.default.cyan.bold('═══════════════════════════════\n'));
429
438
  let running = true;
430
439
  while (running) {
431
440
  const store = loadWallets();
@@ -483,10 +492,10 @@ async function main() {
483
492
  break;
484
493
  case '/exit':
485
494
  running = false;
486
- console.log(chalk_1.default.green('\nGoodbye! 👋\n'));
495
+ console.log(chalk_1.default.green('\nGoodbye! [BYE]\n'));
487
496
  break;
488
497
  default:
489
- console.log(chalk_1.default.red(' Unknown command'));
498
+ console.log(chalk_1.default.red('[ERROR] Unknown command'));
490
499
  }
491
500
  }
492
501
  rl.close();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tetsuo-blockchain-wallet",
3
- "version": "1.2.3",
3
+ "version": "1.2.4",
4
4
  "description": "TypeScript SDK for TETSUO blockchain wallet operations",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/cli.ts CHANGED
@@ -92,18 +92,18 @@ function saveWallets(store: WalletStore) {
92
92
  async function createWallet(rl: readline.Interface): Promise<void> {
93
93
  const name = await question(rl, 'Wallet name: ');
94
94
  if (!name.trim()) {
95
- console.log(chalk.red(' Wallet name cannot be empty'));
95
+ console.log(chalk.red('[ERROR] Wallet name cannot be empty'));
96
96
  return;
97
97
  }
98
98
 
99
99
  try {
100
- console.log(chalk.yellow(' Generating wallet...'));
100
+ console.log(chalk.yellow('[...] Generating wallet...'));
101
101
  const wallet = await generateWallet();
102
102
 
103
103
  const store = loadWallets();
104
104
  const exists = store.wallets.some(w => w.name === name);
105
105
  if (exists) {
106
- console.log(chalk.red(' Wallet with this name already exists'));
106
+ console.log(chalk.red('[ERROR] Wallet with this name already exists'));
107
107
  return;
108
108
  }
109
109
 
@@ -122,13 +122,13 @@ async function createWallet(rl: readline.Interface): Promise<void> {
122
122
 
123
123
  saveWallets(store);
124
124
 
125
- console.log(chalk.green(' Wallet created successfully!'));
126
- console.log(chalk.cyan('\n📝 Mnemonic (BACKUP THIS):'));
125
+ console.log(chalk.green('[OK] Wallet created successfully!'));
126
+ console.log(chalk.cyan('\n[NOTE] Mnemonic (BACKUP THIS):'));
127
127
  console.log(chalk.yellow(wallet.mnemonic));
128
- console.log(chalk.cyan('\n📍 Address:'));
128
+ console.log(chalk.cyan('\n[ADDR] Address:'));
129
129
  console.log(chalk.yellow(wallet.address));
130
130
  } catch (error: any) {
131
- console.log(chalk.red(`✗ Error: ${error.message}`));
131
+ console.log(chalk.red(`[ERROR] Error: ${error.message}`));
132
132
  }
133
133
  }
134
134
 
@@ -137,7 +137,7 @@ async function importWallet(rl: readline.Interface): Promise<void> {
137
137
  const type = await question(rl, 'Import from (mnemonic/privatekey): ');
138
138
 
139
139
  if (!name.trim()) {
140
- console.log(chalk.red(' Wallet name cannot be empty'));
140
+ console.log(chalk.red('[ERROR] Wallet name cannot be empty'));
141
141
  return;
142
142
  }
143
143
 
@@ -147,24 +147,24 @@ async function importWallet(rl: readline.Interface): Promise<void> {
147
147
  if (type.toLowerCase() === 'mnemonic') {
148
148
  const mnemonic = await question(rl, 'Enter mnemonic (12 words): ');
149
149
  if (!isValidMnemonic(mnemonic)) {
150
- console.log(chalk.red(' Invalid mnemonic'));
150
+ console.log(chalk.red('[ERROR] Invalid mnemonic'));
151
151
  return;
152
152
  }
153
- console.log(chalk.yellow(' Importing wallet...'));
153
+ console.log(chalk.yellow('[...] Importing wallet...'));
154
154
  wallet = await importFromMnemonic(mnemonic);
155
155
  } else if (type.toLowerCase() === 'privatekey') {
156
156
  const privateKey = await question(rl, 'Enter private key (hex): ');
157
- console.log(chalk.yellow(' Importing wallet...'));
157
+ console.log(chalk.yellow('[...] Importing wallet...'));
158
158
  wallet = importFromPrivateKey(privateKey);
159
159
  } else {
160
- console.log(chalk.red(' Invalid import type'));
160
+ console.log(chalk.red('[ERROR] Invalid import type'));
161
161
  return;
162
162
  }
163
163
 
164
164
  const store = loadWallets();
165
165
  const exists = store.wallets.some(w => w.name === name);
166
166
  if (exists) {
167
- console.log(chalk.red(' Wallet with this name already exists'));
167
+ console.log(chalk.red('[ERROR] Wallet with this name already exists'));
168
168
  return;
169
169
  }
170
170
 
@@ -182,11 +182,11 @@ async function importWallet(rl: readline.Interface): Promise<void> {
182
182
  }
183
183
 
184
184
  saveWallets(store);
185
- console.log(chalk.green(' Wallet imported successfully!'));
186
- console.log(chalk.cyan('📍 Address:'));
185
+ console.log(chalk.green('[OK] Wallet imported successfully!'));
186
+ console.log(chalk.cyan('[ADDR] Address:'));
187
187
  console.log(chalk.yellow(wallet.address));
188
188
  } catch (error: any) {
189
- console.log(chalk.red(`✗ Error: ${error.message}`));
189
+ console.log(chalk.red(`[ERROR] Error: ${error.message}`));
190
190
  }
191
191
  }
192
192
 
@@ -198,11 +198,11 @@ async function listWallets(): Promise<void> {
198
198
  return;
199
199
  }
200
200
 
201
- console.log(chalk.cyan('\n📊 Your Wallets:'));
201
+ console.log(chalk.cyan('\n[INFO] Your Wallets:'));
202
202
  console.log('─'.repeat(80));
203
203
 
204
204
  store.wallets.forEach((wallet, index) => {
205
- const selected = store.selectedWallet === wallet.name ? ' ' : '';
205
+ const selected = store.selectedWallet === wallet.name ? ' [SELECTED]' : '';
206
206
  const created = new Date(wallet.createdAt).toLocaleDateString();
207
207
  console.log(
208
208
  `${index + 1}. ${chalk.bold(wallet.name)}${selected}`
@@ -230,9 +230,9 @@ async function selectWallet(rl: readline.Interface): Promise<void> {
230
230
  if (index >= 0 && index < store.wallets.length) {
231
231
  store.selectedWallet = store.wallets[index].name;
232
232
  saveWallets(store);
233
- console.log(chalk.green(`✓ Selected: ${store.wallets[index].name}`));
233
+ console.log(chalk.green(`[OK] Selected: ${store.wallets[index].name}`));
234
234
  } else {
235
- console.log(chalk.red(' Invalid selection'));
235
+ console.log(chalk.red('[ERROR] Invalid selection'));
236
236
  }
237
237
  }
238
238
 
@@ -241,23 +241,23 @@ async function getBalance(): Promise<void> {
241
241
  const wallet = store.wallets.find(w => w.name === store.selectedWallet);
242
242
 
243
243
  if (!wallet) {
244
- console.log(chalk.red(' No wallet selected'));
244
+ console.log(chalk.red('[ERROR] No wallet selected'));
245
245
  return;
246
246
  }
247
247
 
248
248
  try {
249
- console.log(chalk.yellow(' Fetching balance...'));
249
+ console.log(chalk.yellow('[...] Fetching balance...'));
250
250
  const rpc = createRPCClient(RPC_URL);
251
251
  const balance = await rpc.getBalance(wallet.address);
252
252
 
253
- console.log(chalk.cyan('\n💰 Balance Information:'));
253
+ console.log(chalk.cyan('\n[BALANCE] Balance Information:'));
254
254
  console.log('─'.repeat(50));
255
255
  console.log(chalk.yellow(' Wallet: ') + chalk.white(wallet.name));
256
256
  console.log(chalk.yellow(' Address: ') + chalk.white(wallet.address));
257
257
  console.log(chalk.yellow(' Balance: ') + chalk.green(`${balance.toFixed(8)} TETSUO`));
258
258
  console.log('─'.repeat(50));
259
259
  } catch (error: any) {
260
- console.log(chalk.red(`✗ Error: ${error.message}`));
260
+ console.log(chalk.red(`[ERROR] Error: ${error.message}`));
261
261
  }
262
262
  }
263
263
 
@@ -266,23 +266,23 @@ async function getTransactions(): Promise<void> {
266
266
  const wallet = store.wallets.find(w => w.name === store.selectedWallet);
267
267
 
268
268
  if (!wallet) {
269
- console.log(chalk.red(' No wallet selected'));
269
+ console.log(chalk.red('[ERROR] No wallet selected'));
270
270
  return;
271
271
  }
272
272
 
273
273
  try {
274
- console.log(chalk.yellow(' Fetching transactions...'));
274
+ console.log(chalk.yellow('[...] Fetching transactions...'));
275
275
  const rpc = createRPCClient(RPC_URL);
276
276
  const transactions = await rpc.getTransactionHistory(wallet.address);
277
277
 
278
278
  if (transactions.length === 0) {
279
- console.log(chalk.cyan('\n📋 Transaction History:'));
279
+ console.log(chalk.cyan('\n[HISTORY] Transaction History:'));
280
280
  console.log(chalk.yellow(' Wallet: ') + wallet.name);
281
281
  console.log(chalk.yellow('No transactions found'));
282
282
  return;
283
283
  }
284
284
 
285
- console.log(chalk.cyan('\n📋 Transaction History:'));
285
+ console.log(chalk.cyan('\n[HISTORY] Transaction History:'));
286
286
  console.log(chalk.yellow(' Wallet: ') + wallet.name);
287
287
  console.log('─'.repeat(80));
288
288
 
@@ -294,7 +294,7 @@ async function getTransactions(): Promise<void> {
294
294
  });
295
295
  console.log('─'.repeat(80));
296
296
  } catch (error: any) {
297
- console.log(chalk.red(`✗ Error: ${error.message}`));
297
+ console.log(chalk.red(`[ERROR] Error: ${error.message}`));
298
298
  }
299
299
  }
300
300
 
@@ -303,11 +303,11 @@ async function receiveTokens(): Promise<void> {
303
303
  const wallet = store.wallets.find(w => w.name === store.selectedWallet);
304
304
 
305
305
  if (!wallet) {
306
- console.log(chalk.red(' No wallet selected'));
306
+ console.log(chalk.red('[ERROR] No wallet selected'));
307
307
  return;
308
308
  }
309
309
 
310
- console.log(chalk.cyan('\n📍 Receive Address:'));
310
+ console.log(chalk.cyan('\n[ADDR] Receive Address:'));
311
311
  console.log(chalk.green(wallet.address));
312
312
  console.log(chalk.yellow('\nShare this address to receive TETSUO'));
313
313
  }
@@ -317,25 +317,25 @@ async function sendTokens(rl: readline.Interface): Promise<void> {
317
317
  const wallet = store.wallets.find(w => w.name === store.selectedWallet);
318
318
 
319
319
  if (!wallet) {
320
- console.log(chalk.red(' No wallet selected'));
320
+ console.log(chalk.red('[ERROR] No wallet selected'));
321
321
  return;
322
322
  }
323
323
 
324
324
  const toAddress = await question(rl, 'Recipient address: ');
325
325
  if (!isValidAddress(toAddress)) {
326
- console.log(chalk.red(' Invalid recipient address'));
326
+ console.log(chalk.red('[ERROR] Invalid recipient address'));
327
327
  return;
328
328
  }
329
329
 
330
330
  const amount = await question(rl, 'Amount (TETSUO): ');
331
331
  const numAmount = parseFloat(amount);
332
332
  if (isNaN(numAmount) || numAmount <= 0) {
333
- console.log(chalk.red(' Invalid amount'));
333
+ console.log(chalk.red('[ERROR] Invalid amount'));
334
334
  return;
335
335
  }
336
336
 
337
337
  try {
338
- console.log(chalk.yellow('\n Preparing transaction...'));
338
+ console.log(chalk.yellow('\n[...] Preparing transaction...'));
339
339
  const rpc = createRPCClient(RPC_URL);
340
340
 
341
341
  // Get UTXOs
@@ -343,7 +343,7 @@ async function sendTokens(rl: readline.Interface): Promise<void> {
343
343
  const utxos = await rpc.getUTXOs(wallet.address);
344
344
 
345
345
  if (utxos.length === 0) {
346
- console.log(chalk.red(' No UTXOs available to spend'));
346
+ console.log(chalk.red('[ERROR] No UTXOs available to spend'));
347
347
  return;
348
348
  }
349
349
 
@@ -351,7 +351,7 @@ async function sendTokens(rl: readline.Interface): Promise<void> {
351
351
  const txData = buildTransaction(wallet.address, toAddress, numAmount, utxos, wallet.address);
352
352
 
353
353
  // Show transaction details
354
- console.log(chalk.cyan('\n📋 Transaction Details:'));
354
+ console.log(chalk.cyan('\n[HISTORY] Transaction Details:'));
355
355
  console.log('─'.repeat(60));
356
356
  console.log(chalk.yellow(' From: ') + wallet.address);
357
357
  console.log(chalk.yellow(' To: ') + toAddress);
@@ -363,12 +363,12 @@ async function sendTokens(rl: readline.Interface): Promise<void> {
363
363
  // Ask for confirmation
364
364
  const confirm = await question(rl, chalk.cyan('\nConfirm transaction? (yes/no): '));
365
365
  if (confirm.toLowerCase() !== 'yes' && confirm.toLowerCase() !== 'y') {
366
- console.log(chalk.yellow(' Transaction cancelled'));
366
+ console.log(chalk.yellow('[CANCEL] Transaction cancelled'));
367
367
  return;
368
368
  }
369
369
 
370
370
  // Create and sign transaction
371
- console.log(chalk.yellow('\n Signing transaction...'));
371
+ console.log(chalk.yellow('\n[...] Signing transaction...'));
372
372
  const txHex = createTransactionHex(txData.inputs, txData.outputs);
373
373
  const signedTxHex = signTransaction(txHex, wallet.privateKey, txData.inputs, utxos);
374
374
 
@@ -384,8 +384,8 @@ async function sendTokens(rl: readline.Interface): Promise<void> {
384
384
  txid = await rpc.signAndBroadcast(txHex, wallet.privateKey);
385
385
  }
386
386
 
387
- console.log(chalk.green('\n Transaction sent successfully!'));
388
- console.log(chalk.cyan('\n📊 Transaction Info:'));
387
+ console.log(chalk.green('\n[OK] Transaction sent successfully!'));
388
+ console.log(chalk.cyan('\n[INFO] Transaction Info:'));
389
389
  console.log('─'.repeat(60));
390
390
  console.log(chalk.yellow(' TXID: ') + chalk.green(txid));
391
391
  console.log(chalk.yellow(' Amount: ') + chalk.green(numAmount.toFixed(8) + ' TETSUO'));
@@ -393,7 +393,7 @@ async function sendTokens(rl: readline.Interface): Promise<void> {
393
393
  console.log('─'.repeat(60));
394
394
  console.log(chalk.cyan('\nCheck transaction status at: https://tetsuoarena.com/tx/' + txid));
395
395
  } catch (error: any) {
396
- console.log(chalk.red('\n Error: ' + error.message));
396
+ console.log(chalk.red('\n[ERROR] Error: ' + error.message));
397
397
  }
398
398
  }
399
399
 
@@ -402,11 +402,11 @@ async function walletData(): Promise<void> {
402
402
  const wallet = store.wallets.find(w => w.name === store.selectedWallet);
403
403
 
404
404
  if (!wallet) {
405
- console.log(chalk.red(' No wallet selected'));
405
+ console.log(chalk.red('[ERROR] No wallet selected'));
406
406
  return;
407
407
  }
408
408
 
409
- console.log(chalk.cyan('\n📊 Wallet Data:'));
409
+ console.log(chalk.cyan('\n[INFO] Wallet Data:'));
410
410
  console.log('─'.repeat(80));
411
411
  console.log(`Name: ${chalk.yellow(wallet.name)}`);
412
412
  console.log(`Address: ${chalk.green(wallet.address)}`);
@@ -424,7 +424,7 @@ async function deleteWallet(rl: readline.Interface): Promise<void> {
424
424
  const wallet = store.wallets.find(w => w.name === store.selectedWallet);
425
425
 
426
426
  if (!wallet) {
427
- console.log(chalk.red(' No wallet selected'));
427
+ console.log(chalk.red('[ERROR] No wallet selected'));
428
428
  return;
429
429
  }
430
430
 
@@ -440,13 +440,13 @@ async function deleteWallet(rl: readline.Interface): Promise<void> {
440
440
  }
441
441
 
442
442
  saveWallets(store);
443
- console.log(chalk.green(' Wallet deleted'));
443
+ console.log(chalk.green('[OK] Wallet deleted'));
444
444
  }
445
445
 
446
446
  async function configureRPC(rl: readline.Interface): Promise<void> {
447
447
  const config = loadConfig();
448
448
 
449
- console.log(chalk.cyan('\n⚙️ RPC Configuration:'));
449
+ console.log(chalk.cyan('\n[CONFIG] RPC Configuration:'));
450
450
  console.log(`Current RPC URL: ${chalk.green(RPC_URL)}`);
451
451
 
452
452
  const newUrl = await question(rl, 'Enter new RPC URL (or press Enter to keep current): ');
@@ -454,7 +454,7 @@ async function configureRPC(rl: readline.Interface): Promise<void> {
454
454
  if (newUrl.trim()) {
455
455
  RPC_URL = newUrl.trim();
456
456
  saveConfig({ rpcUrl: RPC_URL });
457
- console.log(chalk.green(' RPC URL updated!'));
457
+ console.log(chalk.green('[OK] RPC URL updated!'));
458
458
  console.log(`New URL: ${chalk.green(RPC_URL)}`);
459
459
  } else {
460
460
  console.log(chalk.yellow('No changes made'));
@@ -478,9 +478,18 @@ async function main() {
478
478
  });
479
479
 
480
480
  console.clear();
481
- console.log(chalk.green.bold('\n═══════════════════════════════'));
482
- console.log(chalk.green.bold(' TETSUO Wallet CLI'));
483
- console.log(chalk.green.bold('═══════════════════════════════\n'));
481
+ console.log(chalk.cyan.bold(`
482
+ TTTTTTTTT EEEEEEEE TTTTTTTT SSSSSSS UUUU UUUU OOOOOOO
483
+ TTT EEEE TTT SSSS UUUU UUUU OOOOOOO
484
+ TTT EEEEE TTT SSSSS UUUU UUUU OOOOO
485
+ TTT EEEE TTT SSS UUUU UUUU OOOOOOO
486
+ TTT EEEEEEEE TTT SSSSSSS UUUUUUUU OOOOOOO
487
+
488
+ WALLET : SECURE BLOCKCHAIN TRANSACTIONS
489
+ `));
490
+ console.log(chalk.cyan.bold('═══════════════════════════════'));
491
+ console.log(chalk.cyan.bold(' TETSUO BLOCKCHAIN WALLET'));
492
+ console.log(chalk.cyan.bold('═══════════════════════════════\n'));
484
493
 
485
494
  let running = true;
486
495
 
@@ -543,10 +552,10 @@ async function main() {
543
552
  break;
544
553
  case '/exit':
545
554
  running = false;
546
- console.log(chalk.green('\nGoodbye! 👋\n'));
555
+ console.log(chalk.green('\nGoodbye! [BYE]\n'));
547
556
  break;
548
557
  default:
549
- console.log(chalk.red(' Unknown command'));
558
+ console.log(chalk.red('[ERROR] Unknown command'));
550
559
  }
551
560
  }
552
561
 
package/src/cli.ts.bak ADDED
@@ -0,0 +1,569 @@
1
+ #!/usr/bin/env node
2
+
3
+ import * as fs from 'fs';
4
+ import * as path from 'path';
5
+ import * as readline from 'readline';
6
+ import {
7
+ generateWallet,
8
+ importFromMnemonic,
9
+ importFromPrivateKey,
10
+ isValidAddress,
11
+ createRPCClient,
12
+ isValidMnemonic,
13
+ buildTransaction,
14
+ createTransactionHex,
15
+ signTransaction
16
+ } from './index';
17
+ import chalk from 'chalk';
18
+
19
+ // Types
20
+ interface StoredWallet {
21
+ name: string;
22
+ address: string;
23
+ privateKey: string;
24
+ publicKey: string;
25
+ mnemonic?: string;
26
+ createdAt: string;
27
+ }
28
+
29
+ interface WalletStore {
30
+ wallets: StoredWallet[];
31
+ selectedWallet?: string;
32
+ }
33
+
34
+ interface Config {
35
+ rpcUrl: string;
36
+ }
37
+
38
+ // Constants
39
+ const WALLET_DIR = path.join(process.env.HOME || '~', '.tetsuo');
40
+ const WALLET_FILE = path.join(WALLET_DIR, 'wallets.json');
41
+ const CONFIG_FILE = path.join(WALLET_DIR, 'config.json');
42
+ let RPC_URL = process.env.TETSUO_RPC_URL || 'https://tetsuoarena.com';
43
+
44
+ // Load config from storage
45
+ function loadConfig(): Config {
46
+ try {
47
+ if (fs.existsSync(CONFIG_FILE)) {
48
+ const data = fs.readFileSync(CONFIG_FILE, 'utf-8');
49
+ return JSON.parse(data);
50
+ }
51
+ } catch {
52
+ // Fall back to defaults
53
+ }
54
+ return { rpcUrl: RPC_URL };
55
+ }
56
+
57
+ // Save config to storage
58
+ function saveConfig(config: Config) {
59
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
60
+ }
61
+
62
+ // Ensure wallet directory exists
63
+ function initWalletStorage() {
64
+ if (!fs.existsSync(WALLET_DIR)) {
65
+ fs.mkdirSync(WALLET_DIR, { recursive: true });
66
+ }
67
+ if (!fs.existsSync(WALLET_FILE)) {
68
+ fs.writeFileSync(WALLET_FILE, JSON.stringify({ wallets: [] }, null, 2));
69
+ }
70
+
71
+ // Load config and update RPC_URL
72
+ const config = loadConfig();
73
+ RPC_URL = config.rpcUrl;
74
+ }
75
+
76
+ // Load wallets from storage
77
+ function loadWallets(): WalletStore {
78
+ try {
79
+ const data = fs.readFileSync(WALLET_FILE, 'utf-8');
80
+ return JSON.parse(data);
81
+ } catch {
82
+ return { wallets: [] };
83
+ }
84
+ }
85
+
86
+ // Save wallets to storage
87
+ function saveWallets(store: WalletStore) {
88
+ fs.writeFileSync(WALLET_FILE, JSON.stringify(store, null, 2));
89
+ }
90
+
91
+ // CLI Commands
92
+ async function createWallet(rl: readline.Interface): Promise<void> {
93
+ const name = await question(rl, 'Wallet name: ');
94
+ if (!name.trim()) {
95
+ console.log(chalk.red('✗ Wallet name cannot be empty'));
96
+ return;
97
+ }
98
+
99
+ try {
100
+ console.log(chalk.yellow('⏳ Generating wallet...'));
101
+ const wallet = await generateWallet();
102
+
103
+ const store = loadWallets();
104
+ const exists = store.wallets.some(w => w.name === name);
105
+ if (exists) {
106
+ console.log(chalk.red('✗ Wallet with this name already exists'));
107
+ return;
108
+ }
109
+
110
+ store.wallets.push({
111
+ name,
112
+ address: wallet.address,
113
+ privateKey: wallet.privateKey,
114
+ publicKey: wallet.publicKey,
115
+ mnemonic: wallet.mnemonic,
116
+ createdAt: new Date().toISOString()
117
+ });
118
+
119
+ if (!store.selectedWallet) {
120
+ store.selectedWallet = name;
121
+ }
122
+
123
+ saveWallets(store);
124
+
125
+ console.log(chalk.green('✓ Wallet created successfully!'));
126
+ console.log(chalk.cyan('\n📝 Mnemonic (BACKUP THIS):'));
127
+ console.log(chalk.yellow(wallet.mnemonic));
128
+ console.log(chalk.cyan('\n📍 Address:'));
129
+ console.log(chalk.yellow(wallet.address));
130
+ } catch (error: any) {
131
+ console.log(chalk.red(`✗ Error: ${error.message}`));
132
+ }
133
+ }
134
+
135
+ async function importWallet(rl: readline.Interface): Promise<void> {
136
+ const name = await question(rl, 'Wallet name: ');
137
+ const type = await question(rl, 'Import from (mnemonic/privatekey): ');
138
+
139
+ if (!name.trim()) {
140
+ console.log(chalk.red('✗ Wallet name cannot be empty'));
141
+ return;
142
+ }
143
+
144
+ try {
145
+ let wallet;
146
+
147
+ if (type.toLowerCase() === 'mnemonic') {
148
+ const mnemonic = await question(rl, 'Enter mnemonic (12 words): ');
149
+ if (!isValidMnemonic(mnemonic)) {
150
+ console.log(chalk.red('✗ Invalid mnemonic'));
151
+ return;
152
+ }
153
+ console.log(chalk.yellow('⏳ Importing wallet...'));
154
+ wallet = await importFromMnemonic(mnemonic);
155
+ } else if (type.toLowerCase() === 'privatekey') {
156
+ const privateKey = await question(rl, 'Enter private key (hex): ');
157
+ console.log(chalk.yellow('⏳ Importing wallet...'));
158
+ wallet = importFromPrivateKey(privateKey);
159
+ } else {
160
+ console.log(chalk.red('✗ Invalid import type'));
161
+ return;
162
+ }
163
+
164
+ const store = loadWallets();
165
+ const exists = store.wallets.some(w => w.name === name);
166
+ if (exists) {
167
+ console.log(chalk.red('✗ Wallet with this name already exists'));
168
+ return;
169
+ }
170
+
171
+ store.wallets.push({
172
+ name,
173
+ address: wallet.address,
174
+ privateKey: wallet.privateKey,
175
+ publicKey: wallet.publicKey,
176
+ mnemonic: (wallet as any).mnemonic,
177
+ createdAt: new Date().toISOString()
178
+ });
179
+
180
+ if (!store.selectedWallet) {
181
+ store.selectedWallet = name;
182
+ }
183
+
184
+ saveWallets(store);
185
+ console.log(chalk.green('✓ Wallet imported successfully!'));
186
+ console.log(chalk.cyan('📍 Address:'));
187
+ console.log(chalk.yellow(wallet.address));
188
+ } catch (error: any) {
189
+ console.log(chalk.red(`✗ Error: ${error.message}`));
190
+ }
191
+ }
192
+
193
+ async function listWallets(): Promise<void> {
194
+ const store = loadWallets();
195
+
196
+ if (store.wallets.length === 0) {
197
+ console.log(chalk.yellow('No wallets found. Create one first!'));
198
+ return;
199
+ }
200
+
201
+ console.log(chalk.cyan('\n📊 Your Wallets:'));
202
+ console.log('─'.repeat(80));
203
+
204
+ store.wallets.forEach((wallet, index) => {
205
+ const selected = store.selectedWallet === wallet.name ? ' ✓' : '';
206
+ const created = new Date(wallet.createdAt).toLocaleDateString();
207
+ console.log(
208
+ `${index + 1}. ${chalk.bold(wallet.name)}${selected}`
209
+ );
210
+ console.log(` Address: ${chalk.green(wallet.address)}`);
211
+ console.log(` Created: ${created}`);
212
+ });
213
+ console.log('─'.repeat(80));
214
+ }
215
+
216
+ async function selectWallet(rl: readline.Interface): Promise<void> {
217
+ const store = loadWallets();
218
+
219
+ if (store.wallets.length === 0) {
220
+ console.log(chalk.yellow('No wallets found'));
221
+ return;
222
+ }
223
+
224
+ console.log(chalk.cyan('\nAvailable wallets:'));
225
+ store.wallets.forEach((w, i) => console.log(`${i + 1}. ${w.name}`));
226
+
227
+ const choice = await question(rl, 'Select wallet (number): ');
228
+ const index = parseInt(choice) - 1;
229
+
230
+ if (index >= 0 && index < store.wallets.length) {
231
+ store.selectedWallet = store.wallets[index].name;
232
+ saveWallets(store);
233
+ console.log(chalk.green(`✓ Selected: ${store.wallets[index].name}`));
234
+ } else {
235
+ console.log(chalk.red('✗ Invalid selection'));
236
+ }
237
+ }
238
+
239
+ async function getBalance(): Promise<void> {
240
+ const store = loadWallets();
241
+ const wallet = store.wallets.find(w => w.name === store.selectedWallet);
242
+
243
+ if (!wallet) {
244
+ console.log(chalk.red('✗ No wallet selected'));
245
+ return;
246
+ }
247
+
248
+ try {
249
+ console.log(chalk.yellow('⏳ Fetching balance...'));
250
+ const rpc = createRPCClient(RPC_URL);
251
+ const balance = await rpc.getBalance(wallet.address);
252
+
253
+ console.log(chalk.cyan('\n💰 Balance Information:'));
254
+ console.log('─'.repeat(50));
255
+ console.log(chalk.yellow(' Wallet: ') + chalk.white(wallet.name));
256
+ console.log(chalk.yellow(' Address: ') + chalk.white(wallet.address));
257
+ console.log(chalk.yellow(' Balance: ') + chalk.green(`${balance.toFixed(8)} TETSUO`));
258
+ console.log('─'.repeat(50));
259
+ } catch (error: any) {
260
+ console.log(chalk.red(`✗ Error: ${error.message}`));
261
+ }
262
+ }
263
+
264
+ async function getTransactions(): Promise<void> {
265
+ const store = loadWallets();
266
+ const wallet = store.wallets.find(w => w.name === store.selectedWallet);
267
+
268
+ if (!wallet) {
269
+ console.log(chalk.red('✗ No wallet selected'));
270
+ return;
271
+ }
272
+
273
+ try {
274
+ console.log(chalk.yellow('⏳ Fetching transactions...'));
275
+ const rpc = createRPCClient(RPC_URL);
276
+ const transactions = await rpc.getTransactionHistory(wallet.address);
277
+
278
+ if (transactions.length === 0) {
279
+ console.log(chalk.cyan('\n📋 Transaction History:'));
280
+ console.log(chalk.yellow(' Wallet: ') + wallet.name);
281
+ console.log(chalk.yellow('No transactions found'));
282
+ return;
283
+ }
284
+
285
+ console.log(chalk.cyan('\n📋 Transaction History:'));
286
+ console.log(chalk.yellow(' Wallet: ') + wallet.name);
287
+ console.log('─'.repeat(80));
288
+
289
+ transactions.forEach((tx: any) => {
290
+ const type = tx.isIncoming ? chalk.green('↓ RECEIVE') : chalk.yellow('↑ SEND');
291
+ const date = new Date(tx.timestamp).toLocaleDateString();
292
+ const feeStr = tx.fee ? ` | Fee: ${tx.fee}` : '';
293
+ console.log(`${type} | ${tx.amount.toFixed(8)} TETSUO | Confirmations: ${tx.confirmations}${feeStr} | ${date}`);
294
+ });
295
+ console.log('─'.repeat(80));
296
+ } catch (error: any) {
297
+ console.log(chalk.red(`✗ Error: ${error.message}`));
298
+ }
299
+ }
300
+
301
+ async function receiveTokens(): Promise<void> {
302
+ const store = loadWallets();
303
+ const wallet = store.wallets.find(w => w.name === store.selectedWallet);
304
+
305
+ if (!wallet) {
306
+ console.log(chalk.red('✗ No wallet selected'));
307
+ return;
308
+ }
309
+
310
+ console.log(chalk.cyan('\n📍 Receive Address:'));
311
+ console.log(chalk.green(wallet.address));
312
+ console.log(chalk.yellow('\nShare this address to receive TETSUO'));
313
+ }
314
+
315
+ async function sendTokens(rl: readline.Interface): Promise<void> {
316
+ const store = loadWallets();
317
+ const wallet = store.wallets.find(w => w.name === store.selectedWallet);
318
+
319
+ if (!wallet) {
320
+ console.log(chalk.red('✗ No wallet selected'));
321
+ return;
322
+ }
323
+
324
+ const toAddress = await question(rl, 'Recipient address: ');
325
+ if (!isValidAddress(toAddress)) {
326
+ console.log(chalk.red('✗ Invalid recipient address'));
327
+ return;
328
+ }
329
+
330
+ const amount = await question(rl, 'Amount (TETSUO): ');
331
+ const numAmount = parseFloat(amount);
332
+ if (isNaN(numAmount) || numAmount <= 0) {
333
+ console.log(chalk.red('✗ Invalid amount'));
334
+ return;
335
+ }
336
+
337
+ try {
338
+ console.log(chalk.yellow('\n⏳ Preparing transaction...'));
339
+ const rpc = createRPCClient(RPC_URL);
340
+
341
+ // Get UTXOs
342
+ console.log(chalk.yellow(' Fetching UTXOs...'));
343
+ const utxos = await rpc.getUTXOs(wallet.address);
344
+
345
+ if (utxos.length === 0) {
346
+ console.log(chalk.red('✗ No UTXOs available to spend'));
347
+ return;
348
+ }
349
+
350
+ // Build transaction
351
+ const txData = buildTransaction(wallet.address, toAddress, numAmount, utxos, wallet.address);
352
+
353
+ // Show transaction details
354
+ console.log(chalk.cyan('\n📋 Transaction Details:'));
355
+ console.log('─'.repeat(60));
356
+ console.log(chalk.yellow(' From: ') + wallet.address);
357
+ console.log(chalk.yellow(' To: ') + toAddress);
358
+ console.log(chalk.yellow(' Amount: ') + chalk.green(numAmount.toFixed(8) + ' TETSUO'));
359
+ console.log(chalk.yellow(' Fee: ') + chalk.yellow((txData.fee / 100_000_000).toFixed(8) + ' TETSUO'));
360
+ console.log(chalk.yellow(' Total: ') + chalk.cyan((numAmount + txData.fee / 100_000_000).toFixed(8) + ' TETSUO'));
361
+ console.log('─'.repeat(60));
362
+
363
+ // Ask for confirmation
364
+ const confirm = await question(rl, chalk.cyan('\nConfirm transaction? (yes/no): '));
365
+ if (confirm.toLowerCase() !== 'yes' && confirm.toLowerCase() !== 'y') {
366
+ console.log(chalk.yellow('❌ Transaction cancelled'));
367
+ return;
368
+ }
369
+
370
+ // Create and sign transaction
371
+ console.log(chalk.yellow('\n⏳ Signing transaction...'));
372
+ const txHex = createTransactionHex(txData.inputs, txData.outputs);
373
+ const signedTxHex = signTransaction(txHex, wallet.privateKey, txData.inputs, utxos);
374
+
375
+ // Broadcast or use server fallback
376
+ console.log(chalk.yellow(' Broadcasting...'));
377
+ let txid: string;
378
+ try {
379
+ // Try broadcasting signed transaction
380
+ txid = await rpc.broadcastTransaction(signedTxHex);
381
+ } catch (broadcastError: any) {
382
+ console.log(chalk.yellow(' Client signing verification failed, using server signature...'));
383
+ // Fallback: Use server to sign and broadcast
384
+ txid = await rpc.signAndBroadcast(txHex, wallet.privateKey);
385
+ }
386
+
387
+ console.log(chalk.green('\n✅ Transaction sent successfully!'));
388
+ console.log(chalk.cyan('\n📊 Transaction Info:'));
389
+ console.log('─'.repeat(60));
390
+ console.log(chalk.yellow(' TXID: ') + chalk.green(txid));
391
+ console.log(chalk.yellow(' Amount: ') + chalk.green(numAmount.toFixed(8) + ' TETSUO'));
392
+ console.log(chalk.yellow(' Fee: ') + chalk.yellow((txData.fee / 100_000_000).toFixed(8) + ' TETSUO'));
393
+ console.log('─'.repeat(60));
394
+ console.log(chalk.cyan('\nCheck transaction status at: https://tetsuoarena.com/tx/' + txid));
395
+ } catch (error: any) {
396
+ console.log(chalk.red('\n✗ Error: ' + error.message));
397
+ }
398
+ }
399
+
400
+ async function walletData(): Promise<void> {
401
+ const store = loadWallets();
402
+ const wallet = store.wallets.find(w => w.name === store.selectedWallet);
403
+
404
+ if (!wallet) {
405
+ console.log(chalk.red('✗ No wallet selected'));
406
+ return;
407
+ }
408
+
409
+ console.log(chalk.cyan('\n📊 Wallet Data:'));
410
+ console.log('─'.repeat(80));
411
+ console.log(`Name: ${chalk.yellow(wallet.name)}`);
412
+ console.log(`Address: ${chalk.green(wallet.address)}`);
413
+ console.log(`Public Key: ${chalk.blue(wallet.publicKey)}`);
414
+ console.log(`Created: ${new Date(wallet.createdAt).toLocaleString()}`);
415
+ if (wallet.mnemonic) {
416
+ console.log(chalk.yellow('\nMnemonic (keep safe):'));
417
+ console.log(chalk.red(wallet.mnemonic));
418
+ }
419
+ console.log('─'.repeat(80));
420
+ }
421
+
422
+ async function deleteWallet(rl: readline.Interface): Promise<void> {
423
+ const store = loadWallets();
424
+ const wallet = store.wallets.find(w => w.name === store.selectedWallet);
425
+
426
+ if (!wallet) {
427
+ console.log(chalk.red('✗ No wallet selected'));
428
+ return;
429
+ }
430
+
431
+ const confirm = await question(rl, `Delete ${wallet.name}? (yes/no): `);
432
+ if (confirm.toLowerCase() !== 'yes') {
433
+ console.log(chalk.yellow('Cancelled'));
434
+ return;
435
+ }
436
+
437
+ store.wallets = store.wallets.filter(w => w.name !== wallet.name);
438
+ if (store.selectedWallet === wallet.name) {
439
+ store.selectedWallet = store.wallets[0]?.name;
440
+ }
441
+
442
+ saveWallets(store);
443
+ console.log(chalk.green('✓ Wallet deleted'));
444
+ }
445
+
446
+ async function configureRPC(rl: readline.Interface): Promise<void> {
447
+ const config = loadConfig();
448
+
449
+ console.log(chalk.cyan('\n⚙️ RPC Configuration:'));
450
+ console.log(`Current RPC URL: ${chalk.green(RPC_URL)}`);
451
+
452
+ const newUrl = await question(rl, 'Enter new RPC URL (or press Enter to keep current): ');
453
+
454
+ if (newUrl.trim()) {
455
+ RPC_URL = newUrl.trim();
456
+ saveConfig({ rpcUrl: RPC_URL });
457
+ console.log(chalk.green('✓ RPC URL updated!'));
458
+ console.log(`New URL: ${chalk.green(RPC_URL)}`);
459
+ } else {
460
+ console.log(chalk.yellow('No changes made'));
461
+ }
462
+ }
463
+
464
+ // Helper to get user input
465
+ function question(rl: readline.Interface, prompt: string): Promise<string> {
466
+ return new Promise(resolve => {
467
+ rl.question(chalk.cyan(prompt), resolve);
468
+ });
469
+ }
470
+
471
+ // Main CLI Loop
472
+ async function main() {
473
+ initWalletStorage();
474
+
475
+ const rl = readline.createInterface({
476
+ input: process.stdin,
477
+ output: process.stdout
478
+ });
479
+
480
+ console.clear();
481
+ console.log(chalk.cyan.bold(`
482
+ TTTTTTTTT EEEEEEEE TTTTTTTT SSSSSSS UUUU UUUU OOOOOOO
483
+ TTT EEEE TTT SSSS UUUU UUUU OOOOOOO
484
+ TTT EEEEE TTT SSSSS UUUU UUUU OOOOO
485
+ TTT EEEE TTT SSS UUUU UUUU OOOOOOO
486
+ TTT EEEEEEEE TTT SSSSSSS UUUUUUUU OOOOOOO
487
+
488
+ WALLET : SECURE BLOCKCHAIN TRANSACTIONS
489
+ `));
490
+ console.log(chalk.cyan.bold('═══════════════════════════════'));
491
+ console.log(chalk.cyan.bold(' TETSUO BLOCKCHAIN WALLET'));
492
+ console.log(chalk.cyan.bold('═══════════════════════════════\n'));
493
+
494
+ let running = true;
495
+
496
+ while (running) {
497
+ const store = loadWallets();
498
+ const selected = store.selectedWallet
499
+ ? chalk.green(`[${store.selectedWallet}]`)
500
+ : chalk.red('[No Wallet Selected]');
501
+
502
+ console.log(`\n${selected} Commands:`);
503
+ console.log('/create-wallet - Create new wallet');
504
+ console.log('/import-wallet - Import from mnemonic or private key');
505
+ console.log('/list-wallets - Show all wallets');
506
+ console.log('/select-wallet - Select active wallet');
507
+ console.log('/balance - Check balance');
508
+ console.log('/transactions - View transaction history');
509
+ console.log('/receive - Show receive address');
510
+ console.log('/send - Send tokens');
511
+ console.log('/wallet-data - View wallet details');
512
+ console.log('/delete-wallet - Delete wallet');
513
+ console.log('/config - Configure RPC URL');
514
+ console.log('/exit - Exit CLI\n');
515
+
516
+ const input = await question(rl, 'Command: ');
517
+ const command = input.toLowerCase().trim();
518
+
519
+ switch (command) {
520
+ case '/create-wallet':
521
+ await createWallet(rl);
522
+ break;
523
+ case '/import-wallet':
524
+ await importWallet(rl);
525
+ break;
526
+ case '/list-wallets':
527
+ await listWallets();
528
+ break;
529
+ case '/select-wallet':
530
+ await selectWallet(rl);
531
+ break;
532
+ case '/balance':
533
+ await getBalance();
534
+ break;
535
+ case '/transactions':
536
+ await getTransactions();
537
+ break;
538
+ case '/receive':
539
+ await receiveTokens();
540
+ break;
541
+ case '/send':
542
+ await sendTokens(rl);
543
+ break;
544
+ case '/wallet-data':
545
+ await walletData();
546
+ break;
547
+ case '/delete-wallet':
548
+ await deleteWallet(rl);
549
+ break;
550
+ case '/config':
551
+ await configureRPC(rl);
552
+ break;
553
+ case '/exit':
554
+ running = false;
555
+ console.log(chalk.green('\nGoodbye! 👋\n'));
556
+ break;
557
+ default:
558
+ console.log(chalk.red('✗ Unknown command'));
559
+ }
560
+ }
561
+
562
+ rl.close();
563
+ process.exit(0);
564
+ }
565
+
566
+ main().catch(error => {
567
+ console.error(chalk.red('Fatal error:'), error);
568
+ process.exit(1);
569
+ });