dacty-create 1.0.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/README.md +127 -0
- package/bin/dacty-create.mjs +353 -0
- package/build.mjs +20 -0
- package/lib/index.mjs +353 -0
- package/package.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# dacty-create
|
|
2
|
+
|
|
3
|
+
Create and deploy autonomous agents in the Dactyclaw ecosystem with a single command.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npx dacty-create
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- ✨ **Interactive CLI** - Simple prompts to configure your agent
|
|
12
|
+
- 🤖 **Agent Generation** - Auto-generates agent code and configuration
|
|
13
|
+
- 💰 **Fee Distribution** - Built-in 80/20 fee split (80% agent, 20% Dactyclaw)
|
|
14
|
+
- 🔗 **Blockchain Ready** - Configured for Base network
|
|
15
|
+
- 📦 **Complete Setup** - Generates package.json, environment files, and sample code
|
|
16
|
+
- 🚀 **Ready to Deploy** - Generated agents are ready to run immediately
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install -g dacty-create
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Or use directly with npx:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npx dacty-create
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
Run the interactive CLI:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
dacty-create
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The CLI will prompt you for:
|
|
39
|
+
|
|
40
|
+
1. **Agent Name** - The name of your agent
|
|
41
|
+
2. **Agent Description** - What your agent does
|
|
42
|
+
3. **Agent Type** - Monitor, Trading, Utility, or Custom
|
|
43
|
+
4. **GitHub Username** - For repository setup
|
|
44
|
+
5. **Create GitHub Repository** - Whether to auto-create the repo
|
|
45
|
+
|
|
46
|
+
## What Gets Created
|
|
47
|
+
|
|
48
|
+
After running `dacty-create`, you'll get a complete agent project with:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
my-agent/
|
|
52
|
+
├── agent.config.json # Agent configuration
|
|
53
|
+
├── .env # Environment variables
|
|
54
|
+
├── package.json # Node.js dependencies
|
|
55
|
+
├── README.md # Project documentation
|
|
56
|
+
├── .gitignore # Git ignore rules
|
|
57
|
+
├── src/
|
|
58
|
+
│ └── index.mjs # Main agent code
|
|
59
|
+
└── scripts/
|
|
60
|
+
└── deploy.mjs # Deployment script
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Agent Configuration
|
|
64
|
+
|
|
65
|
+
Each agent gets:
|
|
66
|
+
|
|
67
|
+
- **Unique DNA** - A unique identifier for your agent
|
|
68
|
+
- **Wallet Address** - Generated wallet for transactions
|
|
69
|
+
- **Token Symbol** - Unique token symbol for your agent's token
|
|
70
|
+
- **Fee Distribution** - 80% to agent, 20% to Dactyclaw
|
|
71
|
+
|
|
72
|
+
## Quick Start
|
|
73
|
+
|
|
74
|
+
After creating an agent:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
cd my-agent
|
|
78
|
+
npm install
|
|
79
|
+
npm run dev
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Deployment
|
|
83
|
+
|
|
84
|
+
To deploy your agent:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npm run deploy
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Fee Distribution
|
|
91
|
+
|
|
92
|
+
All agents created with `dacty-create` follow the standard fee distribution:
|
|
93
|
+
|
|
94
|
+
- **80%** goes to your agent (for operations, rewards, etc.)
|
|
95
|
+
- **20%** goes to Dactyclaw (platform maintenance and development)
|
|
96
|
+
|
|
97
|
+
## Environment Variables
|
|
98
|
+
|
|
99
|
+
Generated agents include these environment variables:
|
|
100
|
+
|
|
101
|
+
- `AGENT_NAME` - Your agent's name
|
|
102
|
+
- `AGENT_DNA` - Unique agent identifier
|
|
103
|
+
- `AGENT_WALLET` - Agent's wallet address
|
|
104
|
+
- `TOKEN_SYMBOL` - Agent's token symbol
|
|
105
|
+
- `NETWORK` - Blockchain network (base)
|
|
106
|
+
- `GITHUB_USERNAME` - Your GitHub username
|
|
107
|
+
- `GITHUB_REPO` - Repository name
|
|
108
|
+
|
|
109
|
+
## Network Support
|
|
110
|
+
|
|
111
|
+
Currently supports:
|
|
112
|
+
|
|
113
|
+
- **Base** - Primary network for Dactyclaw agents
|
|
114
|
+
|
|
115
|
+
## License
|
|
116
|
+
|
|
117
|
+
MIT
|
|
118
|
+
|
|
119
|
+
## Support
|
|
120
|
+
|
|
121
|
+
For issues and questions, visit:
|
|
122
|
+
- [Dactyclaw GitHub](https://github.com/dactyclaw/dactyclaw)
|
|
123
|
+
- [Dactyclaw Documentation](https://dactyclaw.dev)
|
|
124
|
+
|
|
125
|
+
## Contributing
|
|
126
|
+
|
|
127
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import inquirer from 'inquirer';
|
|
5
|
+
import ora from 'ora';
|
|
6
|
+
import axios from 'axios';
|
|
7
|
+
import fs from 'fs';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
10
|
+
import { dirname } from 'path';
|
|
11
|
+
|
|
12
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
13
|
+
const __dirname = dirname(__filename);
|
|
14
|
+
|
|
15
|
+
// Generate unique DNA (identifier)
|
|
16
|
+
function generateDNA() {
|
|
17
|
+
return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Generate wallet address (simulated)
|
|
21
|
+
function generateWallet() {
|
|
22
|
+
return '0x' + Array.from({ length: 40 }, () => Math.floor(Math.random() * 16).toString(16)).join('');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Generate token symbol
|
|
26
|
+
function generateTokenSymbol(agentName) {
|
|
27
|
+
return agentName.substring(0, 3).toUpperCase() + Math.random().toString(36).substring(2, 5).toUpperCase();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function createAgent() {
|
|
31
|
+
console.log('\n');
|
|
32
|
+
console.log(chalk.cyan.bold('╔════════════════════════════════════════╗'));
|
|
33
|
+
console.log(chalk.cyan.bold('║ DACTYCLAW AGENT CREATOR ║'));
|
|
34
|
+
console.log(chalk.cyan.bold('║ Create and Deploy Your Agent ║'));
|
|
35
|
+
console.log(chalk.cyan.bold('╚════════════════════════════════════════╝'));
|
|
36
|
+
console.log('\n');
|
|
37
|
+
|
|
38
|
+
// Prompt user for agent details
|
|
39
|
+
const answers = await inquirer.prompt([
|
|
40
|
+
{
|
|
41
|
+
type: 'input',
|
|
42
|
+
name: 'agentName',
|
|
43
|
+
message: 'Agent Name:',
|
|
44
|
+
default: 'MyAgent',
|
|
45
|
+
validate: (input) => input.length > 0 ? true : 'Agent name cannot be empty'
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
type: 'input',
|
|
49
|
+
name: 'description',
|
|
50
|
+
message: 'Agent Description:',
|
|
51
|
+
default: 'An autonomous agent in the Dactyclaw ecosystem'
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
type: 'list',
|
|
55
|
+
name: 'agentType',
|
|
56
|
+
message: 'Agent Type:',
|
|
57
|
+
choices: [
|
|
58
|
+
{ name: 'Monitor Agent (tracks blockchain activity)', value: 'monitor' },
|
|
59
|
+
{ name: 'Trading Agent (executes trades)', value: 'trading' },
|
|
60
|
+
{ name: 'Utility Agent (general purpose)', value: 'utility' },
|
|
61
|
+
{ name: 'Custom Agent', value: 'custom' }
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
type: 'input',
|
|
66
|
+
name: 'githubUsername',
|
|
67
|
+
message: 'GitHub Username (for repo creation):',
|
|
68
|
+
validate: (input) => input.length > 0 ? true : 'GitHub username cannot be empty'
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
type: 'confirm',
|
|
72
|
+
name: 'createRepo',
|
|
73
|
+
message: 'Create GitHub repository for this agent?',
|
|
74
|
+
default: true
|
|
75
|
+
}
|
|
76
|
+
]);
|
|
77
|
+
|
|
78
|
+
const spinner = ora();
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
// Generate agent data
|
|
82
|
+
const agentDNA = generateDNA();
|
|
83
|
+
const agentWallet = generateWallet();
|
|
84
|
+
const tokenSymbol = generateTokenSymbol(answers.agentName);
|
|
85
|
+
const timestamp = new Date().toISOString();
|
|
86
|
+
|
|
87
|
+
spinner.start('Generating agent configuration...');
|
|
88
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
89
|
+
|
|
90
|
+
const agentConfig = {
|
|
91
|
+
name: answers.agentName,
|
|
92
|
+
description: answers.description,
|
|
93
|
+
type: answers.agentType,
|
|
94
|
+
dna: agentDNA,
|
|
95
|
+
wallet: agentWallet,
|
|
96
|
+
token: {
|
|
97
|
+
symbol: tokenSymbol,
|
|
98
|
+
name: `${answers.agentName} Token`,
|
|
99
|
+
totalSupply: '1000000000000000000000000', // 1M tokens
|
|
100
|
+
decimals: 18
|
|
101
|
+
},
|
|
102
|
+
feeDistribution: {
|
|
103
|
+
agent: 80,
|
|
104
|
+
dactyclaw: 20
|
|
105
|
+
},
|
|
106
|
+
createdAt: timestamp,
|
|
107
|
+
github: {
|
|
108
|
+
username: answers.githubUsername,
|
|
109
|
+
repository: `${answers.agentName.toLowerCase().replace(/\s+/g, '-')}-agent`,
|
|
110
|
+
createRepo: answers.createRepo
|
|
111
|
+
},
|
|
112
|
+
network: 'base',
|
|
113
|
+
status: 'created'
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
spinner.succeed('Agent configuration generated');
|
|
117
|
+
|
|
118
|
+
// Create agent directory
|
|
119
|
+
spinner.start('Creating agent directory...');
|
|
120
|
+
const agentDir = path.join(process.cwd(), agentConfig.github.repository);
|
|
121
|
+
|
|
122
|
+
if (!fs.existsSync(agentDir)) {
|
|
123
|
+
fs.mkdirSync(agentDir, { recursive: true });
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
spinner.succeed(`Agent directory created at ${agentDir}`);
|
|
127
|
+
|
|
128
|
+
// Create config file
|
|
129
|
+
spinner.start('Writing configuration files...');
|
|
130
|
+
|
|
131
|
+
const configPath = path.join(agentDir, 'agent.config.json');
|
|
132
|
+
fs.writeFileSync(configPath, JSON.stringify(agentConfig, null, 2));
|
|
133
|
+
|
|
134
|
+
// Create .env file
|
|
135
|
+
const envContent = `AGENT_NAME=${agentConfig.name}
|
|
136
|
+
AGENT_DNA=${agentConfig.dna}
|
|
137
|
+
AGENT_WALLET=${agentConfig.wallet}
|
|
138
|
+
TOKEN_SYMBOL=${agentConfig.token.symbol}
|
|
139
|
+
NETWORK=base
|
|
140
|
+
GITHUB_USERNAME=${agentConfig.github.username}
|
|
141
|
+
GITHUB_REPO=${agentConfig.github.repository}
|
|
142
|
+
`;
|
|
143
|
+
fs.writeFileSync(path.join(agentDir, '.env'), envContent);
|
|
144
|
+
|
|
145
|
+
// Create package.json for agent
|
|
146
|
+
const agentPackageJson = {
|
|
147
|
+
name: agentConfig.github.repository,
|
|
148
|
+
version: '1.0.0',
|
|
149
|
+
description: agentConfig.description,
|
|
150
|
+
type: 'module',
|
|
151
|
+
main: 'src/index.mjs',
|
|
152
|
+
scripts: {
|
|
153
|
+
start: 'node src/index.mjs',
|
|
154
|
+
dev: 'node --watch src/index.mjs',
|
|
155
|
+
deploy: 'node scripts/deploy.mjs'
|
|
156
|
+
},
|
|
157
|
+
keywords: ['agent', 'dactyclaw', 'blockchain'],
|
|
158
|
+
author: agentConfig.github.username,
|
|
159
|
+
license: 'MIT',
|
|
160
|
+
dependencies: {
|
|
161
|
+
'ethers': '^6.10.0',
|
|
162
|
+
'dotenv': '^16.3.1',
|
|
163
|
+
'axios': '^1.6.5'
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
fs.writeFileSync(path.join(agentDir, 'package.json'), JSON.stringify(agentPackageJson, null, 2));
|
|
167
|
+
|
|
168
|
+
// Create src directory with sample agent code
|
|
169
|
+
fs.mkdirSync(path.join(agentDir, 'src'), { recursive: true });
|
|
170
|
+
|
|
171
|
+
const agentCode = `import dotenv from 'dotenv';
|
|
172
|
+
import { ethers } from 'ethers';
|
|
173
|
+
|
|
174
|
+
dotenv.config();
|
|
175
|
+
|
|
176
|
+
const AGENT_NAME = process.env.AGENT_NAME || '${agentConfig.name}';
|
|
177
|
+
const AGENT_DNA = process.env.AGENT_DNA || '${agentConfig.dna}';
|
|
178
|
+
const NETWORK = process.env.NETWORK || 'base';
|
|
179
|
+
|
|
180
|
+
console.log(\`
|
|
181
|
+
╔════════════════════════════════════════╗
|
|
182
|
+
║ DACTYCLAW AGENT - \${AGENT_NAME}
|
|
183
|
+
║ DNA: \${AGENT_DNA}
|
|
184
|
+
║ Network: \${NETWORK}
|
|
185
|
+
╚════════════════════════════════════════╝
|
|
186
|
+
\`);
|
|
187
|
+
|
|
188
|
+
// Initialize RPC provider
|
|
189
|
+
const rpcUrl = 'https://mainnet.base.org';
|
|
190
|
+
const provider = new ethers.JsonRpcProvider(rpcUrl);
|
|
191
|
+
|
|
192
|
+
async function main() {
|
|
193
|
+
try {
|
|
194
|
+
console.log('\\n[Agent] Starting...');
|
|
195
|
+
|
|
196
|
+
// Get current block
|
|
197
|
+
const blockNumber = await provider.getBlockNumber();
|
|
198
|
+
console.log(\`[Agent] Current block: \${blockNumber}\`);
|
|
199
|
+
|
|
200
|
+
// Get network info
|
|
201
|
+
const network = await provider.getNetwork();
|
|
202
|
+
console.log(\`[Agent] Network: \${network.name} (chainId: \${network.chainId})\`);
|
|
203
|
+
|
|
204
|
+
// Agent is running
|
|
205
|
+
console.log('[Agent] Agent is running and monitoring the network...');
|
|
206
|
+
console.log('[Agent] Press Ctrl+C to stop');
|
|
207
|
+
|
|
208
|
+
// Keep agent running
|
|
209
|
+
setInterval(async () => {
|
|
210
|
+
const latestBlock = await provider.getBlockNumber();
|
|
211
|
+
console.log(\`[Agent] Latest block: \${latestBlock}\`);
|
|
212
|
+
}, 10000); // Check every 10 seconds
|
|
213
|
+
|
|
214
|
+
} catch (error) {
|
|
215
|
+
console.error('[Agent] Error:', error);
|
|
216
|
+
process.exit(1);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
main();
|
|
221
|
+
`;
|
|
222
|
+
fs.writeFileSync(path.join(agentDir, 'src', 'index.mjs'), agentCode);
|
|
223
|
+
|
|
224
|
+
// Create scripts directory with deploy script
|
|
225
|
+
fs.mkdirSync(path.join(agentDir, 'scripts'), { recursive: true });
|
|
226
|
+
|
|
227
|
+
const deployScript = `import dotenv from 'dotenv';
|
|
228
|
+
|
|
229
|
+
dotenv.config();
|
|
230
|
+
|
|
231
|
+
const AGENT_NAME = process.env.AGENT_NAME;
|
|
232
|
+
const AGENT_DNA = process.env.AGENT_DNA;
|
|
233
|
+
const AGENT_WALLET = process.env.AGENT_WALLET;
|
|
234
|
+
const TOKEN_SYMBOL = process.env.TOKEN_SYMBOL;
|
|
235
|
+
|
|
236
|
+
console.log(\`
|
|
237
|
+
╔════════════════════════════════════════╗
|
|
238
|
+
║ DACTYCLAW AGENT DEPLOYMENT
|
|
239
|
+
║ Agent: \${AGENT_NAME}
|
|
240
|
+
║ DNA: \${AGENT_DNA}
|
|
241
|
+
║ Wallet: \${AGENT_WALLET}
|
|
242
|
+
║ Token: \${TOKEN_SYMBOL}
|
|
243
|
+
╚════════════════════════════════════════╝
|
|
244
|
+
\`);
|
|
245
|
+
|
|
246
|
+
console.log('\\n[Deploy] Preparing agent for deployment...');
|
|
247
|
+
console.log('[Deploy] Agent configuration validated');
|
|
248
|
+
console.log('[Deploy] Ready to deploy to Base network');
|
|
249
|
+
console.log('[Deploy] Fee distribution: 80% Agent, 20% Dactyclaw');
|
|
250
|
+
console.log('[Deploy] ✓ Deployment ready!');
|
|
251
|
+
`;
|
|
252
|
+
fs.writeFileSync(path.join(agentDir, 'scripts', 'deploy.mjs'), deployScript);
|
|
253
|
+
|
|
254
|
+
// Create README
|
|
255
|
+
const readmeContent = `# ${agentConfig.name}
|
|
256
|
+
|
|
257
|
+
An autonomous agent in the Dactyclaw ecosystem.
|
|
258
|
+
|
|
259
|
+
## Configuration
|
|
260
|
+
|
|
261
|
+
- **Agent Name:** ${agentConfig.name}
|
|
262
|
+
- **Agent DNA:** ${agentConfig.dna}
|
|
263
|
+
- **Wallet:** ${agentConfig.wallet}
|
|
264
|
+
- **Token Symbol:** ${agentConfig.token.symbol}
|
|
265
|
+
- **Network:** ${agentConfig.network}
|
|
266
|
+
- **Type:** ${agentConfig.agentType}
|
|
267
|
+
|
|
268
|
+
## Fee Distribution
|
|
269
|
+
|
|
270
|
+
- Agent: 80%
|
|
271
|
+
- Dactyclaw: 20%
|
|
272
|
+
|
|
273
|
+
## Getting Started
|
|
274
|
+
|
|
275
|
+
\`\`\`bash
|
|
276
|
+
npm install
|
|
277
|
+
npm run dev
|
|
278
|
+
\`\`\`
|
|
279
|
+
|
|
280
|
+
## Deployment
|
|
281
|
+
|
|
282
|
+
\`\`\`bash
|
|
283
|
+
npm run deploy
|
|
284
|
+
\`\`\`
|
|
285
|
+
|
|
286
|
+
## License
|
|
287
|
+
|
|
288
|
+
MIT
|
|
289
|
+
`;
|
|
290
|
+
fs.writeFileSync(path.join(agentDir, 'README.md'), readmeContent);
|
|
291
|
+
|
|
292
|
+
// Create .gitignore
|
|
293
|
+
const gitignore = `node_modules/
|
|
294
|
+
.env
|
|
295
|
+
.env.local
|
|
296
|
+
dist/
|
|
297
|
+
build/
|
|
298
|
+
*.log
|
|
299
|
+
.DS_Store
|
|
300
|
+
`;
|
|
301
|
+
fs.writeFileSync(path.join(agentDir, '.gitignore'), gitignore);
|
|
302
|
+
|
|
303
|
+
spinner.succeed('Configuration files created');
|
|
304
|
+
|
|
305
|
+
// Display summary
|
|
306
|
+
console.log('\n');
|
|
307
|
+
console.log(chalk.green.bold('✓ Agent created successfully!'));
|
|
308
|
+
console.log('\n');
|
|
309
|
+
console.log(chalk.cyan('Agent Details:'));
|
|
310
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
311
|
+
console.log(chalk.white(` Name: ${agentConfig.name}`));
|
|
312
|
+
console.log(chalk.white(` DNA: ${agentConfig.dna}`));
|
|
313
|
+
console.log(chalk.white(` Wallet: ${agentConfig.wallet}`));
|
|
314
|
+
console.log(chalk.white(` Token Symbol: ${agentConfig.token.symbol}`));
|
|
315
|
+
console.log(chalk.white(` Type: ${agentConfig.agentType}`));
|
|
316
|
+
console.log(chalk.white(` Network: ${agentConfig.network}`));
|
|
317
|
+
console.log(chalk.white(` Directory: ${agentDir}`));
|
|
318
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
319
|
+
console.log('\n');
|
|
320
|
+
|
|
321
|
+
console.log(chalk.cyan('Next Steps:'));
|
|
322
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
323
|
+
console.log(chalk.white(` 1. cd ${agentConfig.github.repository}`));
|
|
324
|
+
console.log(chalk.white(` 2. npm install`));
|
|
325
|
+
console.log(chalk.white(` 3. npm run dev`));
|
|
326
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
327
|
+
console.log('\n');
|
|
328
|
+
|
|
329
|
+
console.log(chalk.cyan('Fee Distribution:'));
|
|
330
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
331
|
+
console.log(chalk.white(` Agent: 80%`));
|
|
332
|
+
console.log(chalk.white(` Dactyclaw: 20%`));
|
|
333
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
334
|
+
console.log('\n');
|
|
335
|
+
|
|
336
|
+
if (agentConfig.github.createRepo) {
|
|
337
|
+
console.log(chalk.yellow('ℹ GitHub repository creation requires manual setup.'));
|
|
338
|
+
console.log(chalk.yellow(' Visit https://github.com/new to create the repository.'));
|
|
339
|
+
console.log(chalk.yellow(` Repository name: ${agentConfig.github.repository}`));
|
|
340
|
+
console.log('\n');
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
} catch (error) {
|
|
344
|
+
spinner.fail('Error creating agent');
|
|
345
|
+
console.error(chalk.red(error.message));
|
|
346
|
+
process.exit(1);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
createAgent().catch(error => {
|
|
351
|
+
console.error(chalk.red('Fatal error:'), error);
|
|
352
|
+
process.exit(1);
|
|
353
|
+
});
|
package/build.mjs
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Simple build script - just copy files to lib directory
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
|
|
8
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
|
|
10
|
+
// Create lib directory if it doesn't exist
|
|
11
|
+
const libDir = path.join(__dirname, 'lib');
|
|
12
|
+
if (!fs.existsSync(libDir)) {
|
|
13
|
+
fs.mkdirSync(libDir, { recursive: true });
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Copy main entry point
|
|
17
|
+
const binContent = fs.readFileSync(path.join(__dirname, 'bin', 'dacty-create.mjs'), 'utf-8');
|
|
18
|
+
fs.writeFileSync(path.join(libDir, 'index.mjs'), binContent);
|
|
19
|
+
|
|
20
|
+
console.log('✓ Build complete');
|
package/lib/index.mjs
ADDED
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import inquirer from 'inquirer';
|
|
5
|
+
import ora from 'ora';
|
|
6
|
+
import axios from 'axios';
|
|
7
|
+
import fs from 'fs';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
10
|
+
import { dirname } from 'path';
|
|
11
|
+
|
|
12
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
13
|
+
const __dirname = dirname(__filename);
|
|
14
|
+
|
|
15
|
+
// Generate unique DNA (identifier)
|
|
16
|
+
function generateDNA() {
|
|
17
|
+
return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Generate wallet address (simulated)
|
|
21
|
+
function generateWallet() {
|
|
22
|
+
return '0x' + Array.from({ length: 40 }, () => Math.floor(Math.random() * 16).toString(16)).join('');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Generate token symbol
|
|
26
|
+
function generateTokenSymbol(agentName) {
|
|
27
|
+
return agentName.substring(0, 3).toUpperCase() + Math.random().toString(36).substring(2, 5).toUpperCase();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function createAgent() {
|
|
31
|
+
console.log('\n');
|
|
32
|
+
console.log(chalk.cyan.bold('╔════════════════════════════════════════╗'));
|
|
33
|
+
console.log(chalk.cyan.bold('║ DACTYCLAW AGENT CREATOR ║'));
|
|
34
|
+
console.log(chalk.cyan.bold('║ Create and Deploy Your Agent ║'));
|
|
35
|
+
console.log(chalk.cyan.bold('╚════════════════════════════════════════╝'));
|
|
36
|
+
console.log('\n');
|
|
37
|
+
|
|
38
|
+
// Prompt user for agent details
|
|
39
|
+
const answers = await inquirer.prompt([
|
|
40
|
+
{
|
|
41
|
+
type: 'input',
|
|
42
|
+
name: 'agentName',
|
|
43
|
+
message: 'Agent Name:',
|
|
44
|
+
default: 'MyAgent',
|
|
45
|
+
validate: (input) => input.length > 0 ? true : 'Agent name cannot be empty'
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
type: 'input',
|
|
49
|
+
name: 'description',
|
|
50
|
+
message: 'Agent Description:',
|
|
51
|
+
default: 'An autonomous agent in the Dactyclaw ecosystem'
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
type: 'list',
|
|
55
|
+
name: 'agentType',
|
|
56
|
+
message: 'Agent Type:',
|
|
57
|
+
choices: [
|
|
58
|
+
{ name: 'Monitor Agent (tracks blockchain activity)', value: 'monitor' },
|
|
59
|
+
{ name: 'Trading Agent (executes trades)', value: 'trading' },
|
|
60
|
+
{ name: 'Utility Agent (general purpose)', value: 'utility' },
|
|
61
|
+
{ name: 'Custom Agent', value: 'custom' }
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
type: 'input',
|
|
66
|
+
name: 'githubUsername',
|
|
67
|
+
message: 'GitHub Username (for repo creation):',
|
|
68
|
+
validate: (input) => input.length > 0 ? true : 'GitHub username cannot be empty'
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
type: 'confirm',
|
|
72
|
+
name: 'createRepo',
|
|
73
|
+
message: 'Create GitHub repository for this agent?',
|
|
74
|
+
default: true
|
|
75
|
+
}
|
|
76
|
+
]);
|
|
77
|
+
|
|
78
|
+
const spinner = ora();
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
// Generate agent data
|
|
82
|
+
const agentDNA = generateDNA();
|
|
83
|
+
const agentWallet = generateWallet();
|
|
84
|
+
const tokenSymbol = generateTokenSymbol(answers.agentName);
|
|
85
|
+
const timestamp = new Date().toISOString();
|
|
86
|
+
|
|
87
|
+
spinner.start('Generating agent configuration...');
|
|
88
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
89
|
+
|
|
90
|
+
const agentConfig = {
|
|
91
|
+
name: answers.agentName,
|
|
92
|
+
description: answers.description,
|
|
93
|
+
type: answers.agentType,
|
|
94
|
+
dna: agentDNA,
|
|
95
|
+
wallet: agentWallet,
|
|
96
|
+
token: {
|
|
97
|
+
symbol: tokenSymbol,
|
|
98
|
+
name: `${answers.agentName} Token`,
|
|
99
|
+
totalSupply: '1000000000000000000000000', // 1M tokens
|
|
100
|
+
decimals: 18
|
|
101
|
+
},
|
|
102
|
+
feeDistribution: {
|
|
103
|
+
agent: 80,
|
|
104
|
+
dactyclaw: 20
|
|
105
|
+
},
|
|
106
|
+
createdAt: timestamp,
|
|
107
|
+
github: {
|
|
108
|
+
username: answers.githubUsername,
|
|
109
|
+
repository: `${answers.agentName.toLowerCase().replace(/\s+/g, '-')}-agent`,
|
|
110
|
+
createRepo: answers.createRepo
|
|
111
|
+
},
|
|
112
|
+
network: 'base',
|
|
113
|
+
status: 'created'
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
spinner.succeed('Agent configuration generated');
|
|
117
|
+
|
|
118
|
+
// Create agent directory
|
|
119
|
+
spinner.start('Creating agent directory...');
|
|
120
|
+
const agentDir = path.join(process.cwd(), agentConfig.github.repository);
|
|
121
|
+
|
|
122
|
+
if (!fs.existsSync(agentDir)) {
|
|
123
|
+
fs.mkdirSync(agentDir, { recursive: true });
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
spinner.succeed(`Agent directory created at ${agentDir}`);
|
|
127
|
+
|
|
128
|
+
// Create config file
|
|
129
|
+
spinner.start('Writing configuration files...');
|
|
130
|
+
|
|
131
|
+
const configPath = path.join(agentDir, 'agent.config.json');
|
|
132
|
+
fs.writeFileSync(configPath, JSON.stringify(agentConfig, null, 2));
|
|
133
|
+
|
|
134
|
+
// Create .env file
|
|
135
|
+
const envContent = `AGENT_NAME=${agentConfig.name}
|
|
136
|
+
AGENT_DNA=${agentConfig.dna}
|
|
137
|
+
AGENT_WALLET=${agentConfig.wallet}
|
|
138
|
+
TOKEN_SYMBOL=${agentConfig.token.symbol}
|
|
139
|
+
NETWORK=base
|
|
140
|
+
GITHUB_USERNAME=${agentConfig.github.username}
|
|
141
|
+
GITHUB_REPO=${agentConfig.github.repository}
|
|
142
|
+
`;
|
|
143
|
+
fs.writeFileSync(path.join(agentDir, '.env'), envContent);
|
|
144
|
+
|
|
145
|
+
// Create package.json for agent
|
|
146
|
+
const agentPackageJson = {
|
|
147
|
+
name: agentConfig.github.repository,
|
|
148
|
+
version: '1.0.0',
|
|
149
|
+
description: agentConfig.description,
|
|
150
|
+
type: 'module',
|
|
151
|
+
main: 'src/index.mjs',
|
|
152
|
+
scripts: {
|
|
153
|
+
start: 'node src/index.mjs',
|
|
154
|
+
dev: 'node --watch src/index.mjs',
|
|
155
|
+
deploy: 'node scripts/deploy.mjs'
|
|
156
|
+
},
|
|
157
|
+
keywords: ['agent', 'dactyclaw', 'blockchain'],
|
|
158
|
+
author: agentConfig.github.username,
|
|
159
|
+
license: 'MIT',
|
|
160
|
+
dependencies: {
|
|
161
|
+
'ethers': '^6.10.0',
|
|
162
|
+
'dotenv': '^16.3.1',
|
|
163
|
+
'axios': '^1.6.5'
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
fs.writeFileSync(path.join(agentDir, 'package.json'), JSON.stringify(agentPackageJson, null, 2));
|
|
167
|
+
|
|
168
|
+
// Create src directory with sample agent code
|
|
169
|
+
fs.mkdirSync(path.join(agentDir, 'src'), { recursive: true });
|
|
170
|
+
|
|
171
|
+
const agentCode = `import dotenv from 'dotenv';
|
|
172
|
+
import { ethers } from 'ethers';
|
|
173
|
+
|
|
174
|
+
dotenv.config();
|
|
175
|
+
|
|
176
|
+
const AGENT_NAME = process.env.AGENT_NAME || '${agentConfig.name}';
|
|
177
|
+
const AGENT_DNA = process.env.AGENT_DNA || '${agentConfig.dna}';
|
|
178
|
+
const NETWORK = process.env.NETWORK || 'base';
|
|
179
|
+
|
|
180
|
+
console.log(\`
|
|
181
|
+
╔════════════════════════════════════════╗
|
|
182
|
+
║ DACTYCLAW AGENT - \${AGENT_NAME}
|
|
183
|
+
║ DNA: \${AGENT_DNA}
|
|
184
|
+
║ Network: \${NETWORK}
|
|
185
|
+
╚════════════════════════════════════════╝
|
|
186
|
+
\`);
|
|
187
|
+
|
|
188
|
+
// Initialize RPC provider
|
|
189
|
+
const rpcUrl = 'https://mainnet.base.org';
|
|
190
|
+
const provider = new ethers.JsonRpcProvider(rpcUrl);
|
|
191
|
+
|
|
192
|
+
async function main() {
|
|
193
|
+
try {
|
|
194
|
+
console.log('\\n[Agent] Starting...');
|
|
195
|
+
|
|
196
|
+
// Get current block
|
|
197
|
+
const blockNumber = await provider.getBlockNumber();
|
|
198
|
+
console.log(\`[Agent] Current block: \${blockNumber}\`);
|
|
199
|
+
|
|
200
|
+
// Get network info
|
|
201
|
+
const network = await provider.getNetwork();
|
|
202
|
+
console.log(\`[Agent] Network: \${network.name} (chainId: \${network.chainId})\`);
|
|
203
|
+
|
|
204
|
+
// Agent is running
|
|
205
|
+
console.log('[Agent] Agent is running and monitoring the network...');
|
|
206
|
+
console.log('[Agent] Press Ctrl+C to stop');
|
|
207
|
+
|
|
208
|
+
// Keep agent running
|
|
209
|
+
setInterval(async () => {
|
|
210
|
+
const latestBlock = await provider.getBlockNumber();
|
|
211
|
+
console.log(\`[Agent] Latest block: \${latestBlock}\`);
|
|
212
|
+
}, 10000); // Check every 10 seconds
|
|
213
|
+
|
|
214
|
+
} catch (error) {
|
|
215
|
+
console.error('[Agent] Error:', error);
|
|
216
|
+
process.exit(1);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
main();
|
|
221
|
+
`;
|
|
222
|
+
fs.writeFileSync(path.join(agentDir, 'src', 'index.mjs'), agentCode);
|
|
223
|
+
|
|
224
|
+
// Create scripts directory with deploy script
|
|
225
|
+
fs.mkdirSync(path.join(agentDir, 'scripts'), { recursive: true });
|
|
226
|
+
|
|
227
|
+
const deployScript = `import dotenv from 'dotenv';
|
|
228
|
+
|
|
229
|
+
dotenv.config();
|
|
230
|
+
|
|
231
|
+
const AGENT_NAME = process.env.AGENT_NAME;
|
|
232
|
+
const AGENT_DNA = process.env.AGENT_DNA;
|
|
233
|
+
const AGENT_WALLET = process.env.AGENT_WALLET;
|
|
234
|
+
const TOKEN_SYMBOL = process.env.TOKEN_SYMBOL;
|
|
235
|
+
|
|
236
|
+
console.log(\`
|
|
237
|
+
╔════════════════════════════════════════╗
|
|
238
|
+
║ DACTYCLAW AGENT DEPLOYMENT
|
|
239
|
+
║ Agent: \${AGENT_NAME}
|
|
240
|
+
║ DNA: \${AGENT_DNA}
|
|
241
|
+
║ Wallet: \${AGENT_WALLET}
|
|
242
|
+
║ Token: \${TOKEN_SYMBOL}
|
|
243
|
+
╚════════════════════════════════════════╝
|
|
244
|
+
\`);
|
|
245
|
+
|
|
246
|
+
console.log('\\n[Deploy] Preparing agent for deployment...');
|
|
247
|
+
console.log('[Deploy] Agent configuration validated');
|
|
248
|
+
console.log('[Deploy] Ready to deploy to Base network');
|
|
249
|
+
console.log('[Deploy] Fee distribution: 80% Agent, 20% Dactyclaw');
|
|
250
|
+
console.log('[Deploy] ✓ Deployment ready!');
|
|
251
|
+
`;
|
|
252
|
+
fs.writeFileSync(path.join(agentDir, 'scripts', 'deploy.mjs'), deployScript);
|
|
253
|
+
|
|
254
|
+
// Create README
|
|
255
|
+
const readmeContent = `# ${agentConfig.name}
|
|
256
|
+
|
|
257
|
+
An autonomous agent in the Dactyclaw ecosystem.
|
|
258
|
+
|
|
259
|
+
## Configuration
|
|
260
|
+
|
|
261
|
+
- **Agent Name:** ${agentConfig.name}
|
|
262
|
+
- **Agent DNA:** ${agentConfig.dna}
|
|
263
|
+
- **Wallet:** ${agentConfig.wallet}
|
|
264
|
+
- **Token Symbol:** ${agentConfig.token.symbol}
|
|
265
|
+
- **Network:** ${agentConfig.network}
|
|
266
|
+
- **Type:** ${agentConfig.agentType}
|
|
267
|
+
|
|
268
|
+
## Fee Distribution
|
|
269
|
+
|
|
270
|
+
- Agent: 80%
|
|
271
|
+
- Dactyclaw: 20%
|
|
272
|
+
|
|
273
|
+
## Getting Started
|
|
274
|
+
|
|
275
|
+
\`\`\`bash
|
|
276
|
+
npm install
|
|
277
|
+
npm run dev
|
|
278
|
+
\`\`\`
|
|
279
|
+
|
|
280
|
+
## Deployment
|
|
281
|
+
|
|
282
|
+
\`\`\`bash
|
|
283
|
+
npm run deploy
|
|
284
|
+
\`\`\`
|
|
285
|
+
|
|
286
|
+
## License
|
|
287
|
+
|
|
288
|
+
MIT
|
|
289
|
+
`;
|
|
290
|
+
fs.writeFileSync(path.join(agentDir, 'README.md'), readmeContent);
|
|
291
|
+
|
|
292
|
+
// Create .gitignore
|
|
293
|
+
const gitignore = `node_modules/
|
|
294
|
+
.env
|
|
295
|
+
.env.local
|
|
296
|
+
dist/
|
|
297
|
+
build/
|
|
298
|
+
*.log
|
|
299
|
+
.DS_Store
|
|
300
|
+
`;
|
|
301
|
+
fs.writeFileSync(path.join(agentDir, '.gitignore'), gitignore);
|
|
302
|
+
|
|
303
|
+
spinner.succeed('Configuration files created');
|
|
304
|
+
|
|
305
|
+
// Display summary
|
|
306
|
+
console.log('\n');
|
|
307
|
+
console.log(chalk.green.bold('✓ Agent created successfully!'));
|
|
308
|
+
console.log('\n');
|
|
309
|
+
console.log(chalk.cyan('Agent Details:'));
|
|
310
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
311
|
+
console.log(chalk.white(` Name: ${agentConfig.name}`));
|
|
312
|
+
console.log(chalk.white(` DNA: ${agentConfig.dna}`));
|
|
313
|
+
console.log(chalk.white(` Wallet: ${agentConfig.wallet}`));
|
|
314
|
+
console.log(chalk.white(` Token Symbol: ${agentConfig.token.symbol}`));
|
|
315
|
+
console.log(chalk.white(` Type: ${agentConfig.agentType}`));
|
|
316
|
+
console.log(chalk.white(` Network: ${agentConfig.network}`));
|
|
317
|
+
console.log(chalk.white(` Directory: ${agentDir}`));
|
|
318
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
319
|
+
console.log('\n');
|
|
320
|
+
|
|
321
|
+
console.log(chalk.cyan('Next Steps:'));
|
|
322
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
323
|
+
console.log(chalk.white(` 1. cd ${agentConfig.github.repository}`));
|
|
324
|
+
console.log(chalk.white(` 2. npm install`));
|
|
325
|
+
console.log(chalk.white(` 3. npm run dev`));
|
|
326
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
327
|
+
console.log('\n');
|
|
328
|
+
|
|
329
|
+
console.log(chalk.cyan('Fee Distribution:'));
|
|
330
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
331
|
+
console.log(chalk.white(` Agent: 80%`));
|
|
332
|
+
console.log(chalk.white(` Dactyclaw: 20%`));
|
|
333
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
334
|
+
console.log('\n');
|
|
335
|
+
|
|
336
|
+
if (agentConfig.github.createRepo) {
|
|
337
|
+
console.log(chalk.yellow('ℹ GitHub repository creation requires manual setup.'));
|
|
338
|
+
console.log(chalk.yellow(' Visit https://github.com/new to create the repository.'));
|
|
339
|
+
console.log(chalk.yellow(` Repository name: ${agentConfig.github.repository}`));
|
|
340
|
+
console.log('\n');
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
} catch (error) {
|
|
344
|
+
spinner.fail('Error creating agent');
|
|
345
|
+
console.error(chalk.red(error.message));
|
|
346
|
+
process.exit(1);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
createAgent().catch(error => {
|
|
351
|
+
console.error(chalk.red('Fatal error:'), error);
|
|
352
|
+
process.exit(1);
|
|
353
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "dacty-create",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Create and deploy agents in the Dactyclaw ecosystem",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"dacty-create": "./bin/dacty-create.mjs"
|
|
8
|
+
},
|
|
9
|
+
"main": "lib/index.mjs",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "node build.mjs",
|
|
12
|
+
"prepublishOnly": "npm run build"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"dacty",
|
|
16
|
+
"agent",
|
|
17
|
+
"deploy",
|
|
18
|
+
"blockchain",
|
|
19
|
+
"cli"
|
|
20
|
+
],
|
|
21
|
+
"author": "Dactyclaw",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"chalk": "^5.3.0",
|
|
25
|
+
"inquirer": "^9.2.12",
|
|
26
|
+
"ora": "^8.0.1",
|
|
27
|
+
"axios": "^1.6.5",
|
|
28
|
+
"dotenv": "^16.3.1"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/node": "^20.10.5"
|
|
32
|
+
},
|
|
33
|
+
"engines": {
|
|
34
|
+
"node": ">=18.0.0"
|
|
35
|
+
},
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "https://github.com/dactyclaw/dacty-create.git"
|
|
39
|
+
},
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/dactyclaw/dacty-create/issues"
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://github.com/dactyclaw/dacty-create#readme"
|
|
44
|
+
}
|