dacty-create 1.0.1 → 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,23 +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('');
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
+ };
23
29
  }
24
30
 
25
31
  async function createAgent() {
@@ -59,14 +65,8 @@ async function createAgent() {
59
65
  {
60
66
  type: 'input',
61
67
  name: 'githubUsername',
62
- message: 'GitHub Username (for repo creation):',
63
- validate: (input) => input.length > 0 ? true : 'GitHub username cannot be empty'
64
- },
65
- {
66
- type: 'confirm',
67
- name: 'createRepo',
68
- message: 'Create GitHub repository for this agent?',
69
- default: true
68
+ message: 'GitHub Username (optional):',
69
+ default: ''
70
70
  }
71
71
  ]);
72
72
 
@@ -75,7 +75,7 @@ async function createAgent() {
75
75
  try {
76
76
  // Generate agent data
77
77
  const agentDNA = generateDNA();
78
- const agentWallet = generateWallet();
78
+ const wallet = generateWallet();
79
79
  const timestamp = new Date().toISOString();
80
80
 
81
81
  spinner.start('Generating agent configuration...');
@@ -86,22 +86,18 @@ async function createAgent() {
86
86
  description: answers.description,
87
87
  type: answers.agentType,
88
88
  dna: agentDNA,
89
- wallet: agentWallet,
89
+ wallet: wallet.address,
90
90
  createdAt: timestamp,
91
- github: {
92
- username: answers.githubUsername,
93
- repository: `${answers.agentName.toLowerCase().replace(/\s+/g, '-')}-agent`,
94
- createRepo: answers.createRepo
95
- },
96
91
  network: 'base',
97
- status: 'created'
92
+ status: 'created',
93
+ version: '1.0.0'
98
94
  };
99
95
 
100
96
  spinner.succeed('Agent configuration generated');
101
97
 
102
98
  // Create agent directory
103
99
  spinner.start('Creating agent directory...');
104
- const agentDir = path.join(process.cwd(), agentConfig.github.repository);
100
+ const agentDir = path.join(process.cwd(), answers.agentName.toLowerCase().replace(/\s+/g, '-') + '-agent');
105
101
 
106
102
  if (!fs.existsSync(agentDir)) {
107
103
  fs.mkdirSync(agentDir, { recursive: true });
@@ -109,25 +105,47 @@ async function createAgent() {
109
105
 
110
106
  spinner.succeed(`Agent directory created at ${agentDir}`);
111
107
 
112
- // Create config file
108
+ // Create config file (safe - no private key)
113
109
  spinner.start('Writing configuration files...');
114
110
 
115
111
  const configPath = path.join(agentDir, 'agent.config.json');
116
112
  fs.writeFileSync(configPath, JSON.stringify(agentConfig, null, 2));
117
113
 
118
- // Create .env file
119
- const envContent = `AGENT_NAME=${agentConfig.name}
120
- AGENT_DNA=${agentConfig.dna}
121
- AGENT_WALLET=${agentConfig.wallet}
122
- NETWORK=base
123
- GITHUB_USERNAME=${agentConfig.github.username}
124
- 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=""
125
127
  `;
126
128
  fs.writeFileSync(path.join(agentDir, '.env'), envContent);
127
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
+
128
146
  // Create package.json for agent
129
147
  const agentPackageJson = {
130
- name: agentConfig.github.repository,
148
+ name: agentConfig.name.toLowerCase().replace(/\s+/g, '-') + '-agent',
131
149
  version: '1.0.0',
132
150
  description: agentConfig.description,
133
151
  type: 'module',
@@ -135,15 +153,16 @@ GITHUB_REPO=${agentConfig.github.repository}
135
153
  scripts: {
136
154
  start: 'node src/index.mjs',
137
155
  dev: 'node --watch src/index.mjs',
138
- deploy: 'node scripts/deploy.mjs'
156
+ launch: 'node scripts/launch.mjs'
139
157
  },
140
- keywords: ['agent', 'dactyclaw', 'blockchain'],
141
- author: agentConfig.github.username,
158
+ keywords: ['agent', 'dactyclaw', 'blockchain', 'base'],
159
+ author: answers.githubUsername || 'Dactyclaw Agent',
142
160
  license: 'MIT',
143
161
  dependencies: {
144
162
  'ethers': '^6.10.0',
145
163
  'dotenv': '^16.3.1',
146
- 'axios': '^1.6.5'
164
+ 'axios': '^1.6.5',
165
+ 'chalk': '^5.3.0'
147
166
  }
148
167
  };
149
168
  fs.writeFileSync(path.join(agentDir, 'package.json'), JSON.stringify(agentPackageJson, null, 2));
@@ -156,19 +175,21 @@ import { ethers } from 'ethers';
156
175
 
157
176
  dotenv.config();
158
177
 
159
- const AGENT_NAME = process.env.AGENT_NAME || '${agentConfig.name}';
160
- 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 || '';
161
181
  const NETWORK = process.env.NETWORK || 'base';
162
182
 
163
183
  console.log(\`
164
184
  ╔════════════════════════════════════════╗
165
185
  ║ DACTYCLAW AGENT - \${AGENT_NAME}
166
- ║ DNA: \${AGENT_DNA}
186
+ ║ DNA: \${AGENT_DNA.substring(0, 16)}...
187
+ ║ Wallet: \${AGENT_WALLET.substring(0, 10)}...
167
188
  ║ Network: \${NETWORK}
168
189
  ╚════════════════════════════════════════╝
169
190
  \`);
170
191
 
171
- // Initialize RPC provider
192
+ // Initialize RPC provider for Base network
172
193
  const rpcUrl = 'https://mainnet.base.org';
173
194
  const provider = new ethers.JsonRpcProvider(rpcUrl);
174
195
 
@@ -184,6 +205,10 @@ async function main() {
184
205
  const network = await provider.getNetwork();
185
206
  console.log(\`[Agent] Network: \${network.name} (chainId: \${network.chainId})\`);
186
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
+
187
212
  // Agent is running
188
213
  console.log('[Agent] Agent is running and monitoring the network...');
189
214
  console.log('[Agent] Press Ctrl+C to stop');
@@ -192,7 +217,7 @@ async function main() {
192
217
  setInterval(async () => {
193
218
  const latestBlock = await provider.getBlockNumber();
194
219
  console.log(\`[Agent] Latest block: \${latestBlock}\`);
195
- }, 10000); // Check every 10 seconds
220
+ }, 30000); // Check every 30 seconds
196
221
 
197
222
  } catch (error) {
198
223
  console.error('[Agent] Error:', error);
@@ -204,33 +229,35 @@ main();
204
229
  `;
205
230
  fs.writeFileSync(path.join(agentDir, 'src', 'index.mjs'), agentCode);
206
231
 
207
- // Create scripts directory with deploy script
232
+ // Create scripts directory with launch script
208
233
  fs.mkdirSync(path.join(agentDir, 'scripts'), { recursive: true });
209
234
 
210
- const deployScript = `import dotenv from 'dotenv';
235
+ const launchScript = `import dotenv from 'dotenv';
211
236
 
212
237
  dotenv.config();
213
238
 
214
239
  const AGENT_NAME = process.env.AGENT_NAME;
215
240
  const AGENT_DNA = process.env.AGENT_DNA;
216
241
  const AGENT_WALLET = process.env.AGENT_WALLET;
242
+ const AGENT_PRIVATE_KEY = process.env.AGENT_PRIVATE_KEY;
217
243
 
218
244
  console.log(\`
219
245
  ╔════════════════════════════════════════╗
220
- ║ DACTYCLAW AGENT DEPLOYMENT
246
+ ║ DACTYCLAW TOKEN LAUNCH
221
247
  ║ Agent: \${AGENT_NAME}
222
248
  ║ DNA: \${AGENT_DNA}
223
249
  ║ Wallet: \${AGENT_WALLET}
224
250
  ╚════════════════════════════════════════╝
225
251
  \`);
226
252
 
227
- console.log('\\n[Deploy] Preparing agent for deployment...');
228
- console.log('[Deploy] Agent configuration validated');
229
- console.log('[Deploy] Ready to deploy to Base network');
230
- console.log('[Deploy] ✓ Deployment ready!');
231
- console.log('[Deploy] Next step: npx dacty-launch');
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');
232
259
  `;
233
- fs.writeFileSync(path.join(agentDir, 'scripts', 'deploy.mjs'), deployScript);
260
+ fs.writeFileSync(path.join(agentDir, 'scripts', 'launch.mjs'), launchScript);
234
261
 
235
262
  // Create README
236
263
  const readmeContent = `# ${agentConfig.name}
@@ -241,8 +268,8 @@ An autonomous agent in the Dactyclaw ecosystem.
241
268
 
242
269
  - **Agent Name:** ${agentConfig.name}
243
270
  - **Agent DNA:** ${agentConfig.dna}
244
- - **Wallet:** ${agentConfig.wallet}
245
- - **Network:** ${agentConfig.network}
271
+ - **Wallet:** ${wallet.address}
272
+ - **Network:** Base
246
273
  - **Type:** ${agentConfig.agentType}
247
274
 
248
275
  ## Getting Started
@@ -252,14 +279,42 @@ npm install
252
279
  npm run dev
253
280
  \`\`\`
254
281
 
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
+
255
290
  ## Launch Token
256
291
 
257
- To launch your token on-chain:
292
+ To launch your token on Clanker:
258
293
 
259
294
  \`\`\`bash
260
295
  npx dacty-launch
261
296
  \`\`\`
262
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
+
263
318
  ## License
264
319
 
265
320
  MIT
@@ -270,13 +325,32 @@ MIT
270
325
  const gitignore = `node_modules/
271
326
  .env
272
327
  .env.local
328
+ .env.*.local
273
329
  dist/
274
330
  build/
275
331
  *.log
332
+ npm-debug.log*
333
+ yarn-debug.log*
334
+ yarn-error.log*
276
335
  .DS_Store
336
+ .vscode/
337
+ .idea/
338
+ *.swp
339
+ *.swo
340
+ *~
341
+ .pnpm-store/
342
+ pnpm-lock.yaml
343
+ package-lock.json
277
344
  `;
278
345
  fs.writeFileSync(path.join(agentDir, '.gitignore'), gitignore);
279
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
+
280
354
  spinner.succeed('Configuration files created');
281
355
 
282
356
  // Display summary
@@ -284,32 +358,33 @@ build/
284
358
  console.log(chalk.green.bold('✓ Agent created successfully!'));
285
359
  console.log('\n');
286
360
  console.log(chalk.cyan('Agent Details:'));
287
- console.log(chalk.gray('─'.repeat(50)));
361
+ console.log(chalk.gray('─'.repeat(60)));
288
362
  console.log(chalk.white(` Name: ${agentConfig.name}`));
289
363
  console.log(chalk.white(` DNA: ${agentConfig.dna}`));
290
- console.log(chalk.white(` Wallet: ${agentConfig.wallet}`));
364
+ console.log(chalk.white(` Wallet Address: ${wallet.address}`));
291
365
  console.log(chalk.white(` Type: ${agentConfig.agentType}`));
292
366
  console.log(chalk.white(` Network: ${agentConfig.network}`));
293
367
  console.log(chalk.white(` Directory: ${agentDir}`));
294
- 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)));
295
377
  console.log('\n');
296
378
 
297
379
  console.log(chalk.cyan('Next Steps:'));
298
- console.log(chalk.gray('─'.repeat(50)));
299
- 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)}`));
300
382
  console.log(chalk.white(` 2. npm install`));
301
383
  console.log(chalk.white(` 3. npm run dev`));
302
384
  console.log(chalk.white(` 4. npx dacty-launch (to launch token)`));
303
- console.log(chalk.gray('─'.repeat(50)));
385
+ console.log(chalk.gray('─'.repeat(60)));
304
386
  console.log('\n');
305
387
 
306
- if (agentConfig.github.createRepo) {
307
- console.log(chalk.yellow('ℹ GitHub repository creation requires manual setup.'));
308
- console.log(chalk.yellow(' Visit https://github.com/new to create the repository.'));
309
- console.log(chalk.yellow(` Repository name: ${agentConfig.github.repository}`));
310
- console.log('\n');
311
- }
312
-
313
388
  } catch (error) {
314
389
  spinner.fail('Error creating agent');
315
390
  console.error(chalk.red(error.message));
package/lib/index.mjs CHANGED
@@ -3,23 +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('');
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
+ };
23
29
  }
24
30
 
25
31
  async function createAgent() {
@@ -59,14 +65,8 @@ async function createAgent() {
59
65
  {
60
66
  type: 'input',
61
67
  name: 'githubUsername',
62
- message: 'GitHub Username (for repo creation):',
63
- validate: (input) => input.length > 0 ? true : 'GitHub username cannot be empty'
64
- },
65
- {
66
- type: 'confirm',
67
- name: 'createRepo',
68
- message: 'Create GitHub repository for this agent?',
69
- default: true
68
+ message: 'GitHub Username (optional):',
69
+ default: ''
70
70
  }
71
71
  ]);
72
72
 
@@ -75,7 +75,7 @@ async function createAgent() {
75
75
  try {
76
76
  // Generate agent data
77
77
  const agentDNA = generateDNA();
78
- const agentWallet = generateWallet();
78
+ const wallet = generateWallet();
79
79
  const timestamp = new Date().toISOString();
80
80
 
81
81
  spinner.start('Generating agent configuration...');
@@ -86,22 +86,18 @@ async function createAgent() {
86
86
  description: answers.description,
87
87
  type: answers.agentType,
88
88
  dna: agentDNA,
89
- wallet: agentWallet,
89
+ wallet: wallet.address,
90
90
  createdAt: timestamp,
91
- github: {
92
- username: answers.githubUsername,
93
- repository: `${answers.agentName.toLowerCase().replace(/\s+/g, '-')}-agent`,
94
- createRepo: answers.createRepo
95
- },
96
91
  network: 'base',
97
- status: 'created'
92
+ status: 'created',
93
+ version: '1.0.0'
98
94
  };
99
95
 
100
96
  spinner.succeed('Agent configuration generated');
101
97
 
102
98
  // Create agent directory
103
99
  spinner.start('Creating agent directory...');
104
- const agentDir = path.join(process.cwd(), agentConfig.github.repository);
100
+ const agentDir = path.join(process.cwd(), answers.agentName.toLowerCase().replace(/\s+/g, '-') + '-agent');
105
101
 
106
102
  if (!fs.existsSync(agentDir)) {
107
103
  fs.mkdirSync(agentDir, { recursive: true });
@@ -109,25 +105,47 @@ async function createAgent() {
109
105
 
110
106
  spinner.succeed(`Agent directory created at ${agentDir}`);
111
107
 
112
- // Create config file
108
+ // Create config file (safe - no private key)
113
109
  spinner.start('Writing configuration files...');
114
110
 
115
111
  const configPath = path.join(agentDir, 'agent.config.json');
116
112
  fs.writeFileSync(configPath, JSON.stringify(agentConfig, null, 2));
117
113
 
118
- // Create .env file
119
- const envContent = `AGENT_NAME=${agentConfig.name}
120
- AGENT_DNA=${agentConfig.dna}
121
- AGENT_WALLET=${agentConfig.wallet}
122
- NETWORK=base
123
- GITHUB_USERNAME=${agentConfig.github.username}
124
- 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=""
125
127
  `;
126
128
  fs.writeFileSync(path.join(agentDir, '.env'), envContent);
127
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
+
128
146
  // Create package.json for agent
129
147
  const agentPackageJson = {
130
- name: agentConfig.github.repository,
148
+ name: agentConfig.name.toLowerCase().replace(/\s+/g, '-') + '-agent',
131
149
  version: '1.0.0',
132
150
  description: agentConfig.description,
133
151
  type: 'module',
@@ -135,15 +153,16 @@ GITHUB_REPO=${agentConfig.github.repository}
135
153
  scripts: {
136
154
  start: 'node src/index.mjs',
137
155
  dev: 'node --watch src/index.mjs',
138
- deploy: 'node scripts/deploy.mjs'
156
+ launch: 'node scripts/launch.mjs'
139
157
  },
140
- keywords: ['agent', 'dactyclaw', 'blockchain'],
141
- author: agentConfig.github.username,
158
+ keywords: ['agent', 'dactyclaw', 'blockchain', 'base'],
159
+ author: answers.githubUsername || 'Dactyclaw Agent',
142
160
  license: 'MIT',
143
161
  dependencies: {
144
162
  'ethers': '^6.10.0',
145
163
  'dotenv': '^16.3.1',
146
- 'axios': '^1.6.5'
164
+ 'axios': '^1.6.5',
165
+ 'chalk': '^5.3.0'
147
166
  }
148
167
  };
149
168
  fs.writeFileSync(path.join(agentDir, 'package.json'), JSON.stringify(agentPackageJson, null, 2));
@@ -156,19 +175,21 @@ import { ethers } from 'ethers';
156
175
 
157
176
  dotenv.config();
158
177
 
159
- const AGENT_NAME = process.env.AGENT_NAME || '${agentConfig.name}';
160
- 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 || '';
161
181
  const NETWORK = process.env.NETWORK || 'base';
162
182
 
163
183
  console.log(\`
164
184
  ╔════════════════════════════════════════╗
165
185
  ║ DACTYCLAW AGENT - \${AGENT_NAME}
166
- ║ DNA: \${AGENT_DNA}
186
+ ║ DNA: \${AGENT_DNA.substring(0, 16)}...
187
+ ║ Wallet: \${AGENT_WALLET.substring(0, 10)}...
167
188
  ║ Network: \${NETWORK}
168
189
  ╚════════════════════════════════════════╝
169
190
  \`);
170
191
 
171
- // Initialize RPC provider
192
+ // Initialize RPC provider for Base network
172
193
  const rpcUrl = 'https://mainnet.base.org';
173
194
  const provider = new ethers.JsonRpcProvider(rpcUrl);
174
195
 
@@ -184,6 +205,10 @@ async function main() {
184
205
  const network = await provider.getNetwork();
185
206
  console.log(\`[Agent] Network: \${network.name} (chainId: \${network.chainId})\`);
186
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
+
187
212
  // Agent is running
188
213
  console.log('[Agent] Agent is running and monitoring the network...');
189
214
  console.log('[Agent] Press Ctrl+C to stop');
@@ -192,7 +217,7 @@ async function main() {
192
217
  setInterval(async () => {
193
218
  const latestBlock = await provider.getBlockNumber();
194
219
  console.log(\`[Agent] Latest block: \${latestBlock}\`);
195
- }, 10000); // Check every 10 seconds
220
+ }, 30000); // Check every 30 seconds
196
221
 
197
222
  } catch (error) {
198
223
  console.error('[Agent] Error:', error);
@@ -204,33 +229,35 @@ main();
204
229
  `;
205
230
  fs.writeFileSync(path.join(agentDir, 'src', 'index.mjs'), agentCode);
206
231
 
207
- // Create scripts directory with deploy script
232
+ // Create scripts directory with launch script
208
233
  fs.mkdirSync(path.join(agentDir, 'scripts'), { recursive: true });
209
234
 
210
- const deployScript = `import dotenv from 'dotenv';
235
+ const launchScript = `import dotenv from 'dotenv';
211
236
 
212
237
  dotenv.config();
213
238
 
214
239
  const AGENT_NAME = process.env.AGENT_NAME;
215
240
  const AGENT_DNA = process.env.AGENT_DNA;
216
241
  const AGENT_WALLET = process.env.AGENT_WALLET;
242
+ const AGENT_PRIVATE_KEY = process.env.AGENT_PRIVATE_KEY;
217
243
 
218
244
  console.log(\`
219
245
  ╔════════════════════════════════════════╗
220
- ║ DACTYCLAW AGENT DEPLOYMENT
246
+ ║ DACTYCLAW TOKEN LAUNCH
221
247
  ║ Agent: \${AGENT_NAME}
222
248
  ║ DNA: \${AGENT_DNA}
223
249
  ║ Wallet: \${AGENT_WALLET}
224
250
  ╚════════════════════════════════════════╝
225
251
  \`);
226
252
 
227
- console.log('\\n[Deploy] Preparing agent for deployment...');
228
- console.log('[Deploy] Agent configuration validated');
229
- console.log('[Deploy] Ready to deploy to Base network');
230
- console.log('[Deploy] ✓ Deployment ready!');
231
- console.log('[Deploy] Next step: npx dacty-launch');
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');
232
259
  `;
233
- fs.writeFileSync(path.join(agentDir, 'scripts', 'deploy.mjs'), deployScript);
260
+ fs.writeFileSync(path.join(agentDir, 'scripts', 'launch.mjs'), launchScript);
234
261
 
235
262
  // Create README
236
263
  const readmeContent = `# ${agentConfig.name}
@@ -241,8 +268,8 @@ An autonomous agent in the Dactyclaw ecosystem.
241
268
 
242
269
  - **Agent Name:** ${agentConfig.name}
243
270
  - **Agent DNA:** ${agentConfig.dna}
244
- - **Wallet:** ${agentConfig.wallet}
245
- - **Network:** ${agentConfig.network}
271
+ - **Wallet:** ${wallet.address}
272
+ - **Network:** Base
246
273
  - **Type:** ${agentConfig.agentType}
247
274
 
248
275
  ## Getting Started
@@ -252,14 +279,42 @@ npm install
252
279
  npm run dev
253
280
  \`\`\`
254
281
 
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
+
255
290
  ## Launch Token
256
291
 
257
- To launch your token on-chain:
292
+ To launch your token on Clanker:
258
293
 
259
294
  \`\`\`bash
260
295
  npx dacty-launch
261
296
  \`\`\`
262
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
+
263
318
  ## License
264
319
 
265
320
  MIT
@@ -270,13 +325,32 @@ MIT
270
325
  const gitignore = `node_modules/
271
326
  .env
272
327
  .env.local
328
+ .env.*.local
273
329
  dist/
274
330
  build/
275
331
  *.log
332
+ npm-debug.log*
333
+ yarn-debug.log*
334
+ yarn-error.log*
276
335
  .DS_Store
336
+ .vscode/
337
+ .idea/
338
+ *.swp
339
+ *.swo
340
+ *~
341
+ .pnpm-store/
342
+ pnpm-lock.yaml
343
+ package-lock.json
277
344
  `;
278
345
  fs.writeFileSync(path.join(agentDir, '.gitignore'), gitignore);
279
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
+
280
354
  spinner.succeed('Configuration files created');
281
355
 
282
356
  // Display summary
@@ -284,32 +358,33 @@ build/
284
358
  console.log(chalk.green.bold('✓ Agent created successfully!'));
285
359
  console.log('\n');
286
360
  console.log(chalk.cyan('Agent Details:'));
287
- console.log(chalk.gray('─'.repeat(50)));
361
+ console.log(chalk.gray('─'.repeat(60)));
288
362
  console.log(chalk.white(` Name: ${agentConfig.name}`));
289
363
  console.log(chalk.white(` DNA: ${agentConfig.dna}`));
290
- console.log(chalk.white(` Wallet: ${agentConfig.wallet}`));
364
+ console.log(chalk.white(` Wallet Address: ${wallet.address}`));
291
365
  console.log(chalk.white(` Type: ${agentConfig.agentType}`));
292
366
  console.log(chalk.white(` Network: ${agentConfig.network}`));
293
367
  console.log(chalk.white(` Directory: ${agentDir}`));
294
- 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)));
295
377
  console.log('\n');
296
378
 
297
379
  console.log(chalk.cyan('Next Steps:'));
298
- console.log(chalk.gray('─'.repeat(50)));
299
- 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)}`));
300
382
  console.log(chalk.white(` 2. npm install`));
301
383
  console.log(chalk.white(` 3. npm run dev`));
302
384
  console.log(chalk.white(` 4. npx dacty-launch (to launch token)`));
303
- console.log(chalk.gray('─'.repeat(50)));
385
+ console.log(chalk.gray('─'.repeat(60)));
304
386
  console.log('\n');
305
387
 
306
- if (agentConfig.github.createRepo) {
307
- console.log(chalk.yellow('ℹ GitHub repository creation requires manual setup.'));
308
- console.log(chalk.yellow(' Visit https://github.com/new to create the repository.'));
309
- console.log(chalk.yellow(` Repository name: ${agentConfig.github.repository}`));
310
- console.log('\n');
311
- }
312
-
313
388
  } catch (error) {
314
389
  spinner.fail('Error creating agent');
315
390
  console.error(chalk.red(error.message));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dacty-create",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Create and deploy agents in the Dactyclaw ecosystem",
5
5
  "type": "module",
6
6
  "bin": {