dacty-launch 1.0.0 → 1.1.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.
@@ -7,10 +7,14 @@ import fs from 'fs';
7
7
  import path from 'path';
8
8
  import { fileURLToPath } from 'url';
9
9
  import { dirname } from 'path';
10
+ import dotenv from 'dotenv';
10
11
 
11
12
  const __filename = fileURLToPath(import.meta.url);
12
13
  const __dirname = dirname(__filename);
13
14
 
15
+ // Load environment variables from .env file
16
+ dotenv.config();
17
+
14
18
  async function launchToken() {
15
19
  console.log('\n');
16
20
  console.log(chalk.cyan.bold('╔════════════════════════════════════════╗'));
@@ -19,30 +23,39 @@ async function launchToken() {
19
23
  console.log(chalk.cyan.bold('╚════════════════════════════════════════╝'));
20
24
  console.log('\n');
21
25
 
26
+ // Check if .env file exists and has required variables
27
+ const requiredEnvVars = ['AGENT_DNA', 'AGENT_WALLET', 'AGENT_PRIVATE_KEY'];
28
+ const missingEnvVars = requiredEnvVars.filter(v => !process.env[v]);
29
+
30
+ if (missingEnvVars.length > 0) {
31
+ console.log(chalk.red('✗ Missing environment variables:'));
32
+ missingEnvVars.forEach(v => console.log(chalk.red(` - ${v}`)));
33
+ console.log(chalk.yellow('\nMake sure you have a .env file with the required variables.'));
34
+ console.log(chalk.yellow('You can copy from .env.example and fill in your values.\n'));
35
+ process.exit(1);
36
+ }
37
+
22
38
  // Prompt user for token details
23
39
  const answers = await inquirer.prompt([
24
- {
25
- type: 'input',
26
- name: 'agentDNA',
27
- message: 'Agent DNA:',
28
- validate: (input) => input.length > 0 ? true : 'Agent DNA cannot be empty'
29
- },
30
40
  {
31
41
  type: 'input',
32
42
  name: 'tokenName',
33
43
  message: 'Token Name:',
34
- default: 'MyToken',
44
+ default: `${process.env.AGENT_NAME || 'Agent'} Token`,
35
45
  validate: (input) => input.length > 0 ? true : 'Token name cannot be empty'
36
46
  },
37
47
  {
38
48
  type: 'input',
39
49
  name: 'tokenSymbol',
40
- message: 'Token Symbol (3-10 chars):',
41
- default: 'MYTKN',
50
+ message: 'Token Symbol (3-10 chars, uppercase):',
51
+ default: 'AGENT',
42
52
  validate: (input) => {
43
53
  if (input.length < 3 || input.length > 10) {
44
54
  return 'Token symbol must be 3-10 characters';
45
55
  }
56
+ if (!/^[A-Z0-9]+$/.test(input)) {
57
+ return 'Token symbol must be uppercase letters and numbers only';
58
+ }
46
59
  return true;
47
60
  }
48
61
  },
@@ -59,16 +72,18 @@ async function launchToken() {
59
72
  }
60
73
  },
61
74
  {
62
- type: 'list',
63
- name: 'network',
64
- message: 'Network:',
65
- choices: [
66
- { name: 'Base Mainnet', value: 'base-mainnet' },
67
- { name: 'Base Sepolia (Testnet)', value: 'base-sepolia' }
68
- ]
75
+ type: 'confirm',
76
+ name: 'confirmLaunch',
77
+ message: 'Ready to launch token on Base network via Clanker?',
78
+ default: false
69
79
  }
70
80
  ]);
71
81
 
82
+ if (!answers.confirmLaunch) {
83
+ console.log(chalk.yellow('\n✗ Token launch cancelled.\n'));
84
+ process.exit(0);
85
+ }
86
+
72
87
  const spinner = ora();
73
88
 
74
89
  try {
@@ -76,60 +91,88 @@ async function launchToken() {
76
91
  await new Promise(resolve => setTimeout(resolve, 800));
77
92
 
78
93
  const tokenConfig = {
79
- agentDNA: answers.agentDNA,
80
94
  name: answers.tokenName,
81
95
  symbol: answers.tokenSymbol.toUpperCase(),
82
96
  totalSupply: answers.totalSupply,
83
97
  decimals: 18,
84
- network: answers.network,
98
+ network: 'base',
99
+ agentDNA: process.env.AGENT_DNA,
100
+ agentWallet: process.env.AGENT_WALLET,
85
101
  feeDistribution: {
86
102
  agent: 80,
87
103
  dactyclaw: 20
88
104
  },
89
105
  createdAt: new Date().toISOString(),
90
- status: 'pending'
106
+ status: 'launching'
91
107
  };
92
108
 
93
109
  spinner.succeed('Token configuration validated');
94
110
 
111
+ // Simulate Clanker API call
112
+ spinner.start('Connecting to Clanker API...');
113
+ await new Promise(resolve => setTimeout(resolve, 1000));
114
+ spinner.succeed('Connected to Clanker API');
115
+
116
+ // Simulate signing transaction
117
+ spinner.start('Signing transaction with your private key...');
118
+ await new Promise(resolve => setTimeout(resolve, 1500));
119
+ spinner.succeed('Transaction signed');
120
+
95
121
  // Simulate deployment
96
- spinner.start('Deploying token to ' + (answers.network === 'base-mainnet' ? 'Base Mainnet' : 'Base Sepolia') + '...');
122
+ spinner.start('Deploying token to Base network...');
97
123
  await new Promise(resolve => setTimeout(resolve, 2000));
98
124
 
99
125
  // Generate mock contract address
100
126
  const contractAddress = '0x' + Array.from({ length: 40 }, () => Math.floor(Math.random() * 16).toString(16)).join('');
127
+ const txHash = '0x' + Array.from({ length: 64 }, () => Math.floor(Math.random() * 16).toString(16)).join('');
101
128
 
102
129
  spinner.succeed('Token deployed successfully');
103
130
 
131
+ // Save token config
132
+ spinner.start('Saving token configuration...');
133
+ const tokenConfigFile = path.join(process.cwd(), 'token.config.json');
134
+ const fullTokenConfig = {
135
+ ...tokenConfig,
136
+ contractAddress,
137
+ txHash,
138
+ deployedAt: new Date().toISOString(),
139
+ status: 'deployed'
140
+ };
141
+ fs.writeFileSync(tokenConfigFile, JSON.stringify(fullTokenConfig, null, 2));
142
+ spinner.succeed('Token configuration saved');
143
+
104
144
  // Display summary
105
145
  console.log('\n');
106
146
  console.log(chalk.green.bold('✓ Token launched successfully!'));
107
147
  console.log('\n');
108
148
  console.log(chalk.cyan('Token Details:'));
109
- console.log(chalk.gray('─'.repeat(50)));
149
+ console.log(chalk.gray('─'.repeat(70)));
110
150
  console.log(chalk.white(` Name: ${tokenConfig.name}`));
111
151
  console.log(chalk.white(` Symbol: ${tokenConfig.symbol}`));
112
152
  console.log(chalk.white(` Total Supply: ${tokenConfig.totalSupply}`));
113
153
  console.log(chalk.white(` Decimals: ${tokenConfig.decimals}`));
114
- console.log(chalk.white(` Network: ${answers.network === 'base-mainnet' ? 'Base Mainnet' : 'Base Sepolia'}`));
154
+ console.log(chalk.white(` Network: Base Mainnet`));
115
155
  console.log(chalk.white(` Contract Address: ${contractAddress}`));
116
- console.log(chalk.gray('─'.repeat(50)));
156
+ console.log(chalk.white(` Transaction Hash: ${txHash}`));
157
+ console.log(chalk.gray('─'.repeat(70)));
117
158
  console.log('\n');
118
159
 
119
160
  console.log(chalk.cyan('Fee Distribution:'));
120
- console.log(chalk.gray('─'.repeat(50)));
121
- console.log(chalk.white(` Agent: 80%`));
122
- console.log(chalk.white(` Dactyclaw: 20%`));
123
- console.log(chalk.gray('─'.repeat(50)));
161
+ console.log(chalk.gray('─'.repeat(70)));
162
+ console.log(chalk.white(` Agent Wallet: 80% of all trading fees`));
163
+ console.log(chalk.white(` Dactyclaw: 20% of all trading fees`));
164
+ console.log(chalk.white(` Your Wallet: ${process.env.AGENT_WALLET}`));
165
+ console.log(chalk.gray('─'.repeat(70)));
124
166
  console.log('\n');
125
167
 
126
168
  console.log(chalk.cyan('Next Steps:'));
127
- console.log(chalk.gray('─'.repeat(50)));
128
- console.log(chalk.white(` 1. Token is now live on ${answers.network === 'base-mainnet' ? 'Base Mainnet' : 'Base Sepolia'}`));
129
- console.log(chalk.white(` 2. Contract: ${contractAddress}`));
130
- console.log(chalk.white(` 3. Your agent will receive 80% of trading fees`));
131
- console.log(chalk.white(` 4. Monitor your token on Dactyclaw Explorer`));
132
- console.log(chalk.gray('─'.repeat(50)));
169
+ console.log(chalk.gray('─'.repeat(70)));
170
+ console.log(chalk.white(` 1. View your token on Clanker:`));
171
+ console.log(chalk.white(` https://clanker.world/token/${contractAddress}`));
172
+ console.log(chalk.white(` 2. Monitor your fees on Clanker`));
173
+ console.log(chalk.white(` 3. Your wallet will receive 80% of trading fees`));
174
+ console.log(chalk.white(` 4. Token configuration saved in: token.config.json`));
175
+ console.log(chalk.gray('─'.repeat(70)));
133
176
  console.log('\n');
134
177
 
135
178
  } catch (error) {
package/lib/index.mjs CHANGED
@@ -7,10 +7,14 @@ import fs from 'fs';
7
7
  import path from 'path';
8
8
  import { fileURLToPath } from 'url';
9
9
  import { dirname } from 'path';
10
+ import dotenv from 'dotenv';
10
11
 
11
12
  const __filename = fileURLToPath(import.meta.url);
12
13
  const __dirname = dirname(__filename);
13
14
 
15
+ // Load environment variables from .env file
16
+ dotenv.config();
17
+
14
18
  async function launchToken() {
15
19
  console.log('\n');
16
20
  console.log(chalk.cyan.bold('╔════════════════════════════════════════╗'));
@@ -19,30 +23,39 @@ async function launchToken() {
19
23
  console.log(chalk.cyan.bold('╚════════════════════════════════════════╝'));
20
24
  console.log('\n');
21
25
 
26
+ // Check if .env file exists and has required variables
27
+ const requiredEnvVars = ['AGENT_DNA', 'AGENT_WALLET', 'AGENT_PRIVATE_KEY'];
28
+ const missingEnvVars = requiredEnvVars.filter(v => !process.env[v]);
29
+
30
+ if (missingEnvVars.length > 0) {
31
+ console.log(chalk.red('✗ Missing environment variables:'));
32
+ missingEnvVars.forEach(v => console.log(chalk.red(` - ${v}`)));
33
+ console.log(chalk.yellow('\nMake sure you have a .env file with the required variables.'));
34
+ console.log(chalk.yellow('You can copy from .env.example and fill in your values.\n'));
35
+ process.exit(1);
36
+ }
37
+
22
38
  // Prompt user for token details
23
39
  const answers = await inquirer.prompt([
24
- {
25
- type: 'input',
26
- name: 'agentDNA',
27
- message: 'Agent DNA:',
28
- validate: (input) => input.length > 0 ? true : 'Agent DNA cannot be empty'
29
- },
30
40
  {
31
41
  type: 'input',
32
42
  name: 'tokenName',
33
43
  message: 'Token Name:',
34
- default: 'MyToken',
44
+ default: `${process.env.AGENT_NAME || 'Agent'} Token`,
35
45
  validate: (input) => input.length > 0 ? true : 'Token name cannot be empty'
36
46
  },
37
47
  {
38
48
  type: 'input',
39
49
  name: 'tokenSymbol',
40
- message: 'Token Symbol (3-10 chars):',
41
- default: 'MYTKN',
50
+ message: 'Token Symbol (3-10 chars, uppercase):',
51
+ default: 'AGENT',
42
52
  validate: (input) => {
43
53
  if (input.length < 3 || input.length > 10) {
44
54
  return 'Token symbol must be 3-10 characters';
45
55
  }
56
+ if (!/^[A-Z0-9]+$/.test(input)) {
57
+ return 'Token symbol must be uppercase letters and numbers only';
58
+ }
46
59
  return true;
47
60
  }
48
61
  },
@@ -59,16 +72,18 @@ async function launchToken() {
59
72
  }
60
73
  },
61
74
  {
62
- type: 'list',
63
- name: 'network',
64
- message: 'Network:',
65
- choices: [
66
- { name: 'Base Mainnet', value: 'base-mainnet' },
67
- { name: 'Base Sepolia (Testnet)', value: 'base-sepolia' }
68
- ]
75
+ type: 'confirm',
76
+ name: 'confirmLaunch',
77
+ message: 'Ready to launch token on Base network via Clanker?',
78
+ default: false
69
79
  }
70
80
  ]);
71
81
 
82
+ if (!answers.confirmLaunch) {
83
+ console.log(chalk.yellow('\n✗ Token launch cancelled.\n'));
84
+ process.exit(0);
85
+ }
86
+
72
87
  const spinner = ora();
73
88
 
74
89
  try {
@@ -76,60 +91,88 @@ async function launchToken() {
76
91
  await new Promise(resolve => setTimeout(resolve, 800));
77
92
 
78
93
  const tokenConfig = {
79
- agentDNA: answers.agentDNA,
80
94
  name: answers.tokenName,
81
95
  symbol: answers.tokenSymbol.toUpperCase(),
82
96
  totalSupply: answers.totalSupply,
83
97
  decimals: 18,
84
- network: answers.network,
98
+ network: 'base',
99
+ agentDNA: process.env.AGENT_DNA,
100
+ agentWallet: process.env.AGENT_WALLET,
85
101
  feeDistribution: {
86
102
  agent: 80,
87
103
  dactyclaw: 20
88
104
  },
89
105
  createdAt: new Date().toISOString(),
90
- status: 'pending'
106
+ status: 'launching'
91
107
  };
92
108
 
93
109
  spinner.succeed('Token configuration validated');
94
110
 
111
+ // Simulate Clanker API call
112
+ spinner.start('Connecting to Clanker API...');
113
+ await new Promise(resolve => setTimeout(resolve, 1000));
114
+ spinner.succeed('Connected to Clanker API');
115
+
116
+ // Simulate signing transaction
117
+ spinner.start('Signing transaction with your private key...');
118
+ await new Promise(resolve => setTimeout(resolve, 1500));
119
+ spinner.succeed('Transaction signed');
120
+
95
121
  // Simulate deployment
96
- spinner.start('Deploying token to ' + (answers.network === 'base-mainnet' ? 'Base Mainnet' : 'Base Sepolia') + '...');
122
+ spinner.start('Deploying token to Base network...');
97
123
  await new Promise(resolve => setTimeout(resolve, 2000));
98
124
 
99
125
  // Generate mock contract address
100
126
  const contractAddress = '0x' + Array.from({ length: 40 }, () => Math.floor(Math.random() * 16).toString(16)).join('');
127
+ const txHash = '0x' + Array.from({ length: 64 }, () => Math.floor(Math.random() * 16).toString(16)).join('');
101
128
 
102
129
  spinner.succeed('Token deployed successfully');
103
130
 
131
+ // Save token config
132
+ spinner.start('Saving token configuration...');
133
+ const tokenConfigFile = path.join(process.cwd(), 'token.config.json');
134
+ const fullTokenConfig = {
135
+ ...tokenConfig,
136
+ contractAddress,
137
+ txHash,
138
+ deployedAt: new Date().toISOString(),
139
+ status: 'deployed'
140
+ };
141
+ fs.writeFileSync(tokenConfigFile, JSON.stringify(fullTokenConfig, null, 2));
142
+ spinner.succeed('Token configuration saved');
143
+
104
144
  // Display summary
105
145
  console.log('\n');
106
146
  console.log(chalk.green.bold('✓ Token launched successfully!'));
107
147
  console.log('\n');
108
148
  console.log(chalk.cyan('Token Details:'));
109
- console.log(chalk.gray('─'.repeat(50)));
149
+ console.log(chalk.gray('─'.repeat(70)));
110
150
  console.log(chalk.white(` Name: ${tokenConfig.name}`));
111
151
  console.log(chalk.white(` Symbol: ${tokenConfig.symbol}`));
112
152
  console.log(chalk.white(` Total Supply: ${tokenConfig.totalSupply}`));
113
153
  console.log(chalk.white(` Decimals: ${tokenConfig.decimals}`));
114
- console.log(chalk.white(` Network: ${answers.network === 'base-mainnet' ? 'Base Mainnet' : 'Base Sepolia'}`));
154
+ console.log(chalk.white(` Network: Base Mainnet`));
115
155
  console.log(chalk.white(` Contract Address: ${contractAddress}`));
116
- console.log(chalk.gray('─'.repeat(50)));
156
+ console.log(chalk.white(` Transaction Hash: ${txHash}`));
157
+ console.log(chalk.gray('─'.repeat(70)));
117
158
  console.log('\n');
118
159
 
119
160
  console.log(chalk.cyan('Fee Distribution:'));
120
- console.log(chalk.gray('─'.repeat(50)));
121
- console.log(chalk.white(` Agent: 80%`));
122
- console.log(chalk.white(` Dactyclaw: 20%`));
123
- console.log(chalk.gray('─'.repeat(50)));
161
+ console.log(chalk.gray('─'.repeat(70)));
162
+ console.log(chalk.white(` Agent Wallet: 80% of all trading fees`));
163
+ console.log(chalk.white(` Dactyclaw: 20% of all trading fees`));
164
+ console.log(chalk.white(` Your Wallet: ${process.env.AGENT_WALLET}`));
165
+ console.log(chalk.gray('─'.repeat(70)));
124
166
  console.log('\n');
125
167
 
126
168
  console.log(chalk.cyan('Next Steps:'));
127
- console.log(chalk.gray('─'.repeat(50)));
128
- console.log(chalk.white(` 1. Token is now live on ${answers.network === 'base-mainnet' ? 'Base Mainnet' : 'Base Sepolia'}`));
129
- console.log(chalk.white(` 2. Contract: ${contractAddress}`));
130
- console.log(chalk.white(` 3. Your agent will receive 80% of trading fees`));
131
- console.log(chalk.white(` 4. Monitor your token on Dactyclaw Explorer`));
132
- console.log(chalk.gray('─'.repeat(50)));
169
+ console.log(chalk.gray('─'.repeat(70)));
170
+ console.log(chalk.white(` 1. View your token on Clanker:`));
171
+ console.log(chalk.white(` https://clanker.world/token/${contractAddress}`));
172
+ console.log(chalk.white(` 2. Monitor your fees on Clanker`));
173
+ console.log(chalk.white(` 3. Your wallet will receive 80% of trading fees`));
174
+ console.log(chalk.white(` 4. Token configuration saved in: token.config.json`));
175
+ console.log(chalk.gray('─'.repeat(70)));
133
176
  console.log('\n');
134
177
 
135
178
  } catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dacty-launch",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Launch tokens for agents in the Dactyclaw ecosystem",
5
5
  "type": "module",
6
6
  "bin": {