clawrtc 1.2.0 → 1.4.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/clawrtc.js +159 -1
- package/package.json +4 -4
package/bin/clawrtc.js
CHANGED
|
@@ -22,7 +22,7 @@ const os = require('os');
|
|
|
22
22
|
const path = require('path');
|
|
23
23
|
const readline = require('readline');
|
|
24
24
|
|
|
25
|
-
const VERSION = '1.
|
|
25
|
+
const VERSION = '1.4.0';
|
|
26
26
|
const INSTALL_DIR = path.join(os.homedir(), '.clawrtc');
|
|
27
27
|
const VENV_DIR = path.join(INSTALL_DIR, 'venv');
|
|
28
28
|
const NODE_URL = 'https://bulbous-bouffant.metalseed.net';
|
|
@@ -263,6 +263,20 @@ ${R}${B} ╔══════════════════════
|
|
|
263
263
|
warn('Could not reach network (node may be temporarily unavailable)');
|
|
264
264
|
}
|
|
265
265
|
|
|
266
|
+
// Anonymous install telemetry — fire-and-forget, no PII
|
|
267
|
+
try {
|
|
268
|
+
const payload = JSON.stringify({
|
|
269
|
+
package: 'clawrtc', version: VERSION,
|
|
270
|
+
platform: os.platform(), arch: os.arch(), source: 'npm'
|
|
271
|
+
});
|
|
272
|
+
const req = https.request('https://bottube.ai/api/telemetry/install', {
|
|
273
|
+
method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload) },
|
|
274
|
+
timeout: 5000
|
|
275
|
+
});
|
|
276
|
+
req.on('error', () => {});
|
|
277
|
+
req.end(payload);
|
|
278
|
+
} catch (e) {}
|
|
279
|
+
|
|
266
280
|
console.log(`
|
|
267
281
|
${G}${B}═══════════════════════════════════════════════════════════
|
|
268
282
|
ClawRTC installed! Your agent is ready to mine RTC.
|
|
@@ -455,6 +469,144 @@ function cmdLogs() {
|
|
|
455
469
|
}
|
|
456
470
|
}
|
|
457
471
|
|
|
472
|
+
// ═══ WALLET COMMANDS ═══
|
|
473
|
+
const WALLET_DIR = path.join(INSTALL_DIR, 'wallets');
|
|
474
|
+
const WALLET_FILE = path.join(WALLET_DIR, 'default.json');
|
|
475
|
+
|
|
476
|
+
function loadWallet() {
|
|
477
|
+
try { return JSON.parse(fs.readFileSync(WALLET_FILE, 'utf8')); }
|
|
478
|
+
catch (e) { return null; }
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
function deriveRTCAddress(pubKeyBytes) {
|
|
482
|
+
return 'RTC' + crypto.createHash('sha256').update(pubKeyBytes).digest('hex').slice(0, 40);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
async function cmdWallet(action) {
|
|
486
|
+
if (action === 'create') await walletCreate();
|
|
487
|
+
else if (action === 'show') walletShow();
|
|
488
|
+
else if (action === 'export') walletExport();
|
|
489
|
+
else { walletShow(); }
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
async function walletCreate() {
|
|
493
|
+
const existing = loadWallet();
|
|
494
|
+
if (existing && !args.includes('--force')) {
|
|
495
|
+
console.log(`\n ${Y}You already have an RTC wallet:${NC}`);
|
|
496
|
+
console.log(` ${G}${B}${existing.address}${NC}\n`);
|
|
497
|
+
console.log(` To create a new one (REPLACES existing), use:`);
|
|
498
|
+
console.log(` clawrtc wallet create --force\n`);
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
log('Generating Ed25519 keypair...');
|
|
503
|
+
const { generateKeyPairSync } = crypto;
|
|
504
|
+
const { publicKey, privateKey } = generateKeyPairSync('ed25519');
|
|
505
|
+
|
|
506
|
+
const pubRaw = publicKey.export({ type: 'spki', format: 'der' });
|
|
507
|
+
// Ed25519 SPKI DER has 12-byte header, raw key starts at offset 12
|
|
508
|
+
const pubBytes = pubRaw.slice(12);
|
|
509
|
+
const privDer = privateKey.export({ type: 'pkcs8', format: 'der' });
|
|
510
|
+
// Ed25519 PKCS8 DER has 16-byte header, raw key starts at offset 16
|
|
511
|
+
const privBytes = privDer.slice(16);
|
|
512
|
+
|
|
513
|
+
const address = deriveRTCAddress(pubBytes);
|
|
514
|
+
|
|
515
|
+
const walletData = {
|
|
516
|
+
address,
|
|
517
|
+
public_key: pubBytes.toString('hex'),
|
|
518
|
+
private_key: privBytes.toString('hex'),
|
|
519
|
+
created: new Date().toISOString(),
|
|
520
|
+
curve: 'Ed25519',
|
|
521
|
+
network: 'rustchain-mainnet',
|
|
522
|
+
};
|
|
523
|
+
|
|
524
|
+
fs.mkdirSync(WALLET_DIR, { recursive: true });
|
|
525
|
+
fs.writeFileSync(WALLET_FILE, JSON.stringify(walletData, null, 2));
|
|
526
|
+
fs.chmodSync(WALLET_FILE, 0o600);
|
|
527
|
+
|
|
528
|
+
// Also update .wallet for miner
|
|
529
|
+
fs.mkdirSync(INSTALL_DIR, { recursive: true });
|
|
530
|
+
fs.writeFileSync(path.join(INSTALL_DIR, '.wallet'), address);
|
|
531
|
+
|
|
532
|
+
console.log(`
|
|
533
|
+
${G}${B}═══════════════════════════════════════════════════════════
|
|
534
|
+
RTC WALLET CREATED
|
|
535
|
+
═══════════════════════════════════════════════════════════${NC}
|
|
536
|
+
|
|
537
|
+
${G}Address (PUBLIC — paste this in bounty claims):${NC}
|
|
538
|
+
${B}${address}${NC}
|
|
539
|
+
|
|
540
|
+
${R}Private key saved to:${NC}
|
|
541
|
+
${D}${WALLET_FILE}${NC}
|
|
542
|
+
|
|
543
|
+
${R}${B} ╔══════════════════════════════════════════════════════╗
|
|
544
|
+
║ SAVE YOUR PRIVATE KEY — IT CANNOT BE RECOVERED! ║
|
|
545
|
+
║ Anyone with this key can spend your RTC. ║
|
|
546
|
+
╚══════════════════════════════════════════════════════╝${NC}
|
|
547
|
+
|
|
548
|
+
${C}Next steps:${NC}
|
|
549
|
+
1. Copy your ${B}RTC...${NC} address above
|
|
550
|
+
2. Paste it in GitHub bounty claims
|
|
551
|
+
3. Start mining: clawrtc start
|
|
552
|
+
4. Check balance: clawrtc wallet show
|
|
553
|
+
|
|
554
|
+
${D}This is NOT a Solana/ETH/BTC address.
|
|
555
|
+
For wRTC on Solana, bridge at https://bottube.ai/bridge${NC}
|
|
556
|
+
`);
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
function walletShow() {
|
|
560
|
+
const wallet = loadWallet();
|
|
561
|
+
if (!wallet) {
|
|
562
|
+
console.log(`\n ${Y}No RTC wallet found.${NC}`);
|
|
563
|
+
console.log(` Create one: clawrtc wallet create`);
|
|
564
|
+
console.log(` Or generate online: https://rustchain.org/wallet.html\n`);
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
console.log(`\n ${G}${B}RTC Address:${NC} ${B}${wallet.address}${NC}`);
|
|
569
|
+
console.log(` ${D}Public Key:${NC} ${D}${wallet.public_key}${NC}`);
|
|
570
|
+
console.log(` ${D}Created:${NC} ${D}${wallet.created || 'unknown'}${NC}`);
|
|
571
|
+
console.log(` ${D}Curve:${NC} ${D}${wallet.curve || 'Ed25519'}${NC}`);
|
|
572
|
+
console.log(` ${D}Key File:${NC} ${D}${WALLET_FILE}${NC}`);
|
|
573
|
+
|
|
574
|
+
// Check balance
|
|
575
|
+
https.get(`${NODE_URL}/api/balance?wallet=${wallet.address}`, (res) => {
|
|
576
|
+
let d = '';
|
|
577
|
+
res.on('data', c => d += c);
|
|
578
|
+
res.on('end', () => {
|
|
579
|
+
try {
|
|
580
|
+
const data = JSON.parse(d);
|
|
581
|
+
const bal = data.balance_rtc || data.balance || 0;
|
|
582
|
+
console.log(` ${G}Balance:${NC} ${G}${B}${bal} RTC${NC}\n`);
|
|
583
|
+
} catch (e) { console.log(` ${D}Balance:${NC} ${D}(could not parse)${NC}\n`); }
|
|
584
|
+
});
|
|
585
|
+
}).on('error', () => { console.log(` ${D}Balance:${NC} ${D}(could not reach network)${NC}\n`); });
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
function walletExport() {
|
|
589
|
+
const wallet = loadWallet();
|
|
590
|
+
if (!wallet) {
|
|
591
|
+
console.log(`\n ${Y}No wallet to export. Create one first:${NC}`);
|
|
592
|
+
console.log(` clawrtc wallet create\n`);
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
const pubOnly = args.includes('--public-only');
|
|
597
|
+
const outIdx = args.indexOf('-o') >= 0 ? args.indexOf('-o') : args.indexOf('--output');
|
|
598
|
+
const outPath = outIdx >= 0 ? args[outIdx + 1] : `rtc-wallet-${wallet.address}.json`;
|
|
599
|
+
|
|
600
|
+
const exportData = pubOnly
|
|
601
|
+
? Object.fromEntries(Object.entries(wallet).filter(([k]) => k !== 'private_key'))
|
|
602
|
+
: wallet;
|
|
603
|
+
|
|
604
|
+
fs.writeFileSync(outPath, JSON.stringify(exportData, null, 2));
|
|
605
|
+
console.log(`\n ${G}Wallet exported to:${NC} ${outPath}`);
|
|
606
|
+
if (!pubOnly) console.log(` ${R}Contains private key — keep this file secure!${NC}`);
|
|
607
|
+
console.log();
|
|
608
|
+
}
|
|
609
|
+
|
|
458
610
|
function cmdUninstall() {
|
|
459
611
|
log('Stopping miner...');
|
|
460
612
|
cmdStop();
|
|
@@ -475,6 +627,11 @@ function showHelp() {
|
|
|
475
627
|
console.log(`
|
|
476
628
|
ClawRTC v${VERSION} — Mine RTC tokens with your AI agent on real hardware
|
|
477
629
|
|
|
630
|
+
Wallet:
|
|
631
|
+
clawrtc wallet create Generate Ed25519 RTC wallet
|
|
632
|
+
clawrtc wallet show Show address and check balance
|
|
633
|
+
clawrtc wallet export Download key file (--public-only)
|
|
634
|
+
|
|
478
635
|
Commands:
|
|
479
636
|
clawrtc install [--wallet NAME] Install miner and configure wallet
|
|
480
637
|
clawrtc start Start mining (foreground)
|
|
@@ -516,6 +673,7 @@ switch (cmd) {
|
|
|
516
673
|
case 'status': cmdStatus(); break;
|
|
517
674
|
case 'logs': cmdLogs(); break;
|
|
518
675
|
case 'uninstall': cmdUninstall(); break;
|
|
676
|
+
case 'wallet': cmdWallet(args[1]); break;
|
|
519
677
|
case '--help': case '-h': showHelp(); break;
|
|
520
678
|
case undefined: showHelp(); break;
|
|
521
679
|
default:
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clawrtc",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "ClawRTC —
|
|
3
|
+
"version": "1.4.0",
|
|
4
|
+
"description": "ClawRTC — Mine RTC tokens with your AI agent. Built-in Ed25519 wallet, hardware fingerprinting, VM-penalized.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"clawrtc": "./bin/clawrtc.js"
|
|
7
7
|
},
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
"bin/",
|
|
10
10
|
"data/"
|
|
11
11
|
],
|
|
12
|
-
"keywords": ["clawrtc", "ai-agent", "miner", "rustchain", "rtc", "openclaw", "proof-of-antiquity", "blockchain"],
|
|
12
|
+
"keywords": ["clawrtc", "ai-agent", "miner", "rustchain", "rtc", "openclaw", "proof-of-antiquity", "blockchain", "wallet", "ed25519"],
|
|
13
13
|
"author": "Elyan Labs <scott@elyanlabs.ai>",
|
|
14
14
|
"license": "MIT",
|
|
15
|
-
"homepage": "https://
|
|
15
|
+
"homepage": "https://rustchain.org",
|
|
16
16
|
"repository": {
|
|
17
17
|
"type": "git",
|
|
18
18
|
"url": "https://github.com/Scottcjn/Rustchain"
|