jaelis-node 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/jaelis-node.js +202 -1
- package/lib/index.js +958 -23
- package/lib/vm/index.js +397 -0
- package/package.json +12 -3
package/bin/jaelis-node.js
CHANGED
|
@@ -76,6 +76,7 @@ program
|
|
|
76
76
|
.option('--rpc-host <host>', 'RPC server host', '0.0.0.0')
|
|
77
77
|
.option('--no-rpc', 'Disable RPC server')
|
|
78
78
|
.option('--sync-mode <mode>', 'Sync mode: full, light, archive', 'full')
|
|
79
|
+
.option('--reward-recipient <address>', 'Wallet address to receive node rewards (ANY chain format!)')
|
|
79
80
|
.action(async (options) => {
|
|
80
81
|
console.log(chalk.cyan(BANNER));
|
|
81
82
|
console.log(chalk.green('Starting JAELIS Node...'));
|
|
@@ -94,6 +95,9 @@ program
|
|
|
94
95
|
console.log(chalk.gray(` P2P Port: ${options.p2pPort}`));
|
|
95
96
|
console.log(chalk.gray(` Data Dir: ${options.dataDir}`));
|
|
96
97
|
console.log(chalk.gray(` Sync Mode: ${options.syncMode}`));
|
|
98
|
+
if (options.rewardRecipient) {
|
|
99
|
+
console.log(chalk.gray(` Rewards To: ${options.rewardRecipient}`));
|
|
100
|
+
}
|
|
97
101
|
console.log();
|
|
98
102
|
|
|
99
103
|
const spinner = ora('Initializing node...').start();
|
|
@@ -111,7 +115,8 @@ program
|
|
|
111
115
|
dataDir: options.dataDir,
|
|
112
116
|
syncMode: options.syncMode,
|
|
113
117
|
enableRpc: options.rpc,
|
|
114
|
-
bootstrapNodes: network.bootstrapNodes
|
|
118
|
+
bootstrapNodes: network.bootstrapNodes,
|
|
119
|
+
rewardRecipient: options.rewardRecipient // Like Geth's --suggested-fee-recipient
|
|
115
120
|
});
|
|
116
121
|
|
|
117
122
|
spinner.text = 'Connecting to network...';
|
|
@@ -311,5 +316,201 @@ program
|
|
|
311
316
|
console.log(chalk.cyan('Website: https://jaelis.io'));
|
|
312
317
|
});
|
|
313
318
|
|
|
319
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
320
|
+
// WALLET COMMANDS - Manage node wallet configuration
|
|
321
|
+
// Like Geth's account management, but supports ANY chain address!
|
|
322
|
+
// NO STAKING REQUIRED - JAELIS doesn't hold your funds!
|
|
323
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
324
|
+
|
|
325
|
+
// WALLET SET-RECIPIENT - Set reward recipient address (like Geth --suggested-fee-recipient)
|
|
326
|
+
program
|
|
327
|
+
.command('wallet:set-recipient <address>')
|
|
328
|
+
.description('Set the wallet address to receive node rewards (accepts ANY chain format!)')
|
|
329
|
+
.option('-d, --data-dir <path>', 'Data directory', './jaelis-data')
|
|
330
|
+
.action((address, options) => {
|
|
331
|
+
console.log(chalk.cyan('Setting reward recipient...'));
|
|
332
|
+
console.log();
|
|
333
|
+
|
|
334
|
+
try {
|
|
335
|
+
const { NodeWalletConfig, validateAddress } = require('../lib/index.js');
|
|
336
|
+
|
|
337
|
+
// Validate address format
|
|
338
|
+
const validation = validateAddress(address);
|
|
339
|
+
if (!validation.valid) {
|
|
340
|
+
console.log(chalk.red('✗ Invalid address format'));
|
|
341
|
+
console.log(chalk.gray(' Supported formats:'));
|
|
342
|
+
console.log(chalk.gray(' • EVM (Ethereum, Polygon, etc.): 0x...'));
|
|
343
|
+
console.log(chalk.gray(' • Solana: base58 address'));
|
|
344
|
+
console.log(chalk.gray(' • Bitcoin: 1..., 3..., or bc1...'));
|
|
345
|
+
console.log(chalk.gray(' • TON: base64url address'));
|
|
346
|
+
console.log(chalk.gray(' • Move (Aptos/Sui): 0x... (64 chars)'));
|
|
347
|
+
process.exit(1);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const walletConfig = new NodeWalletConfig(options.dataDir);
|
|
351
|
+
walletConfig.load();
|
|
352
|
+
const result = walletConfig.setRewardRecipient(address);
|
|
353
|
+
|
|
354
|
+
console.log(chalk.green('✓ Reward recipient set successfully!'));
|
|
355
|
+
console.log();
|
|
356
|
+
console.log(chalk.white(' Address: ') + chalk.cyan(result.originalFormat));
|
|
357
|
+
console.log(chalk.white(' Type: ') + chalk.gray(result.typeName));
|
|
358
|
+
console.log();
|
|
359
|
+
console.log(chalk.gray(' Node rewards will be sent to this address.'));
|
|
360
|
+
console.log(chalk.gray(' NO STAKING REQUIRED - you keep your own funds!'));
|
|
361
|
+
|
|
362
|
+
} catch (error) {
|
|
363
|
+
console.log(chalk.red('✗ Failed to set recipient'));
|
|
364
|
+
console.log(chalk.gray(error.message));
|
|
365
|
+
process.exit(1);
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
// WALLET ADD - Add an additional wallet
|
|
370
|
+
program
|
|
371
|
+
.command('wallet:add <name> <address>')
|
|
372
|
+
.description('Add a wallet to this node (accepts ANY chain format!)')
|
|
373
|
+
.option('-d, --data-dir <path>', 'Data directory', './jaelis-data')
|
|
374
|
+
.option('-p, --purpose <purpose>', 'Wallet purpose (general, validator, development)', 'general')
|
|
375
|
+
.action((name, address, options) => {
|
|
376
|
+
console.log(chalk.cyan('Adding wallet...'));
|
|
377
|
+
console.log();
|
|
378
|
+
|
|
379
|
+
try {
|
|
380
|
+
const { NodeWalletConfig, validateAddress } = require('../lib/index.js');
|
|
381
|
+
|
|
382
|
+
const validation = validateAddress(address);
|
|
383
|
+
if (!validation.valid) {
|
|
384
|
+
console.log(chalk.red('✗ Invalid address format'));
|
|
385
|
+
process.exit(1);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
const walletConfig = new NodeWalletConfig(options.dataDir);
|
|
389
|
+
walletConfig.load();
|
|
390
|
+
const result = walletConfig.addWallet(name, address, { purpose: options.purpose });
|
|
391
|
+
|
|
392
|
+
console.log(chalk.green('✓ Wallet added successfully!'));
|
|
393
|
+
console.log();
|
|
394
|
+
console.log(chalk.white(' Name: ') + chalk.cyan(result.name));
|
|
395
|
+
console.log(chalk.white(' Address: ') + chalk.gray(result.originalFormat));
|
|
396
|
+
console.log(chalk.white(' Type: ') + chalk.gray(result.typeName));
|
|
397
|
+
console.log(chalk.white(' Purpose: ') + chalk.gray(result.purpose));
|
|
398
|
+
|
|
399
|
+
} catch (error) {
|
|
400
|
+
console.log(chalk.red('✗ Failed to add wallet'));
|
|
401
|
+
console.log(chalk.gray(error.message));
|
|
402
|
+
process.exit(1);
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
// WALLET REMOVE - Remove a wallet
|
|
407
|
+
program
|
|
408
|
+
.command('wallet:remove <name-or-address>')
|
|
409
|
+
.description('Remove a wallet from this node')
|
|
410
|
+
.option('-d, --data-dir <path>', 'Data directory', './jaelis-data')
|
|
411
|
+
.action((nameOrAddress, options) => {
|
|
412
|
+
console.log(chalk.cyan('Removing wallet...'));
|
|
413
|
+
console.log();
|
|
414
|
+
|
|
415
|
+
try {
|
|
416
|
+
const { NodeWalletConfig } = require('../lib/index.js');
|
|
417
|
+
|
|
418
|
+
const walletConfig = new NodeWalletConfig(options.dataDir);
|
|
419
|
+
walletConfig.load();
|
|
420
|
+
const result = walletConfig.removeWallet(nameOrAddress);
|
|
421
|
+
|
|
422
|
+
console.log(chalk.green('✓ Wallet removed!'));
|
|
423
|
+
console.log(chalk.gray(` Removed: ${result.name} (${result.originalFormat})`));
|
|
424
|
+
|
|
425
|
+
} catch (error) {
|
|
426
|
+
console.log(chalk.red('✗ Failed to remove wallet'));
|
|
427
|
+
console.log(chalk.gray(error.message));
|
|
428
|
+
process.exit(1);
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
// WALLET LIST - List all wallets
|
|
433
|
+
program
|
|
434
|
+
.command('wallet:list')
|
|
435
|
+
.description('List all configured wallets')
|
|
436
|
+
.option('-d, --data-dir <path>', 'Data directory', './jaelis-data')
|
|
437
|
+
.action((options) => {
|
|
438
|
+
console.log(chalk.cyan('Node Wallet Configuration'));
|
|
439
|
+
console.log();
|
|
440
|
+
|
|
441
|
+
try {
|
|
442
|
+
const { NodeWalletConfig } = require('../lib/index.js');
|
|
443
|
+
|
|
444
|
+
const walletConfig = new NodeWalletConfig(options.dataDir);
|
|
445
|
+
const config = walletConfig.listWallets();
|
|
446
|
+
|
|
447
|
+
// Show reward recipient
|
|
448
|
+
if (config.rewardRecipient) {
|
|
449
|
+
console.log(chalk.white('Reward Recipient:'));
|
|
450
|
+
console.log(chalk.green(` ★ ${config.rewardRecipient.originalFormat}`));
|
|
451
|
+
console.log(chalk.gray(` Type: ${config.rewardRecipient.typeName}`));
|
|
452
|
+
console.log();
|
|
453
|
+
} else {
|
|
454
|
+
console.log(chalk.yellow('⚠ No reward recipient set!'));
|
|
455
|
+
console.log(chalk.gray(' Run: jaelis-node wallet:set-recipient <your-address>'));
|
|
456
|
+
console.log();
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// Show additional wallets
|
|
460
|
+
if (config.wallets && config.wallets.length > 0) {
|
|
461
|
+
console.log(chalk.white('Additional Wallets:'));
|
|
462
|
+
config.wallets.forEach((wallet, i) => {
|
|
463
|
+
console.log(chalk.cyan(` ${i + 1}. ${wallet.name}`));
|
|
464
|
+
console.log(chalk.gray(` Address: ${wallet.originalFormat}`));
|
|
465
|
+
console.log(chalk.gray(` Type: ${wallet.typeName}`));
|
|
466
|
+
console.log(chalk.gray(` Purpose: ${wallet.purpose}`));
|
|
467
|
+
});
|
|
468
|
+
} else {
|
|
469
|
+
console.log(chalk.gray('No additional wallets configured.'));
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
console.log();
|
|
473
|
+
console.log(chalk.gray('Supported address formats:'));
|
|
474
|
+
console.log(chalk.gray(' • EVM (Ethereum, Polygon, Arbitrum, Base, etc.)'));
|
|
475
|
+
console.log(chalk.gray(' • Solana (base58)'));
|
|
476
|
+
console.log(chalk.gray(' • Bitcoin (Legacy & SegWit)'));
|
|
477
|
+
console.log(chalk.gray(' • TON'));
|
|
478
|
+
console.log(chalk.gray(' • Move (Aptos/Sui)'));
|
|
479
|
+
|
|
480
|
+
} catch (error) {
|
|
481
|
+
console.log(chalk.red('Failed to list wallets'));
|
|
482
|
+
console.log(chalk.gray(error.message));
|
|
483
|
+
}
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
// WALLET IDENTITY - Show or generate node identity
|
|
487
|
+
program
|
|
488
|
+
.command('wallet:identity')
|
|
489
|
+
.description('Show or generate the node identity (like Solana identity keypair)')
|
|
490
|
+
.option('-d, --data-dir <path>', 'Data directory', './jaelis-data')
|
|
491
|
+
.action((options) => {
|
|
492
|
+
console.log(chalk.cyan('Node Identity'));
|
|
493
|
+
console.log();
|
|
494
|
+
|
|
495
|
+
try {
|
|
496
|
+
const { NodeWalletConfig } = require('../lib/index.js');
|
|
497
|
+
|
|
498
|
+
const walletConfig = new NodeWalletConfig(options.dataDir);
|
|
499
|
+
walletConfig.load();
|
|
500
|
+
const identity = walletConfig.getNodeIdentity();
|
|
501
|
+
|
|
502
|
+
console.log(chalk.white('Node Identity:'));
|
|
503
|
+
console.log(chalk.green(` Public Key: ${identity.publicKey}`));
|
|
504
|
+
console.log(chalk.gray(` Created: ${new Date(identity.createdAt).toISOString()}`));
|
|
505
|
+
console.log();
|
|
506
|
+
console.log(chalk.gray('This identity is used to identify your node on the network.'));
|
|
507
|
+
console.log(chalk.gray('It is NOT a wallet - use wallet:set-recipient for rewards.'));
|
|
508
|
+
|
|
509
|
+
} catch (error) {
|
|
510
|
+
console.log(chalk.red('Failed to get node identity'));
|
|
511
|
+
console.log(chalk.gray(error.message));
|
|
512
|
+
}
|
|
513
|
+
});
|
|
514
|
+
|
|
314
515
|
// Parse and execute
|
|
315
516
|
program.parse();
|