clawcloud 1.1.0 → 1.3.1

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/index.js DELETED
@@ -1,637 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * ClawCloud CLI - Decentralized Cloud Infrastructure for AI Agents
5
- * Purchase and manage VMs with crypto on Base blockchain
6
- *
7
- * Usage: npx clawcloud [command] [options]
8
- */
9
-
10
- const { ethers } = require('ethers');
11
- const readline = require('readline');
12
- const fs = require('fs');
13
- const os = require('os');
14
- const path = require('path');
15
-
16
- // ============================================================================
17
- // PRODUCTION CONFIGURATION
18
- // ============================================================================
19
-
20
- const CONFIG = {
21
- // Network
22
- NETWORK: 'base',
23
- RPC_URL: 'https://mainnet.base.org',
24
- CHAIN_ID: 8453,
25
-
26
- // Contracts
27
- CONTRACT_ADDRESS: '0xF708741D37C420518852c6A15aB658066951c852',
28
- USDC_ADDRESS: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
29
-
30
- // API
31
- API_URL: 'https://api.clawcloud.co',
32
-
33
- // Explorer
34
- EXPLORER_URL: 'https://basescan.org',
35
-
36
- // Config file
37
- CONFIG_FILE: path.join(os.homedir(), '.clawcloud', 'config.json')
38
- };
39
-
40
- // ============================================================================
41
- // CONTRACT ABIs
42
- // ============================================================================
43
-
44
- const CONTRACT_ABI = [
45
- "function purchaseVM(uint8 tier, uint16 durationDays) returns (uint256)",
46
- "function getTierConfig(uint8 tier) view returns (uint256, bool, string)",
47
- "function isTokenValid(uint256 tokenId) view returns (bool)",
48
- "function ownerOf(uint256 tokenId) view returns (address)",
49
- "function balanceOf(address owner) view returns (uint256)",
50
- "function tokenOfOwnerByIndex(address owner, uint256 index) view returns (uint256)"
51
- ];
52
-
53
- const USDC_ABI = [
54
- "function approve(address spender, uint256 amount) returns (bool)",
55
- "function allowance(address owner, address spender) view returns (uint256)",
56
- "function balanceOf(address account) view returns (uint256)"
57
- ];
58
-
59
- // ============================================================================
60
- // UTILITIES
61
- // ============================================================================
62
-
63
- const rl = readline.createInterface({
64
- input: process.stdin,
65
- output: process.stdout
66
- });
67
-
68
- function question(query) {
69
- return new Promise(resolve => rl.question(query, resolve));
70
- }
71
-
72
- function log(message, type = 'info') {
73
- const symbols = {
74
- info: 'šŸ¦ž',
75
- success: 'āœ…',
76
- error: 'āŒ',
77
- warning: 'āš ļø',
78
- loading: 'ā³'
79
- };
80
- console.log(`${symbols[type]} ${message}`);
81
- }
82
-
83
- function formatUSDC(amount) {
84
- return ethers.formatUnits(amount, 6);
85
- }
86
-
87
- function parseUSDC(amount) {
88
- return ethers.parseUnits(amount.toString(), 6);
89
- }
90
-
91
- // ============================================================================
92
- // CONFIGURATION MANAGEMENT
93
- // ============================================================================
94
-
95
- function loadConfig() {
96
- try {
97
- if (fs.existsSync(CONFIG.CONFIG_FILE)) {
98
- return JSON.parse(fs.readFileSync(CONFIG.CONFIG_FILE, 'utf8'));
99
- }
100
- } catch (error) {
101
- // Config doesn't exist or is invalid
102
- }
103
- return {};
104
- }
105
-
106
- function saveConfig(config) {
107
- const dir = path.dirname(CONFIG.CONFIG_FILE);
108
- if (!fs.existsSync(dir)) {
109
- fs.mkdirSync(dir, { recursive: true });
110
- }
111
- fs.writeFileSync(CONFIG.CONFIG_FILE, JSON.stringify(config, null, 2));
112
- }
113
-
114
- // ============================================================================
115
- // WALLET SETUP
116
- // ============================================================================
117
-
118
- async function setupWallet() {
119
- const config = loadConfig();
120
-
121
- if (config.privateKey) {
122
- const provider = new ethers.JsonRpcProvider(CONFIG.RPC_URL);
123
- return new ethers.Wallet(config.privateKey, provider);
124
- }
125
-
126
- log('No wallet found. Let\'s set one up!', 'info');
127
- console.log('\nOptions:');
128
- console.log('1. Import existing private key');
129
- console.log('2. Generate new wallet');
130
-
131
- const choice = await question('\nChoose (1 or 2): ');
132
-
133
- let wallet;
134
- if (choice === '1') {
135
- const privateKey = await question('Enter your private key: ');
136
- const provider = new ethers.JsonRpcProvider(CONFIG.RPC_URL);
137
- wallet = new ethers.Wallet(privateKey.trim(), provider);
138
- } else {
139
- const provider = new ethers.JsonRpcProvider(CONFIG.RPC_URL);
140
- wallet = ethers.Wallet.createRandom(provider);
141
- log(`New wallet created!`, 'success');
142
- console.log(`Address: ${wallet.address}`);
143
- console.log(`\nāš ļø SAVE THIS PRIVATE KEY SECURELY:`);
144
- console.log(`${wallet.privateKey}\n`);
145
- await question('Press Enter after saving your private key...');
146
- }
147
-
148
- const save = await question('Save wallet to config? (y/n): ');
149
- if (save.toLowerCase() === 'y') {
150
- saveConfig({ privateKey: wallet.privateKey });
151
- log('Wallet saved!', 'success');
152
- }
153
-
154
- return wallet;
155
- }
156
-
157
- // ============================================================================
158
- // COMMANDS
159
- // ============================================================================
160
-
161
- async function cmdRegister() {
162
- try {
163
- log('Registering new AI agent...', 'loading');
164
-
165
- // Generate unique agent ID
166
- const timestamp = Math.floor(Date.now() / 1000);
167
- const randomStr = Math.random().toString(36).substring(2, 7);
168
- const agentId = `agent_${timestamp}_${randomStr}`;
169
-
170
- console.log(`\nšŸ¤– Generated Agent ID: ${agentId}`);
171
-
172
- // Register with API
173
- log('Registering with ClawCloud...', 'loading');
174
-
175
- const response = await fetch(`${CONFIG.API_URL}/agents/register`, {
176
- method: 'POST',
177
- headers: { 'Content-Type': 'application/json' },
178
- body: JSON.stringify({
179
- agentId,
180
- telegramUserId: null,
181
- telegramChatId: null,
182
- walletAddress: null
183
- })
184
- });
185
-
186
- if (!response.ok) {
187
- const error = await response.json();
188
- log(`Registration failed: ${error.error || 'Unknown error'}`, 'error');
189
- return;
190
- }
191
-
192
- const result = await response.json();
193
-
194
- if (!result.success) {
195
- log('Registration failed!', 'error');
196
- return;
197
- }
198
-
199
- log('Agent registered successfully!', 'success');
200
-
201
- console.log('\n' + '='.repeat(80));
202
- console.log('šŸŽ‰ AGENT REGISTRATION SUCCESSFUL');
203
- console.log('='.repeat(80));
204
- console.log(`\nšŸ¤– Your Agent ID:\n ${agentId}`);
205
- console.log('\nšŸ“± Next Steps:');
206
- console.log('\n1ļøāƒ£ Open Telegram and find @clawcloud_devbot');
207
- console.log(`2ļøāƒ£ Send this message:\n /start ${agentId}`);
208
- console.log('3ļøāƒ£ The bot will create a wallet for your agent');
209
- console.log('4ļøāƒ£ Fund the wallet with USDC on Base');
210
- console.log('5ļøāƒ£ Your agent can now purchase VMs autonomously!');
211
- console.log('\nšŸ’” SAVE THIS AGENT ID - You\'ll need it to link your Telegram wallet!');
212
- console.log('='.repeat(80) + '\n');
213
-
214
- // Save agent ID to config
215
- const config = loadConfig();
216
- if (!config.agents) config.agents = [];
217
- config.agents.push({
218
- agentId,
219
- createdAt: new Date().toISOString()
220
- });
221
- saveConfig(config);
222
-
223
- log('Agent ID saved to local config!', 'success');
224
-
225
- } catch (error) {
226
- log(`Registration failed: ${error.message}`, 'error');
227
- console.error(error);
228
- }
229
- }
230
-
231
- async function cmdTiers() {
232
- try {
233
- log('Fetching available VM tiers...', 'loading');
234
-
235
- const response = await fetch(`${CONFIG.API_URL}/tiers`);
236
- const data = await response.json();
237
-
238
- console.log('\nšŸ“Š Available VM Tiers:\n');
239
- console.log('ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”');
240
- console.log('│ Tier │ Name │ Per Day │ Per Month │ Status │');
241
- console.log('ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤');
242
-
243
- for (const tier of data.tiers) {
244
- const status = tier.active ? 'āœ…' : 'āŒ';
245
- console.log(
246
- `│ ${String(tier.tier).padEnd(4)} │ ${tier.name.padEnd(27)} │ $${tier.pricePerDay.padEnd(11)} │ $${tier.pricePerMonth.padEnd(12)} │ ${status} │`
247
- );
248
- }
249
-
250
- console.log('ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜\n');
251
-
252
- } catch (error) {
253
- log(`Failed to fetch tiers: ${error.message}`, 'error');
254
- }
255
- }
256
-
257
- async function cmdPurchase() {
258
- try {
259
- const wallet = await setupWallet();
260
-
261
- log(`Wallet: ${wallet.address}`, 'info');
262
-
263
- // Get tiers first
264
- const response = await fetch(`${CONFIG.API_URL}/tiers`);
265
- const { tiers } = await response.json();
266
-
267
- // Show tiers
268
- console.log('\nšŸ“Š Available Tiers:\n');
269
- tiers.forEach(tier => {
270
- if (tier.active) {
271
- console.log(`${tier.tier}. ${tier.name} - $${tier.pricePerDay}/day ($${tier.pricePerMonth}/month)`);
272
- }
273
- });
274
-
275
- // Get user input
276
- const tierInput = await question('\nChoose tier (0-7): ');
277
- const tier = parseInt(tierInput);
278
-
279
- if (tier < 0 || tier > 7 || !tiers[tier].active) {
280
- log('Invalid tier!', 'error');
281
- return;
282
- }
283
-
284
- const daysInput = await question('Duration in days (3+ recommended): ');
285
- const days = parseInt(daysInput);
286
-
287
- if (days < 3) {
288
- log('Minimum duration is 3 days!', 'error');
289
- return;
290
- }
291
-
292
- // Calculate cost
293
- const pricePerDay = parseUSDC(tiers[tier].pricePerDay);
294
- const totalCost = pricePerDay * BigInt(days);
295
-
296
- console.log(`\nšŸ’° Total cost: $${formatUSDC(totalCost)} USDC`);
297
-
298
- const confirm = await question('Proceed with purchase? (y/n): ');
299
- if (confirm.toLowerCase() !== 'y') {
300
- log('Purchase cancelled', 'info');
301
- return;
302
- }
303
-
304
- // Check USDC balance
305
- log('Checking USDC balance...', 'loading');
306
- const usdc = new ethers.Contract(CONFIG.USDC_ADDRESS, USDC_ABI, wallet);
307
- const balance = await usdc.balanceOf(wallet.address);
308
-
309
- if (balance < totalCost) {
310
- log(`Insufficient USDC! You have $${formatUSDC(balance)}, need $${formatUSDC(totalCost)}`, 'error');
311
- console.log(`\nBuy USDC on Base: https://app.uniswap.org/swap?chain=base`);
312
- return;
313
- }
314
-
315
- log(`USDC balance: $${formatUSDC(balance)} āœ…`, 'success');
316
-
317
- // Check approval
318
- log('Checking USDC approval...', 'loading');
319
- const contract = new ethers.Contract(CONFIG.CONTRACT_ADDRESS, CONTRACT_ABI, wallet);
320
- const allowance = await usdc.allowance(wallet.address, CONFIG.CONTRACT_ADDRESS);
321
-
322
- if (allowance < totalCost) {
323
- log('Approving USDC...', 'loading');
324
- const approveTx = await usdc.approve(CONFIG.CONTRACT_ADDRESS, totalCost);
325
- log(`Approval tx: ${CONFIG.EXPLORER_URL}/tx/${approveTx.hash}`, 'info');
326
- await approveTx.wait();
327
- log('USDC approved!', 'success');
328
- }
329
-
330
- // Purchase VM
331
- log('Purchasing VM...', 'loading');
332
- const purchaseTx = await contract.purchaseVM(tier, days);
333
- log(`Purchase tx: ${CONFIG.EXPLORER_URL}/tx/${purchaseTx.hash}`, 'info');
334
-
335
- const receipt = await purchaseTx.wait();
336
-
337
- // Get token ID from event
338
- const iface = new ethers.Interface(CONTRACT_ABI);
339
- const event = receipt.logs
340
- .map(log => {
341
- try {
342
- return iface.parseLog(log);
343
- } catch {
344
- return null;
345
- }
346
- })
347
- .find(e => e && e.name === 'VMPurchased');
348
-
349
- const tokenId = event.args.tokenId;
350
-
351
- log(`VM purchased successfully! šŸŽ‰`, 'success');
352
- console.log(`\nToken ID: ${tokenId}`);
353
- console.log(`Tier: ${tier}`);
354
- console.log(`Duration: ${days} days`);
355
- console.log(`\nā³ VM is provisioning... This takes 2-3 minutes.`);
356
- console.log(`\nGet credentials: npx clawcloud get ${tokenId}`);
357
-
358
- } catch (error) {
359
- log(`Purchase failed: ${error.message}`, 'error');
360
- if (error.message.includes('insufficient funds')) {
361
- log('You need ETH on Base for gas fees!', 'warning');
362
- console.log(`Bridge ETH: https://bridge.base.org`);
363
- }
364
- }
365
- }
366
-
367
- async function cmdGet(tokenId) {
368
- try {
369
- if (!tokenId) {
370
- log('Usage: npx clawcloud get <tokenId>', 'error');
371
- return;
372
- }
373
-
374
- const wallet = await setupWallet();
375
-
376
- log(`Fetching credentials for VM #${tokenId}...`, 'loading');
377
-
378
- // Sign authentication message
379
- const message = `ClawCloud Access Request: ${tokenId}`;
380
- const signature = await wallet.signMessage(message);
381
-
382
- // Call API
383
- const response = await fetch(
384
- `${CONFIG.API_URL}/credentials/${tokenId}`,
385
- {
386
- headers: {
387
- 'Authorization': `Bearer ${signature}`
388
- }
389
- }
390
- );
391
-
392
- const data = await response.json();
393
-
394
- if (response.status === 202) {
395
- log('VM is still provisioning...', 'warning');
396
- console.log(`Status: ${data.status}`);
397
- console.log(`Message: ${data.message}`);
398
- console.log(`\nTry again in 2-3 minutes: npx clawcloud get ${tokenId}`);
399
- return;
400
- }
401
-
402
- if (!response.ok) {
403
- log(`Error: ${data.error || 'Failed to get credentials'}`, 'error');
404
- return;
405
- }
406
-
407
- log('VM credentials retrieved!', 'success');
408
- console.log('\n' + '='.repeat(70));
409
- console.log(`šŸ–„ļø VM #${data.tokenId} - ${data.type.toUpperCase()}`);
410
- console.log('='.repeat(70));
411
- console.log(`Tier: ${data.tier}`);
412
- console.log(`Host: ${data.host}`);
413
- console.log(`Username: ${data.username}`);
414
- console.log(`Expires: ${new Date(data.expiresAt).toLocaleString()}`);
415
- console.log('\nšŸ“ SSH Command:');
416
- console.log(` ${data.instructions}`);
417
-
418
- if (data.privateKey) {
419
- console.log('\nšŸ”‘ Private Key:');
420
- console.log(` Save to file: echo "${data.privateKey}" > vm_${tokenId}.pem`);
421
- console.log(` Then: chmod 600 vm_${tokenId}.pem`);
422
- console.log(` Connect: ssh -i vm_${tokenId}.pem ${data.username}@${data.host}`);
423
- }
424
-
425
- console.log('='.repeat(70) + '\n');
426
-
427
- } catch (error) {
428
- log(`Failed to get credentials: ${error.message}`, 'error');
429
- }
430
- }
431
-
432
- async function cmdList() {
433
- try {
434
- const wallet = await setupWallet();
435
-
436
- log(`Fetching VMs for ${wallet.address}...`, 'loading');
437
-
438
- const response = await fetch(`${CONFIG.API_URL}/vms/${wallet.address}`);
439
- const data = await response.json();
440
-
441
- if (data.count === 0) {
442
- log('No VMs found!', 'info');
443
- console.log('\nPurchase a VM: npx clawcloud purchase');
444
- return;
445
- }
446
-
447
- log(`Found ${data.count} VM(s)`, 'success');
448
- console.log('\n' + '='.repeat(90));
449
- console.log('Your VMs:');
450
- console.log('='.repeat(90));
451
-
452
- for (const vm of data.vms) {
453
- const status = vm.status === 'running' ? 'āœ…' :
454
- vm.status === 'provisioning' ? 'ā³' :
455
- vm.status === 'expired' ? 'ā°' : 'āŒ';
456
-
457
- console.log(`\n${status} VM #${vm.token_id}`);
458
- console.log(` Tier: ${vm.tier}`);
459
- console.log(` Type: ${vm.vm_type}`);
460
- console.log(` Host: ${vm.ssh_host}`);
461
- console.log(` Status: ${vm.status}`);
462
- console.log(` Created: ${new Date(vm.created_at).toLocaleString()}`);
463
- console.log(` Expires: ${new Date(vm.expires_at).toLocaleString()}`);
464
- console.log(` Access: npx clawcloud get ${vm.token_id}`);
465
- }
466
-
467
- console.log('\n' + '='.repeat(90) + '\n');
468
-
469
- } catch (error) {
470
- log(`Failed to list VMs: ${error.message}`, 'error');
471
- }
472
- }
473
-
474
- async function cmdBalance() {
475
- try {
476
- const wallet = await setupWallet();
477
-
478
- log('Checking balances...', 'loading');
479
-
480
- const provider = wallet.provider;
481
- const usdc = new ethers.Contract(CONFIG.USDC_ADDRESS, USDC_ABI, provider);
482
-
483
- const ethBalance = await provider.getBalance(wallet.address);
484
- const usdcBalance = await usdc.balanceOf(wallet.address);
485
-
486
- console.log('\nšŸ’° Wallet Balances:');
487
- console.log(` Address: ${wallet.address}`);
488
- console.log(` ETH: ${ethers.formatEther(ethBalance)} ETH (for gas)`);
489
- console.log(` USDC: $${formatUSDC(usdcBalance)} USDC`);
490
-
491
- if (ethBalance === 0n) {
492
- log('You need ETH for gas fees!', 'warning');
493
- console.log(` Bridge ETH: https://bridge.base.org`);
494
- }
495
-
496
- if (usdcBalance === 0n) {
497
- log('You need USDC to purchase VMs!', 'warning');
498
- console.log(` Buy USDC: https://app.uniswap.org/swap?chain=base`);
499
- }
500
-
501
- console.log('');
502
-
503
- } catch (error) {
504
- log(`Failed to check balance: ${error.message}`, 'error');
505
- }
506
- }
507
-
508
- async function cmdInfo() {
509
- console.log('\nšŸ¦ž ClawCloud CLI\n');
510
- console.log('Decentralized Cloud Infrastructure for AI Agents\n');
511
- console.log('Network: Base Mainnet');
512
- console.log(`Contract: ${CONFIG.CONTRACT_ADDRESS}`);
513
- console.log(`USDC: ${CONFIG.USDC_ADDRESS}`);
514
- console.log(`API: ${CONFIG.API_URL}`);
515
- console.log(`Explorer: ${CONFIG.EXPLORER_URL}`);
516
- console.log(`\nWebsite: https://clawcloud.co`);
517
- console.log(`Documentation: https://docs.clawcloud.co`);
518
- console.log(`X: https://x.com/clawcloudx`);
519
- console.log(`Chart: https://dexscreener.com/base/0xe8850bBc9c289c34e7C92C9572BE38f77D61cB07`);
520
- console.log('');
521
- }
522
-
523
- async function cmdHelp() {
524
- console.log('\nšŸ¦ž ClawCloud CLI - Commands\n');
525
- console.log('AGENT SETUP:');
526
- console.log(' npx clawcloud register Register a new AI agent');
527
- console.log('');
528
- console.log('PURCHASE & MANAGE:');
529
- console.log(' npx clawcloud purchase Purchase a new VM');
530
- console.log(' npx clawcloud get <tokenId> Get VM credentials');
531
- console.log(' npx clawcloud list List your VMs');
532
- console.log('');
533
- console.log('INFORMATION:');
534
- console.log(' npx clawcloud tiers Show available VM tiers');
535
- console.log(' npx clawcloud balance Check wallet balance');
536
- console.log(' npx clawcloud info Show contract/API info');
537
- console.log('');
538
- console.log('WALLET:');
539
- console.log(' npx clawcloud wallet View/setup wallet');
540
- console.log('');
541
- console.log('HELP:');
542
- console.log(' npx clawcloud help Show this help');
543
- console.log('');
544
- console.log('Examples:');
545
- console.log(' npx clawcloud register # Register your AI agent first');
546
- console.log(' npx clawcloud tiers # View available tiers');
547
- console.log(' npx clawcloud purchase # Buy a VM');
548
- console.log(' npx clawcloud get 42 # Get VM credentials');
549
- console.log(' npx clawcloud list # List your VMs');
550
- console.log('');
551
- }
552
-
553
- async function cmdWallet() {
554
- const config = loadConfig();
555
-
556
- if (config.privateKey) {
557
- const provider = new ethers.JsonRpcProvider(CONFIG.RPC_URL);
558
- const wallet = new ethers.Wallet(config.privateKey, provider);
559
-
560
- console.log('\nšŸ’¼ Current Wallet:');
561
- console.log(` Address: ${wallet.address}`);
562
- console.log(` Network: Base Mainnet`);
563
- console.log('');
564
-
565
- const action = await question('Options: (b)alance, (c)hange wallet, (r)emove wallet, or Enter to exit: ');
566
-
567
- if (action === 'b') {
568
- await cmdBalance();
569
- } else if (action === 'c') {
570
- saveConfig({});
571
- log('Wallet removed. Run any command to set up a new one.', 'success');
572
- } else if (action === 'r') {
573
- saveConfig({});
574
- log('Wallet removed from config.', 'success');
575
- }
576
- } else {
577
- await setupWallet();
578
- }
579
- }
580
-
581
- // ============================================================================
582
- // MAIN
583
- // ============================================================================
584
-
585
- async function main() {
586
- const args = process.argv.slice(2);
587
- const command = args[0] || 'help';
588
-
589
- try {
590
- switch (command) {
591
- case 'register':
592
- await cmdRegister();
593
- break;
594
- case 'tiers':
595
- await cmdTiers();
596
- break;
597
- case 'purchase':
598
- case 'buy':
599
- await cmdPurchase();
600
- break;
601
- case 'get':
602
- case 'credentials':
603
- await cmdGet(args[1]);
604
- break;
605
- case 'list':
606
- case 'ls':
607
- await cmdList();
608
- break;
609
- case 'balance':
610
- case 'bal':
611
- await cmdBalance();
612
- break;
613
- case 'wallet':
614
- await cmdWallet();
615
- break;
616
- case 'info':
617
- await cmdInfo();
618
- break;
619
- case 'help':
620
- case '--help':
621
- case '-h':
622
- await cmdHelp();
623
- break;
624
- default:
625
- log(`Unknown command: ${command}`, 'error');
626
- await cmdHelp();
627
- }
628
- } catch (error) {
629
- log(`Error: ${error.message}`, 'error');
630
- console.error(error);
631
- } finally {
632
- rl.close();
633
- process.exit(0);
634
- }
635
- }
636
-
637
- main();