dacty-create 1.0.0 → 1.0.2

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.
@@ -3,28 +3,29 @@
3
3
  import chalk from 'chalk';
4
4
  import inquirer from 'inquirer';
5
5
  import ora from 'ora';
6
- import axios from 'axios';
7
6
  import fs from 'fs';
8
7
  import path from 'path';
9
8
  import { fileURLToPath } from 'url';
10
9
  import { dirname } from 'path';
10
+ import crypto from 'crypto';
11
11
 
12
12
  const __filename = fileURLToPath(import.meta.url);
13
13
  const __dirname = dirname(__filename);
14
14
 
15
15
  // Generate unique DNA (identifier)
16
16
  function generateDNA() {
17
- return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
17
+ return crypto.randomBytes(16).toString('hex');
18
18
  }
19
19
 
20
- // Generate wallet address (simulated)
20
+ // Generate wallet (Ethereum-style)
21
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();
22
+ const privateKey = crypto.randomBytes(32).toString('hex');
23
+ return {
24
+ privateKey: '0x' + privateKey,
25
+ // Note: In production, derive address from private key using ethers.js
26
+ // For now, generate a mock address
27
+ address: '0x' + crypto.randomBytes(20).toString('hex')
28
+ };
28
29
  }
29
30
 
30
31
  async function createAgent() {
@@ -64,14 +65,8 @@ async function createAgent() {
64
65
  {
65
66
  type: 'input',
66
67
  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
68
+ message: 'GitHub Username (optional):',
69
+ default: ''
75
70
  }
76
71
  ]);
77
72
 
@@ -80,8 +75,7 @@ async function createAgent() {
80
75
  try {
81
76
  // Generate agent data
82
77
  const agentDNA = generateDNA();
83
- const agentWallet = generateWallet();
84
- const tokenSymbol = generateTokenSymbol(answers.agentName);
78
+ const wallet = generateWallet();
85
79
  const timestamp = new Date().toISOString();
86
80
 
87
81
  spinner.start('Generating agent configuration...');
@@ -92,32 +86,18 @@ async function createAgent() {
92
86
  description: answers.description,
93
87
  type: answers.agentType,
94
88
  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
- },
89
+ wallet: wallet.address,
106
90
  createdAt: timestamp,
107
- github: {
108
- username: answers.githubUsername,
109
- repository: `${answers.agentName.toLowerCase().replace(/\s+/g, '-')}-agent`,
110
- createRepo: answers.createRepo
111
- },
112
91
  network: 'base',
113
- status: 'created'
92
+ status: 'created',
93
+ version: '1.0.0'
114
94
  };
115
95
 
116
96
  spinner.succeed('Agent configuration generated');
117
97
 
118
98
  // Create agent directory
119
99
  spinner.start('Creating agent directory...');
120
- const agentDir = path.join(process.cwd(), agentConfig.github.repository);
100
+ const agentDir = path.join(process.cwd(), answers.agentName.toLowerCase().replace(/\s+/g, '-') + '-agent');
121
101
 
122
102
  if (!fs.existsSync(agentDir)) {
123
103
  fs.mkdirSync(agentDir, { recursive: true });
@@ -125,26 +105,47 @@ async function createAgent() {
125
105
 
126
106
  spinner.succeed(`Agent directory created at ${agentDir}`);
127
107
 
128
- // Create config file
108
+ // Create config file (safe - no private key)
129
109
  spinner.start('Writing configuration files...');
130
110
 
131
111
  const configPath = path.join(agentDir, 'agent.config.json');
132
112
  fs.writeFileSync(configPath, JSON.stringify(agentConfig, null, 2));
133
113
 
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}
114
+ // Create .env file with private key (gitignored)
115
+ const envContent = `# DACTYCLAW Agent Environment Variables
116
+ # IMPORTANT: Keep this file secret! Never commit to version control!
117
+
118
+ AGENT_NAME="${agentConfig.name}"
119
+ AGENT_DNA="${agentConfig.dna}"
120
+ AGENT_WALLET="${wallet.address}"
121
+ AGENT_PRIVATE_KEY="${wallet.privateKey}"
122
+ NETWORK="base"
123
+ GITHUB_USERNAME="${answers.githubUsername || ''}"
124
+
125
+ # Clanker API (optional - user can add their own)
126
+ # CLANKER_API_KEY=""
142
127
  `;
143
128
  fs.writeFileSync(path.join(agentDir, '.env'), envContent);
144
129
 
130
+ // Create .env.example (safe - no private key)
131
+ const envExampleContent = `# DACTYCLAW Agent Environment Variables
132
+ # Copy this file to .env and fill in your values
133
+
134
+ AGENT_NAME="MyAgent"
135
+ AGENT_DNA="your-agent-dna"
136
+ AGENT_WALLET="0x..."
137
+ AGENT_PRIVATE_KEY="0x..."
138
+ NETWORK="base"
139
+ GITHUB_USERNAME=""
140
+
141
+ # Clanker API (optional)
142
+ # CLANKER_API_KEY=""
143
+ `;
144
+ fs.writeFileSync(path.join(agentDir, '.env.example'), envExampleContent);
145
+
145
146
  // Create package.json for agent
146
147
  const agentPackageJson = {
147
- name: agentConfig.github.repository,
148
+ name: agentConfig.name.toLowerCase().replace(/\s+/g, '-') + '-agent',
148
149
  version: '1.0.0',
149
150
  description: agentConfig.description,
150
151
  type: 'module',
@@ -152,15 +153,16 @@ GITHUB_REPO=${agentConfig.github.repository}
152
153
  scripts: {
153
154
  start: 'node src/index.mjs',
154
155
  dev: 'node --watch src/index.mjs',
155
- deploy: 'node scripts/deploy.mjs'
156
+ launch: 'node scripts/launch.mjs'
156
157
  },
157
- keywords: ['agent', 'dactyclaw', 'blockchain'],
158
- author: agentConfig.github.username,
158
+ keywords: ['agent', 'dactyclaw', 'blockchain', 'base'],
159
+ author: answers.githubUsername || 'Dactyclaw Agent',
159
160
  license: 'MIT',
160
161
  dependencies: {
161
162
  'ethers': '^6.10.0',
162
163
  'dotenv': '^16.3.1',
163
- 'axios': '^1.6.5'
164
+ 'axios': '^1.6.5',
165
+ 'chalk': '^5.3.0'
164
166
  }
165
167
  };
166
168
  fs.writeFileSync(path.join(agentDir, 'package.json'), JSON.stringify(agentPackageJson, null, 2));
@@ -173,19 +175,21 @@ import { ethers } from 'ethers';
173
175
 
174
176
  dotenv.config();
175
177
 
176
- const AGENT_NAME = process.env.AGENT_NAME || '${agentConfig.name}';
177
- const AGENT_DNA = process.env.AGENT_DNA || '${agentConfig.dna}';
178
+ const AGENT_NAME = process.env.AGENT_NAME || 'Agent';
179
+ const AGENT_DNA = process.env.AGENT_DNA || '';
180
+ const AGENT_WALLET = process.env.AGENT_WALLET || '';
178
181
  const NETWORK = process.env.NETWORK || 'base';
179
182
 
180
183
  console.log(\`
181
184
  ╔════════════════════════════════════════╗
182
185
  ║ DACTYCLAW AGENT - \${AGENT_NAME}
183
- ║ DNA: \${AGENT_DNA}
186
+ ║ DNA: \${AGENT_DNA.substring(0, 16)}...
187
+ ║ Wallet: \${AGENT_WALLET.substring(0, 10)}...
184
188
  ║ Network: \${NETWORK}
185
189
  ╚════════════════════════════════════════╝
186
190
  \`);
187
191
 
188
- // Initialize RPC provider
192
+ // Initialize RPC provider for Base network
189
193
  const rpcUrl = 'https://mainnet.base.org';
190
194
  const provider = new ethers.JsonRpcProvider(rpcUrl);
191
195
 
@@ -201,6 +205,10 @@ async function main() {
201
205
  const network = await provider.getNetwork();
202
206
  console.log(\`[Agent] Network: \${network.name} (chainId: \${network.chainId})\`);
203
207
 
208
+ // Get wallet balance
209
+ const balance = await provider.getBalance(process.env.AGENT_WALLET);
210
+ console.log(\`[Agent] Wallet balance: \${ethers.formatEther(balance)} ETH\`);
211
+
204
212
  // Agent is running
205
213
  console.log('[Agent] Agent is running and monitoring the network...');
206
214
  console.log('[Agent] Press Ctrl+C to stop');
@@ -209,7 +217,7 @@ async function main() {
209
217
  setInterval(async () => {
210
218
  const latestBlock = await provider.getBlockNumber();
211
219
  console.log(\`[Agent] Latest block: \${latestBlock}\`);
212
- }, 10000); // Check every 10 seconds
220
+ }, 30000); // Check every 30 seconds
213
221
 
214
222
  } catch (error) {
215
223
  console.error('[Agent] Error:', error);
@@ -221,35 +229,35 @@ main();
221
229
  `;
222
230
  fs.writeFileSync(path.join(agentDir, 'src', 'index.mjs'), agentCode);
223
231
 
224
- // Create scripts directory with deploy script
232
+ // Create scripts directory with launch script
225
233
  fs.mkdirSync(path.join(agentDir, 'scripts'), { recursive: true });
226
234
 
227
- const deployScript = `import dotenv from 'dotenv';
235
+ const launchScript = `import dotenv from 'dotenv';
228
236
 
229
237
  dotenv.config();
230
238
 
231
239
  const AGENT_NAME = process.env.AGENT_NAME;
232
240
  const AGENT_DNA = process.env.AGENT_DNA;
233
241
  const AGENT_WALLET = process.env.AGENT_WALLET;
234
- const TOKEN_SYMBOL = process.env.TOKEN_SYMBOL;
242
+ const AGENT_PRIVATE_KEY = process.env.AGENT_PRIVATE_KEY;
235
243
 
236
244
  console.log(\`
237
245
  ╔════════════════════════════════════════╗
238
- ║ DACTYCLAW AGENT DEPLOYMENT
246
+ ║ DACTYCLAW TOKEN LAUNCH
239
247
  ║ Agent: \${AGENT_NAME}
240
248
  ║ DNA: \${AGENT_DNA}
241
249
  ║ Wallet: \${AGENT_WALLET}
242
- ║ Token: \${TOKEN_SYMBOL}
243
250
  ╚════════════════════════════════════════╝
244
251
  \`);
245
252
 
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!');
253
+ console.log('\\n[Launch] Preparing to launch token...');
254
+ console.log('[Launch] Agent configuration loaded');
255
+ console.log('[Launch] Wallet ready');
256
+ console.log('[Launch] Private key loaded');
257
+ console.log('[Launch] ✓ Ready to deploy!');
258
+ console.log('\\n[Launch] Next step: npx dacty-launch');
251
259
  `;
252
- fs.writeFileSync(path.join(agentDir, 'scripts', 'deploy.mjs'), deployScript);
260
+ fs.writeFileSync(path.join(agentDir, 'scripts', 'launch.mjs'), launchScript);
253
261
 
254
262
  // Create README
255
263
  const readmeContent = `# ${agentConfig.name}
@@ -260,16 +268,10 @@ An autonomous agent in the Dactyclaw ecosystem.
260
268
 
261
269
  - **Agent Name:** ${agentConfig.name}
262
270
  - **Agent DNA:** ${agentConfig.dna}
263
- - **Wallet:** ${agentConfig.wallet}
264
- - **Token Symbol:** ${agentConfig.token.symbol}
265
- - **Network:** ${agentConfig.network}
271
+ - **Wallet:** ${wallet.address}
272
+ - **Network:** Base
266
273
  - **Type:** ${agentConfig.agentType}
267
274
 
268
- ## Fee Distribution
269
-
270
- - Agent: 80%
271
- - Dactyclaw: 20%
272
-
273
275
  ## Getting Started
274
276
 
275
277
  \`\`\`bash
@@ -277,12 +279,42 @@ npm install
277
279
  npm run dev
278
280
  \`\`\`
279
281
 
280
- ## Deployment
282
+ ## Environment Variables
283
+
284
+ This project uses a \`.env\` file to store sensitive information including your private key.
285
+
286
+ **⚠️ IMPORTANT: Never commit \`.env\` to version control!**
287
+
288
+ The \`.env\` file is already in \`.gitignore\` for your safety.
289
+
290
+ ## Launch Token
291
+
292
+ To launch your token on Clanker:
281
293
 
282
294
  \`\`\`bash
283
- npm run deploy
295
+ npx dacty-launch
284
296
  \`\`\`
285
297
 
298
+ This will:
299
+ 1. Use your private key to sign transactions
300
+ 2. Deploy token to Base network via Clanker
301
+ 3. Setup fee distribution (80% to your wallet, 20% to Dactyclaw)
302
+
303
+ ## Fee Distribution
304
+
305
+ Once your token is launched:
306
+ - **80%** of trading fees go to your agent wallet
307
+ - **20%** of trading fees go to Dactyclaw
308
+
309
+ Monitor your fees on [Clanker.world](https://clanker.world)
310
+
311
+ ## Security
312
+
313
+ - Keep your \`.env\` file private
314
+ - Never share your private key
315
+ - Never commit \`.env\` to version control
316
+ - Use a hardware wallet for production
317
+
286
318
  ## License
287
319
 
288
320
  MIT
@@ -293,13 +325,32 @@ MIT
293
325
  const gitignore = `node_modules/
294
326
  .env
295
327
  .env.local
328
+ .env.*.local
296
329
  dist/
297
330
  build/
298
331
  *.log
332
+ npm-debug.log*
333
+ yarn-debug.log*
334
+ yarn-error.log*
299
335
  .DS_Store
336
+ .vscode/
337
+ .idea/
338
+ *.swp
339
+ *.swo
340
+ *~
341
+ .pnpm-store/
342
+ pnpm-lock.yaml
343
+ package-lock.json
300
344
  `;
301
345
  fs.writeFileSync(path.join(agentDir, '.gitignore'), gitignore);
302
346
 
347
+ // Create .gitattributes to ensure .env is never committed
348
+ const gitattributes = `# Ensure .env files are never committed
349
+ .env export-ignore
350
+ .env.* export-ignore
351
+ `;
352
+ fs.writeFileSync(path.join(agentDir, '.gitattributes'), gitattributes);
353
+
303
354
  spinner.succeed('Configuration files created');
304
355
 
305
356
  // Display summary
@@ -307,38 +358,32 @@ build/
307
358
  console.log(chalk.green.bold('✓ Agent created successfully!'));
308
359
  console.log('\n');
309
360
  console.log(chalk.cyan('Agent Details:'));
310
- console.log(chalk.gray('─'.repeat(50)));
361
+ console.log(chalk.gray('─'.repeat(60)));
311
362
  console.log(chalk.white(` Name: ${agentConfig.name}`));
312
363
  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}`));
364
+ console.log(chalk.white(` Wallet Address: ${wallet.address}`));
315
365
  console.log(chalk.white(` Type: ${agentConfig.agentType}`));
316
366
  console.log(chalk.white(` Network: ${agentConfig.network}`));
317
367
  console.log(chalk.white(` Directory: ${agentDir}`));
318
- console.log(chalk.gray('─'.repeat(50)));
368
+ console.log(chalk.gray('─'.repeat(60)));
369
+ console.log('\n');
370
+
371
+ console.log(chalk.cyan('Security Notice:'));
372
+ console.log(chalk.gray('─'.repeat(60)));
373
+ console.log(chalk.yellow(` ⚠️ Your private key is stored in .env file`));
374
+ console.log(chalk.yellow(` ⚠️ NEVER commit .env to version control`));
375
+ console.log(chalk.yellow(` ⚠️ Keep your private key safe and secure`));
376
+ console.log(chalk.gray('─'.repeat(60)));
319
377
  console.log('\n');
320
378
 
321
379
  console.log(chalk.cyan('Next Steps:'));
322
- console.log(chalk.gray('─'.repeat(50)));
323
- console.log(chalk.white(` 1. cd ${agentConfig.github.repository}`));
380
+ console.log(chalk.gray('─'.repeat(60)));
381
+ console.log(chalk.white(` 1. cd ${path.basename(agentDir)}`));
324
382
  console.log(chalk.white(` 2. npm install`));
325
383
  console.log(chalk.white(` 3. npm run dev`));
326
- console.log(chalk.gray('─'.repeat(50)));
384
+ console.log(chalk.white(` 4. npx dacty-launch (to launch token)`));
385
+ console.log(chalk.gray('─'.repeat(60)));
327
386
  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
387
 
343
388
  } catch (error) {
344
389
  spinner.fail('Error creating agent');
package/lib/index.mjs CHANGED
@@ -3,28 +3,29 @@
3
3
  import chalk from 'chalk';
4
4
  import inquirer from 'inquirer';
5
5
  import ora from 'ora';
6
- import axios from 'axios';
7
6
  import fs from 'fs';
8
7
  import path from 'path';
9
8
  import { fileURLToPath } from 'url';
10
9
  import { dirname } from 'path';
10
+ import crypto from 'crypto';
11
11
 
12
12
  const __filename = fileURLToPath(import.meta.url);
13
13
  const __dirname = dirname(__filename);
14
14
 
15
15
  // Generate unique DNA (identifier)
16
16
  function generateDNA() {
17
- return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
17
+ return crypto.randomBytes(16).toString('hex');
18
18
  }
19
19
 
20
- // Generate wallet address (simulated)
20
+ // Generate wallet (Ethereum-style)
21
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();
22
+ const privateKey = crypto.randomBytes(32).toString('hex');
23
+ return {
24
+ privateKey: '0x' + privateKey,
25
+ // Note: In production, derive address from private key using ethers.js
26
+ // For now, generate a mock address
27
+ address: '0x' + crypto.randomBytes(20).toString('hex')
28
+ };
28
29
  }
29
30
 
30
31
  async function createAgent() {
@@ -64,14 +65,8 @@ async function createAgent() {
64
65
  {
65
66
  type: 'input',
66
67
  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
68
+ message: 'GitHub Username (optional):',
69
+ default: ''
75
70
  }
76
71
  ]);
77
72
 
@@ -80,8 +75,7 @@ async function createAgent() {
80
75
  try {
81
76
  // Generate agent data
82
77
  const agentDNA = generateDNA();
83
- const agentWallet = generateWallet();
84
- const tokenSymbol = generateTokenSymbol(answers.agentName);
78
+ const wallet = generateWallet();
85
79
  const timestamp = new Date().toISOString();
86
80
 
87
81
  spinner.start('Generating agent configuration...');
@@ -92,32 +86,18 @@ async function createAgent() {
92
86
  description: answers.description,
93
87
  type: answers.agentType,
94
88
  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
- },
89
+ wallet: wallet.address,
106
90
  createdAt: timestamp,
107
- github: {
108
- username: answers.githubUsername,
109
- repository: `${answers.agentName.toLowerCase().replace(/\s+/g, '-')}-agent`,
110
- createRepo: answers.createRepo
111
- },
112
91
  network: 'base',
113
- status: 'created'
92
+ status: 'created',
93
+ version: '1.0.0'
114
94
  };
115
95
 
116
96
  spinner.succeed('Agent configuration generated');
117
97
 
118
98
  // Create agent directory
119
99
  spinner.start('Creating agent directory...');
120
- const agentDir = path.join(process.cwd(), agentConfig.github.repository);
100
+ const agentDir = path.join(process.cwd(), answers.agentName.toLowerCase().replace(/\s+/g, '-') + '-agent');
121
101
 
122
102
  if (!fs.existsSync(agentDir)) {
123
103
  fs.mkdirSync(agentDir, { recursive: true });
@@ -125,26 +105,47 @@ async function createAgent() {
125
105
 
126
106
  spinner.succeed(`Agent directory created at ${agentDir}`);
127
107
 
128
- // Create config file
108
+ // Create config file (safe - no private key)
129
109
  spinner.start('Writing configuration files...');
130
110
 
131
111
  const configPath = path.join(agentDir, 'agent.config.json');
132
112
  fs.writeFileSync(configPath, JSON.stringify(agentConfig, null, 2));
133
113
 
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}
114
+ // Create .env file with private key (gitignored)
115
+ const envContent = `# DACTYCLAW Agent Environment Variables
116
+ # IMPORTANT: Keep this file secret! Never commit to version control!
117
+
118
+ AGENT_NAME="${agentConfig.name}"
119
+ AGENT_DNA="${agentConfig.dna}"
120
+ AGENT_WALLET="${wallet.address}"
121
+ AGENT_PRIVATE_KEY="${wallet.privateKey}"
122
+ NETWORK="base"
123
+ GITHUB_USERNAME="${answers.githubUsername || ''}"
124
+
125
+ # Clanker API (optional - user can add their own)
126
+ # CLANKER_API_KEY=""
142
127
  `;
143
128
  fs.writeFileSync(path.join(agentDir, '.env'), envContent);
144
129
 
130
+ // Create .env.example (safe - no private key)
131
+ const envExampleContent = `# DACTYCLAW Agent Environment Variables
132
+ # Copy this file to .env and fill in your values
133
+
134
+ AGENT_NAME="MyAgent"
135
+ AGENT_DNA="your-agent-dna"
136
+ AGENT_WALLET="0x..."
137
+ AGENT_PRIVATE_KEY="0x..."
138
+ NETWORK="base"
139
+ GITHUB_USERNAME=""
140
+
141
+ # Clanker API (optional)
142
+ # CLANKER_API_KEY=""
143
+ `;
144
+ fs.writeFileSync(path.join(agentDir, '.env.example'), envExampleContent);
145
+
145
146
  // Create package.json for agent
146
147
  const agentPackageJson = {
147
- name: agentConfig.github.repository,
148
+ name: agentConfig.name.toLowerCase().replace(/\s+/g, '-') + '-agent',
148
149
  version: '1.0.0',
149
150
  description: agentConfig.description,
150
151
  type: 'module',
@@ -152,15 +153,16 @@ GITHUB_REPO=${agentConfig.github.repository}
152
153
  scripts: {
153
154
  start: 'node src/index.mjs',
154
155
  dev: 'node --watch src/index.mjs',
155
- deploy: 'node scripts/deploy.mjs'
156
+ launch: 'node scripts/launch.mjs'
156
157
  },
157
- keywords: ['agent', 'dactyclaw', 'blockchain'],
158
- author: agentConfig.github.username,
158
+ keywords: ['agent', 'dactyclaw', 'blockchain', 'base'],
159
+ author: answers.githubUsername || 'Dactyclaw Agent',
159
160
  license: 'MIT',
160
161
  dependencies: {
161
162
  'ethers': '^6.10.0',
162
163
  'dotenv': '^16.3.1',
163
- 'axios': '^1.6.5'
164
+ 'axios': '^1.6.5',
165
+ 'chalk': '^5.3.0'
164
166
  }
165
167
  };
166
168
  fs.writeFileSync(path.join(agentDir, 'package.json'), JSON.stringify(agentPackageJson, null, 2));
@@ -173,19 +175,21 @@ import { ethers } from 'ethers';
173
175
 
174
176
  dotenv.config();
175
177
 
176
- const AGENT_NAME = process.env.AGENT_NAME || '${agentConfig.name}';
177
- const AGENT_DNA = process.env.AGENT_DNA || '${agentConfig.dna}';
178
+ const AGENT_NAME = process.env.AGENT_NAME || 'Agent';
179
+ const AGENT_DNA = process.env.AGENT_DNA || '';
180
+ const AGENT_WALLET = process.env.AGENT_WALLET || '';
178
181
  const NETWORK = process.env.NETWORK || 'base';
179
182
 
180
183
  console.log(\`
181
184
  ╔════════════════════════════════════════╗
182
185
  ║ DACTYCLAW AGENT - \${AGENT_NAME}
183
- ║ DNA: \${AGENT_DNA}
186
+ ║ DNA: \${AGENT_DNA.substring(0, 16)}...
187
+ ║ Wallet: \${AGENT_WALLET.substring(0, 10)}...
184
188
  ║ Network: \${NETWORK}
185
189
  ╚════════════════════════════════════════╝
186
190
  \`);
187
191
 
188
- // Initialize RPC provider
192
+ // Initialize RPC provider for Base network
189
193
  const rpcUrl = 'https://mainnet.base.org';
190
194
  const provider = new ethers.JsonRpcProvider(rpcUrl);
191
195
 
@@ -201,6 +205,10 @@ async function main() {
201
205
  const network = await provider.getNetwork();
202
206
  console.log(\`[Agent] Network: \${network.name} (chainId: \${network.chainId})\`);
203
207
 
208
+ // Get wallet balance
209
+ const balance = await provider.getBalance(process.env.AGENT_WALLET);
210
+ console.log(\`[Agent] Wallet balance: \${ethers.formatEther(balance)} ETH\`);
211
+
204
212
  // Agent is running
205
213
  console.log('[Agent] Agent is running and monitoring the network...');
206
214
  console.log('[Agent] Press Ctrl+C to stop');
@@ -209,7 +217,7 @@ async function main() {
209
217
  setInterval(async () => {
210
218
  const latestBlock = await provider.getBlockNumber();
211
219
  console.log(\`[Agent] Latest block: \${latestBlock}\`);
212
- }, 10000); // Check every 10 seconds
220
+ }, 30000); // Check every 30 seconds
213
221
 
214
222
  } catch (error) {
215
223
  console.error('[Agent] Error:', error);
@@ -221,35 +229,35 @@ main();
221
229
  `;
222
230
  fs.writeFileSync(path.join(agentDir, 'src', 'index.mjs'), agentCode);
223
231
 
224
- // Create scripts directory with deploy script
232
+ // Create scripts directory with launch script
225
233
  fs.mkdirSync(path.join(agentDir, 'scripts'), { recursive: true });
226
234
 
227
- const deployScript = `import dotenv from 'dotenv';
235
+ const launchScript = `import dotenv from 'dotenv';
228
236
 
229
237
  dotenv.config();
230
238
 
231
239
  const AGENT_NAME = process.env.AGENT_NAME;
232
240
  const AGENT_DNA = process.env.AGENT_DNA;
233
241
  const AGENT_WALLET = process.env.AGENT_WALLET;
234
- const TOKEN_SYMBOL = process.env.TOKEN_SYMBOL;
242
+ const AGENT_PRIVATE_KEY = process.env.AGENT_PRIVATE_KEY;
235
243
 
236
244
  console.log(\`
237
245
  ╔════════════════════════════════════════╗
238
- ║ DACTYCLAW AGENT DEPLOYMENT
246
+ ║ DACTYCLAW TOKEN LAUNCH
239
247
  ║ Agent: \${AGENT_NAME}
240
248
  ║ DNA: \${AGENT_DNA}
241
249
  ║ Wallet: \${AGENT_WALLET}
242
- ║ Token: \${TOKEN_SYMBOL}
243
250
  ╚════════════════════════════════════════╝
244
251
  \`);
245
252
 
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!');
253
+ console.log('\\n[Launch] Preparing to launch token...');
254
+ console.log('[Launch] Agent configuration loaded');
255
+ console.log('[Launch] Wallet ready');
256
+ console.log('[Launch] Private key loaded');
257
+ console.log('[Launch] ✓ Ready to deploy!');
258
+ console.log('\\n[Launch] Next step: npx dacty-launch');
251
259
  `;
252
- fs.writeFileSync(path.join(agentDir, 'scripts', 'deploy.mjs'), deployScript);
260
+ fs.writeFileSync(path.join(agentDir, 'scripts', 'launch.mjs'), launchScript);
253
261
 
254
262
  // Create README
255
263
  const readmeContent = `# ${agentConfig.name}
@@ -260,16 +268,10 @@ An autonomous agent in the Dactyclaw ecosystem.
260
268
 
261
269
  - **Agent Name:** ${agentConfig.name}
262
270
  - **Agent DNA:** ${agentConfig.dna}
263
- - **Wallet:** ${agentConfig.wallet}
264
- - **Token Symbol:** ${agentConfig.token.symbol}
265
- - **Network:** ${agentConfig.network}
271
+ - **Wallet:** ${wallet.address}
272
+ - **Network:** Base
266
273
  - **Type:** ${agentConfig.agentType}
267
274
 
268
- ## Fee Distribution
269
-
270
- - Agent: 80%
271
- - Dactyclaw: 20%
272
-
273
275
  ## Getting Started
274
276
 
275
277
  \`\`\`bash
@@ -277,12 +279,42 @@ npm install
277
279
  npm run dev
278
280
  \`\`\`
279
281
 
280
- ## Deployment
282
+ ## Environment Variables
283
+
284
+ This project uses a \`.env\` file to store sensitive information including your private key.
285
+
286
+ **⚠️ IMPORTANT: Never commit \`.env\` to version control!**
287
+
288
+ The \`.env\` file is already in \`.gitignore\` for your safety.
289
+
290
+ ## Launch Token
291
+
292
+ To launch your token on Clanker:
281
293
 
282
294
  \`\`\`bash
283
- npm run deploy
295
+ npx dacty-launch
284
296
  \`\`\`
285
297
 
298
+ This will:
299
+ 1. Use your private key to sign transactions
300
+ 2. Deploy token to Base network via Clanker
301
+ 3. Setup fee distribution (80% to your wallet, 20% to Dactyclaw)
302
+
303
+ ## Fee Distribution
304
+
305
+ Once your token is launched:
306
+ - **80%** of trading fees go to your agent wallet
307
+ - **20%** of trading fees go to Dactyclaw
308
+
309
+ Monitor your fees on [Clanker.world](https://clanker.world)
310
+
311
+ ## Security
312
+
313
+ - Keep your \`.env\` file private
314
+ - Never share your private key
315
+ - Never commit \`.env\` to version control
316
+ - Use a hardware wallet for production
317
+
286
318
  ## License
287
319
 
288
320
  MIT
@@ -293,13 +325,32 @@ MIT
293
325
  const gitignore = `node_modules/
294
326
  .env
295
327
  .env.local
328
+ .env.*.local
296
329
  dist/
297
330
  build/
298
331
  *.log
332
+ npm-debug.log*
333
+ yarn-debug.log*
334
+ yarn-error.log*
299
335
  .DS_Store
336
+ .vscode/
337
+ .idea/
338
+ *.swp
339
+ *.swo
340
+ *~
341
+ .pnpm-store/
342
+ pnpm-lock.yaml
343
+ package-lock.json
300
344
  `;
301
345
  fs.writeFileSync(path.join(agentDir, '.gitignore'), gitignore);
302
346
 
347
+ // Create .gitattributes to ensure .env is never committed
348
+ const gitattributes = `# Ensure .env files are never committed
349
+ .env export-ignore
350
+ .env.* export-ignore
351
+ `;
352
+ fs.writeFileSync(path.join(agentDir, '.gitattributes'), gitattributes);
353
+
303
354
  spinner.succeed('Configuration files created');
304
355
 
305
356
  // Display summary
@@ -307,38 +358,32 @@ build/
307
358
  console.log(chalk.green.bold('✓ Agent created successfully!'));
308
359
  console.log('\n');
309
360
  console.log(chalk.cyan('Agent Details:'));
310
- console.log(chalk.gray('─'.repeat(50)));
361
+ console.log(chalk.gray('─'.repeat(60)));
311
362
  console.log(chalk.white(` Name: ${agentConfig.name}`));
312
363
  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}`));
364
+ console.log(chalk.white(` Wallet Address: ${wallet.address}`));
315
365
  console.log(chalk.white(` Type: ${agentConfig.agentType}`));
316
366
  console.log(chalk.white(` Network: ${agentConfig.network}`));
317
367
  console.log(chalk.white(` Directory: ${agentDir}`));
318
- console.log(chalk.gray('─'.repeat(50)));
368
+ console.log(chalk.gray('─'.repeat(60)));
369
+ console.log('\n');
370
+
371
+ console.log(chalk.cyan('Security Notice:'));
372
+ console.log(chalk.gray('─'.repeat(60)));
373
+ console.log(chalk.yellow(` ⚠️ Your private key is stored in .env file`));
374
+ console.log(chalk.yellow(` ⚠️ NEVER commit .env to version control`));
375
+ console.log(chalk.yellow(` ⚠️ Keep your private key safe and secure`));
376
+ console.log(chalk.gray('─'.repeat(60)));
319
377
  console.log('\n');
320
378
 
321
379
  console.log(chalk.cyan('Next Steps:'));
322
- console.log(chalk.gray('─'.repeat(50)));
323
- console.log(chalk.white(` 1. cd ${agentConfig.github.repository}`));
380
+ console.log(chalk.gray('─'.repeat(60)));
381
+ console.log(chalk.white(` 1. cd ${path.basename(agentDir)}`));
324
382
  console.log(chalk.white(` 2. npm install`));
325
383
  console.log(chalk.white(` 3. npm run dev`));
326
- console.log(chalk.gray('─'.repeat(50)));
384
+ console.log(chalk.white(` 4. npx dacty-launch (to launch token)`));
385
+ console.log(chalk.gray('─'.repeat(60)));
327
386
  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
387
 
343
388
  } catch (error) {
344
389
  spinner.fail('Error creating agent');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dacty-create",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Create and deploy agents in the Dactyclaw ecosystem",
5
5
  "type": "module",
6
6
  "bin": {