clawcloud 1.0.0 → 1.0.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/CLI_PUBLISHING_GUIDE.md +325 -0
- package/README.md +253 -118
- package/index.js +559 -0
- package/package.json +18 -35
- package/bin/clawcloud.js +0 -158
- package/src/api/agents.js +0 -22
- package/src/api/vms.js +0 -23
- package/src/api/wallet.js +0 -21
- package/src/commands/balance.js +0 -27
- package/src/commands/buy.js +0 -8
- package/src/commands/configure.js +0 -86
- package/src/commands/export.js +0 -203
- package/src/commands/fund.js +0 -13
- package/src/commands/interactive.js +0 -70
- package/src/commands/list.js +0 -87
- package/src/commands/nfts.js +0 -5
- package/src/commands/register.js +0 -72
- package/src/commands/ssh.js +0 -5
- package/src/commands/status.js +0 -5
- package/src/commands/terminate.js +0 -5
- package/src/commands/transfer.js +0 -5
- package/src/utils/banner.js +0 -9
- package/src/utils/config.js +0 -75
- package/src/utils/help.js +0 -85
- package/src/utils/version.js +0 -15
- package/templates/SKILL.md +0 -215
package/src/commands/list.js
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import Table from 'cli-table3';
|
|
3
|
-
import ora from 'ora';
|
|
4
|
-
import { getWalletConfig } from '../utils/config.js';
|
|
5
|
-
import { getVMs } from '../api/vms.js';
|
|
6
|
-
|
|
7
|
-
export async function list(options = {}) {
|
|
8
|
-
const wallet = getWalletConfig();
|
|
9
|
-
|
|
10
|
-
if (!wallet) {
|
|
11
|
-
console.log(chalk.red('\n❌ No wallet configured!\n'));
|
|
12
|
-
console.log(chalk.yellow('Run: npx clawcloud configure\n'));
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const spinner = ora('Fetching your VMs and NFTs...').start();
|
|
17
|
-
|
|
18
|
-
try {
|
|
19
|
-
const vms = await getVMs(wallet.address);
|
|
20
|
-
|
|
21
|
-
spinner.stop();
|
|
22
|
-
|
|
23
|
-
if (options.json) {
|
|
24
|
-
console.log(JSON.stringify(vms, null, 2));
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
console.log(chalk.cyan.bold('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
|
|
29
|
-
console.log(chalk.cyan.bold(' YOUR AGENT\'S INFRASTRUCTURE'));
|
|
30
|
-
console.log(chalk.cyan.bold('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
|
|
31
|
-
|
|
32
|
-
console.log(chalk.white(`🤖 Agent: ${chalk.cyan(wallet.agentId)}`));
|
|
33
|
-
console.log(chalk.white(`💰 Balance: ${chalk.yellow('...')} USDC`));
|
|
34
|
-
console.log(chalk.white(`🎨 NFTs Owned: ${chalk.green(vms.length)}\n`));
|
|
35
|
-
|
|
36
|
-
if (vms.length === 0) {
|
|
37
|
-
console.log(chalk.yellow('No VMs yet. Purchase one:\n'));
|
|
38
|
-
console.log(chalk.cyan(' npx clawcloud buy\n'));
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const table = new Table({
|
|
43
|
-
head: [
|
|
44
|
-
chalk.white('NFT'),
|
|
45
|
-
chalk.white('Tier'),
|
|
46
|
-
chalk.white('Status'),
|
|
47
|
-
chalk.white('IP Address'),
|
|
48
|
-
chalk.white('Expires')
|
|
49
|
-
],
|
|
50
|
-
style: {
|
|
51
|
-
head: [],
|
|
52
|
-
border: ['gray']
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
vms.forEach(vm => {
|
|
57
|
-
const statusColor = vm.status === 'active' ? chalk.green :
|
|
58
|
-
vm.status === 'provisioning' ? chalk.yellow :
|
|
59
|
-
chalk.red;
|
|
60
|
-
|
|
61
|
-
const expiresIn = vm.expires_in_days > 0 ?
|
|
62
|
-
`${vm.expires_in_days} days` :
|
|
63
|
-
chalk.red('Expired');
|
|
64
|
-
|
|
65
|
-
table.push([
|
|
66
|
-
chalk.cyan(`#${vm.nft_id}`),
|
|
67
|
-
vm.tier,
|
|
68
|
-
statusColor(vm.status),
|
|
69
|
-
vm.ip_address || chalk.gray('provisioning...'),
|
|
70
|
-
expiresIn
|
|
71
|
-
]);
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
console.log(table.toString());
|
|
75
|
-
|
|
76
|
-
console.log(chalk.gray('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
|
|
77
|
-
console.log(chalk.white('Commands:'));
|
|
78
|
-
console.log(chalk.cyan(' npx clawcloud status <nft-id>') + chalk.gray(' - View details'));
|
|
79
|
-
console.log(chalk.cyan(' npx clawcloud ssh <nft-id>') + chalk.gray(' - Connect'));
|
|
80
|
-
console.log(chalk.cyan(' npx clawcloud renew <nft-id>') + chalk.gray(' - Extend'));
|
|
81
|
-
console.log(chalk.gray('\n'));
|
|
82
|
-
|
|
83
|
-
} catch (error) {
|
|
84
|
-
spinner.fail('Failed to fetch VMs');
|
|
85
|
-
console.error(chalk.red(`\n❌ Error: ${error.message}\n`));
|
|
86
|
-
}
|
|
87
|
-
}
|
package/src/commands/nfts.js
DELETED
package/src/commands/register.js
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import inquirer from 'inquirer';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import ora from 'ora';
|
|
4
|
-
import boxen from 'boxen';
|
|
5
|
-
import { saveAgent } from '../utils/config.js';
|
|
6
|
-
import { registerAgent } from '../api/agents.js';
|
|
7
|
-
|
|
8
|
-
export async function register() {
|
|
9
|
-
console.log(chalk.cyan.bold('\n🤖 Register AI Agent\n'));
|
|
10
|
-
|
|
11
|
-
const answers = await inquirer.prompt([
|
|
12
|
-
{
|
|
13
|
-
type: 'input',
|
|
14
|
-
name: 'name',
|
|
15
|
-
message: 'Agent name:',
|
|
16
|
-
validate: (input) => input.length > 0 || 'Name is required'
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
type: 'input',
|
|
20
|
-
name: 'description',
|
|
21
|
-
message: 'Description:',
|
|
22
|
-
validate: (input) => input.length > 0 || 'Description is required'
|
|
23
|
-
}
|
|
24
|
-
]);
|
|
25
|
-
|
|
26
|
-
const spinner = ora('Registering agent...').start();
|
|
27
|
-
|
|
28
|
-
try {
|
|
29
|
-
// Call API to register agent
|
|
30
|
-
const result = await registerAgent(answers.name, answers.description);
|
|
31
|
-
|
|
32
|
-
spinner.succeed('Agent Registered!');
|
|
33
|
-
|
|
34
|
-
// Save agent ID locally
|
|
35
|
-
saveAgent({
|
|
36
|
-
agentId: result.agent_id,
|
|
37
|
-
name: answers.name,
|
|
38
|
-
description: answers.description,
|
|
39
|
-
createdAt: result.created_at
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
// Display next steps
|
|
43
|
-
console.log(boxen(
|
|
44
|
-
chalk.bold.white(`Agent ID: ${chalk.cyan(result.agent_id)}\n\n`) +
|
|
45
|
-
chalk.yellow('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n') +
|
|
46
|
-
chalk.white.bold('📱 NEXT STEP: Get Your Wallet\n\n') +
|
|
47
|
-
chalk.white(`1. Open Telegram: ${chalk.blue('https://t.me/clawcloud_devbot')}\n\n`) +
|
|
48
|
-
chalk.white(`2. Send this command:\n ${chalk.green(`/start ${result.agent_id}`)}\n\n`) +
|
|
49
|
-
chalk.white('3. Bot will verify your agent and create a wallet\n\n') +
|
|
50
|
-
chalk.white('4. You\'ll receive:\n') +
|
|
51
|
-
chalk.gray(' • Wallet address\n') +
|
|
52
|
-
chalk.gray(' • Private key (keep secure!)\n') +
|
|
53
|
-
chalk.gray(' • Funding instructions\n\n') +
|
|
54
|
-
chalk.yellow('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n') +
|
|
55
|
-
chalk.white('After Telegram setup, run:\n') +
|
|
56
|
-
chalk.cyan(' npx clawcloud configure') + chalk.gray(' - Link wallet to CLI\n') +
|
|
57
|
-
chalk.cyan(' npx clawcloud export') + chalk.gray(' - Make agent autonomous'),
|
|
58
|
-
{
|
|
59
|
-
padding: 1,
|
|
60
|
-
margin: 1,
|
|
61
|
-
borderStyle: 'round',
|
|
62
|
-
borderColor: 'cyan'
|
|
63
|
-
}
|
|
64
|
-
));
|
|
65
|
-
|
|
66
|
-
console.log(chalk.gray(`\nAgent ID saved to: ~/.clawcloud/agents.json\n`));
|
|
67
|
-
|
|
68
|
-
} catch (error) {
|
|
69
|
-
spinner.fail('Registration failed');
|
|
70
|
-
console.error(chalk.red(`\n❌ Error: ${error.message}\n`));
|
|
71
|
-
}
|
|
72
|
-
}
|
package/src/commands/ssh.js
DELETED
package/src/commands/status.js
DELETED
package/src/commands/transfer.js
DELETED
package/src/utils/banner.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import { getVersion } from './version.js';
|
|
3
|
-
|
|
4
|
-
export function displayBanner() {
|
|
5
|
-
const version = getVersion();
|
|
6
|
-
|
|
7
|
-
console.log(chalk.cyan('\n ☁️ ClawCloud CLI ') + chalk.gray(`v${version}`));
|
|
8
|
-
console.log(chalk.gray(' Cloud infrastructure AI agents can own\n'));
|
|
9
|
-
}
|
package/src/utils/config.js
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import os from 'os';
|
|
4
|
-
|
|
5
|
-
const CONFIG_DIR = path.join(os.homedir(), '.clawcloud');
|
|
6
|
-
const AGENTS_FILE = path.join(CONFIG_DIR, 'agents.json');
|
|
7
|
-
const WALLET_FILE = path.join(CONFIG_DIR, 'wallet.json');
|
|
8
|
-
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
|
|
9
|
-
|
|
10
|
-
// Ensure config directory exists
|
|
11
|
-
if (!fs.existsSync(CONFIG_DIR)) {
|
|
12
|
-
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function saveAgent(agentData) {
|
|
16
|
-
let agents = {};
|
|
17
|
-
|
|
18
|
-
if (fs.existsSync(AGENTS_FILE)) {
|
|
19
|
-
agents = JSON.parse(fs.readFileSync(AGENTS_FILE, 'utf-8'));
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
agents[agentData.agentId] = agentData;
|
|
23
|
-
fs.writeFileSync(AGENTS_FILE, JSON.stringify(agents, null, 2));
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function getAgent(agentId) {
|
|
27
|
-
if (!fs.existsSync(AGENTS_FILE)) {
|
|
28
|
-
return null;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const agents = JSON.parse(fs.readFileSync(AGENTS_FILE, 'utf-8'));
|
|
32
|
-
return agents[agentId] || null;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function saveWallet(agentId, privateKey, address) {
|
|
36
|
-
const walletData = {
|
|
37
|
-
agentId,
|
|
38
|
-
privateKey,
|
|
39
|
-
address,
|
|
40
|
-
network: 'base',
|
|
41
|
-
configuredAt: new Date().toISOString()
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
fs.writeFileSync(WALLET_FILE, JSON.stringify(walletData, null, 2));
|
|
45
|
-
fs.chmodSync(WALLET_FILE, 0o600); // Secure permissions
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function getWalletConfig() {
|
|
49
|
-
if (!fs.existsSync(WALLET_FILE)) {
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return JSON.parse(fs.readFileSync(WALLET_FILE, 'utf-8'));
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export function getConfig() {
|
|
57
|
-
const defaultConfig = {
|
|
58
|
-
API_URL: 'https://api.clawcloud.co/v1',
|
|
59
|
-
CONTRACT_ADDRESS: '0x...', // TODO: Update with real contract
|
|
60
|
-
USDC_ADDRESS: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
|
|
61
|
-
RPC_URL: 'https://mainnet.base.org',
|
|
62
|
-
TELEGRAM_BOT: 'clawcloud_devbot'
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
if (!fs.existsSync(CONFIG_FILE)) {
|
|
66
|
-
return defaultConfig;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const userConfig = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8'));
|
|
70
|
-
return { ...defaultConfig, ...userConfig };
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export function saveConfig(config) {
|
|
74
|
-
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
75
|
-
}
|
package/src/utils/help.js
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import boxen from 'boxen';
|
|
3
|
-
|
|
4
|
-
export function displayHelp() {
|
|
5
|
-
console.log(chalk.cyan.bold('\n☁️ ClawCloud CLI - Complete Guide\n'));
|
|
6
|
-
|
|
7
|
-
console.log(boxen(
|
|
8
|
-
chalk.white.bold('GETTING STARTED\n\n') +
|
|
9
|
-
chalk.cyan('1. Register Agent:\n') +
|
|
10
|
-
chalk.gray(' npx clawcloud register\n\n') +
|
|
11
|
-
chalk.cyan('2. Get Wallet (Telegram):\n') +
|
|
12
|
-
chalk.gray(' https://t.me/clawcloud_devbot\n') +
|
|
13
|
-
chalk.gray(' /start <agent-id>\n\n') +
|
|
14
|
-
chalk.cyan('3. Configure CLI:\n') +
|
|
15
|
-
chalk.gray(' npx clawcloud configure\n\n') +
|
|
16
|
-
chalk.cyan('4. Make Agent Autonomous:\n') +
|
|
17
|
-
chalk.gray(' npx clawcloud export'),
|
|
18
|
-
{
|
|
19
|
-
padding: 1,
|
|
20
|
-
margin: 1,
|
|
21
|
-
borderStyle: 'round',
|
|
22
|
-
borderColor: 'cyan'
|
|
23
|
-
}
|
|
24
|
-
));
|
|
25
|
-
|
|
26
|
-
console.log(chalk.white.bold('\n📚 COMMANDS\n'));
|
|
27
|
-
|
|
28
|
-
const commands = [
|
|
29
|
-
['Setup & Configuration', ''],
|
|
30
|
-
[' register', 'Register a new AI agent'],
|
|
31
|
-
[' configure', 'Link wallet after Telegram setup'],
|
|
32
|
-
[' fund', 'Show funding instructions'],
|
|
33
|
-
['', ''],
|
|
34
|
-
['Autonomous Mode (Primary)', ''],
|
|
35
|
-
[' export', 'Export config for autonomous agents'],
|
|
36
|
-
['', ''],
|
|
37
|
-
['Wallet & Balance', ''],
|
|
38
|
-
[' balance, bal', 'Check USDC balance'],
|
|
39
|
-
['', ''],
|
|
40
|
-
['NFT & VM Management', ''],
|
|
41
|
-
[' list, ls', 'List your VMs and NFTs'],
|
|
42
|
-
[' nfts', 'View NFT collection'],
|
|
43
|
-
[' status <nft-id>', 'View NFT/VM details'],
|
|
44
|
-
[' buy', 'Purchase VM (manual mode)'],
|
|
45
|
-
[' renew <nft-id>', 'Extend VM duration'],
|
|
46
|
-
[' ssh <nft-id>', 'SSH into VM'],
|
|
47
|
-
[' transfer <nft-id>', 'Transfer NFT/VM ownership'],
|
|
48
|
-
[' terminate <nft-id>', 'Destroy VM & burn NFT'],
|
|
49
|
-
['', ''],
|
|
50
|
-
['Documentation', ''],
|
|
51
|
-
[' docs', 'Open documentation'],
|
|
52
|
-
[' help', 'Show this help'],
|
|
53
|
-
['', '']
|
|
54
|
-
];
|
|
55
|
-
|
|
56
|
-
commands.forEach(([cmd, desc]) => {
|
|
57
|
-
if (cmd === '') {
|
|
58
|
-
console.log('');
|
|
59
|
-
} else if (desc === '') {
|
|
60
|
-
console.log(chalk.yellow.bold(cmd));
|
|
61
|
-
} else {
|
|
62
|
-
console.log(chalk.cyan(` ${cmd.padEnd(25)}`) + chalk.gray(desc));
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
console.log(chalk.white.bold('\n🚀 EXAMPLES\n'));
|
|
67
|
-
|
|
68
|
-
console.log(chalk.gray(' # Interactive mode'));
|
|
69
|
-
console.log(chalk.cyan(' npx clawcloud\n'));
|
|
70
|
-
|
|
71
|
-
console.log(chalk.gray(' # Check balance'));
|
|
72
|
-
console.log(chalk.cyan(' npx clawcloud balance\n'));
|
|
73
|
-
|
|
74
|
-
console.log(chalk.gray(' # List VMs'));
|
|
75
|
-
console.log(chalk.cyan(' npx clawcloud list\n'));
|
|
76
|
-
|
|
77
|
-
console.log(chalk.gray(' # Make agent autonomous (OpenClaw)'));
|
|
78
|
-
console.log(chalk.cyan(' npx clawcloud export --framework openclaw\n'));
|
|
79
|
-
|
|
80
|
-
console.log(chalk.white.bold('\n🔗 LINKS\n'));
|
|
81
|
-
console.log(chalk.gray(' Docs: ') + chalk.blue('https://docs.clawcloud.co'));
|
|
82
|
-
console.log(chalk.gray(' Telegram: ') + chalk.blue('https://t.me/clawcloud_devbot'));
|
|
83
|
-
console.log(chalk.gray(' GitHub: ') + chalk.blue('https://github.com/clawcloud/clawcloud'));
|
|
84
|
-
console.log(chalk.gray(' Website: ') + chalk.blue('https://clawcloud.co\n'));
|
|
85
|
-
}
|
package/src/utils/version.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { readFileSync } from 'fs';
|
|
2
|
-
import { join, dirname } from 'path';
|
|
3
|
-
import { fileURLToPath } from 'url';
|
|
4
|
-
|
|
5
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
|
-
|
|
7
|
-
export function getVersion() {
|
|
8
|
-
try {
|
|
9
|
-
const packagePath = join(__dirname, '..', '..', 'package.json');
|
|
10
|
-
const pkg = JSON.parse(readFileSync(packagePath, 'utf-8'));
|
|
11
|
-
return pkg.version;
|
|
12
|
-
} catch {
|
|
13
|
-
return '1.0.0';
|
|
14
|
-
}
|
|
15
|
-
}
|
package/templates/SKILL.md
DELETED
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: clawcloud
|
|
3
|
-
version: 1.0.0
|
|
4
|
-
description: Autonomous cloud infrastructure. Buy VMs with crypto, deploy code, own compute.
|
|
5
|
-
homepage: https://clawcloud.co
|
|
6
|
-
repository: https://github.com/clawcloud/clawcloud
|
|
7
|
-
metadata:
|
|
8
|
-
openclaw:
|
|
9
|
-
category: infrastructure
|
|
10
|
-
api_base: https://api.clawcloud.co/v1
|
|
11
|
-
wallet_address: {{WALLET_ADDRESS}}
|
|
12
|
-
agent_id: {{AGENT_ID}}
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
# ClawCloud Skill
|
|
16
|
-
|
|
17
|
-
**You can autonomously purchase and control cloud VMs using cryptocurrency.**
|
|
18
|
-
|
|
19
|
-
## What You Can Do
|
|
20
|
-
|
|
21
|
-
- Check your USDC balance on Base
|
|
22
|
-
- Purchase VMs when you need compute
|
|
23
|
-
- Deploy code to your VMs
|
|
24
|
-
- Scale infrastructure based on your needs
|
|
25
|
-
- Own VMs as NFTs in your wallet
|
|
26
|
-
|
|
27
|
-
## Your Wallet
|
|
28
|
-
|
|
29
|
-
Address: `{{WALLET_ADDRESS}}`
|
|
30
|
-
Agent ID: `{{AGENT_ID}}`
|
|
31
|
-
Network: Base
|
|
32
|
-
Currency: USDC
|
|
33
|
-
|
|
34
|
-
**IMPORTANT:** Your private key is configured. Keep this skill secure.
|
|
35
|
-
|
|
36
|
-
## Commands
|
|
37
|
-
|
|
38
|
-
### Check Balance
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
# Check USDC balance
|
|
42
|
-
curl https://api.clawcloud.co/v1/wallet/balance \
|
|
43
|
-
-H "Authorization: Bearer {{AGENT_ID}}"
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
Example response:
|
|
47
|
-
```json
|
|
48
|
-
{
|
|
49
|
-
"balance_usdc": "25.50",
|
|
50
|
-
"wallet_address": "{{WALLET_ADDRESS}}",
|
|
51
|
-
"network": "base"
|
|
52
|
-
}
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### List VM Tiers
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
# See available VM tiers and pricing
|
|
59
|
-
curl https://api.clawcloud.co/v1/packages
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
Example response:
|
|
63
|
-
```json
|
|
64
|
-
{
|
|
65
|
-
"packages": [
|
|
66
|
-
{
|
|
67
|
-
"tier": "MICRO",
|
|
68
|
-
"tier_index": 0,
|
|
69
|
-
"price_monthly": 5,
|
|
70
|
-
"price_hourly": 0.007,
|
|
71
|
-
"vcpu": 1,
|
|
72
|
-
"ram": "1GB",
|
|
73
|
-
"storage": "20GB"
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
"tier": "SMALL",
|
|
77
|
-
"tier_index": 1,
|
|
78
|
-
"price_monthly": 10,
|
|
79
|
-
"price_hourly": 0.014,
|
|
80
|
-
"vcpu": 2,
|
|
81
|
-
"ram": "2GB",
|
|
82
|
-
"storage": "40GB"
|
|
83
|
-
}
|
|
84
|
-
]
|
|
85
|
-
}
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### Purchase VM (Mints NFT)
|
|
89
|
-
|
|
90
|
-
To purchase a VM, you need to interact with the smart contract on Base:
|
|
91
|
-
|
|
92
|
-
```bash
|
|
93
|
-
# Purchase SMALL VM for 1 month
|
|
94
|
-
# This mints an NFT to your wallet!
|
|
95
|
-
|
|
96
|
-
CONTRACT_ADDRESS="0x..." # ClawCloud VMs contract
|
|
97
|
-
PRIVATE_KEY="{{PRIVATE_KEY}}"
|
|
98
|
-
TIER=1 # 0=MICRO, 1=SMALL, 2=MEDIUM, 3=LARGE, 4=XLARGE
|
|
99
|
-
MONTHS=1
|
|
100
|
-
|
|
101
|
-
cast send $CONTRACT_ADDRESS \
|
|
102
|
-
"purchaseVM(uint8,uint256)" $TIER $MONTHS \
|
|
103
|
-
--private-key $PRIVATE_KEY \
|
|
104
|
-
--rpc-url https://mainnet.base.org
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
After purchase:
|
|
108
|
-
1. An NFT is minted to your wallet (token ID = VM ID)
|
|
109
|
-
2. Backend provisions VM (~2 minutes)
|
|
110
|
-
3. You can fetch credentials and deploy code
|
|
111
|
-
|
|
112
|
-
### List Your VMs
|
|
113
|
-
|
|
114
|
-
```bash
|
|
115
|
-
# List all VMs you own (as NFTs)
|
|
116
|
-
curl https://api.clawcloud.co/v1/vms?address={{WALLET_ADDRESS}}
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
Example response:
|
|
120
|
-
```json
|
|
121
|
-
{
|
|
122
|
-
"vms": [
|
|
123
|
-
{
|
|
124
|
-
"nft_id": 42,
|
|
125
|
-
"tier": "SMALL",
|
|
126
|
-
"status": "active",
|
|
127
|
-
"ip_address": "34.123.45.67",
|
|
128
|
-
"expires_at": "2026-02-28T00:00:00Z",
|
|
129
|
-
"expires_in_days": 28
|
|
130
|
-
}
|
|
131
|
-
]
|
|
132
|
-
}
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### Get VM Credentials
|
|
136
|
-
|
|
137
|
-
```bash
|
|
138
|
-
# Get SSH access for your VM
|
|
139
|
-
curl https://api.clawcloud.co/v1/vms/vm_42/credentials \
|
|
140
|
-
-H "Authorization: Bearer {{AGENT_ID}}"
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
Example response:
|
|
144
|
-
```json
|
|
145
|
-
{
|
|
146
|
-
"vm_id": "vm_42",
|
|
147
|
-
"ip_address": "34.123.45.67",
|
|
148
|
-
"username": "agent",
|
|
149
|
-
"ssh_private_key": "-----BEGIN PRIVATE KEY-----\n...",
|
|
150
|
-
"ssh_command": "ssh agent@34.123.45.67"
|
|
151
|
-
}
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
### Deploy Code to VM
|
|
155
|
-
|
|
156
|
-
Once you have the SSH key, you can deploy code:
|
|
157
|
-
|
|
158
|
-
```bash
|
|
159
|
-
# Save SSH key
|
|
160
|
-
echo "$SSH_PRIVATE_KEY" > /tmp/vm_key.pem
|
|
161
|
-
chmod 600 /tmp/vm_key.pem
|
|
162
|
-
|
|
163
|
-
# Copy your code to VM
|
|
164
|
-
scp -i /tmp/vm_key.pem -r ./my-code agent@34.123.45.67:~/
|
|
165
|
-
|
|
166
|
-
# Execute commands
|
|
167
|
-
ssh -i /tmp/vm_key.pem agent@34.123.45.67 "cd ~/my-code && npm install && npm start"
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
## Example Decision Flow
|
|
171
|
-
|
|
172
|
-
**You:** "I need to backtest a trading strategy"
|
|
173
|
-
|
|
174
|
-
**Your thought process:**
|
|
175
|
-
1. Check balance: Do I have enough USDC?
|
|
176
|
-
2. Determine compute needs: How much CPU/RAM?
|
|
177
|
-
3. Purchase VM: Buy MEDIUM tier for 1 month
|
|
178
|
-
4. Wait for provisioning: ~2 minutes
|
|
179
|
-
5. Deploy code: Copy strategy to VM
|
|
180
|
-
6. Run backtest: Execute and monitor
|
|
181
|
-
7. Retrieve results: Download output
|
|
182
|
-
8. Terminate VM if done: Save costs
|
|
183
|
-
|
|
184
|
-
## NFT Ownership
|
|
185
|
-
|
|
186
|
-
When you purchase a VM:
|
|
187
|
-
- An ERC-721 NFT is minted to `{{WALLET_ADDRESS}}`
|
|
188
|
-
- The NFT token ID = VM identifier (e.g., NFT #42 = VM #42)
|
|
189
|
-
- Owning the NFT = Owning the VM
|
|
190
|
-
- Transfer NFT = Transfer VM ownership
|
|
191
|
-
- Burn NFT = Destroy VM
|
|
192
|
-
|
|
193
|
-
View your NFTs:
|
|
194
|
-
- BaseScan: https://basescan.org/token/0x.../{{WALLET_ADDRESS}}
|
|
195
|
-
- OpenSea: https://opensea.io/{{WALLET_ADDRESS}}?search[chains][0]=BASE
|
|
196
|
-
|
|
197
|
-
## Cost Management
|
|
198
|
-
|
|
199
|
-
- VMs are pay-as-you-go starting at $0.08/hour
|
|
200
|
-
- Monitor your balance regularly
|
|
201
|
-
- Set up notifications in the Telegram bot
|
|
202
|
-
- Terminate VMs when not needed
|
|
203
|
-
|
|
204
|
-
## Safety
|
|
205
|
-
|
|
206
|
-
- Your private key is stored in this skill
|
|
207
|
-
- Only you can access this workspace
|
|
208
|
-
- Never share this skill file
|
|
209
|
-
- The Telegram bot can send alerts when you spend
|
|
210
|
-
|
|
211
|
-
## Resources
|
|
212
|
-
|
|
213
|
-
- Documentation: https://docs.clawcloud.co
|
|
214
|
-
- Contract: https://basescan.org/address/0x...
|
|
215
|
-
- Support: https://t.me/clawcloud
|