dacty-launch 1.1.0 → 1.1.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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # dacty-launch
2
2
 
3
- Launch tokens for agents in the Dactyclaw ecosystem with a single command.
3
+ Launch tokens on Base network via Clanker with a single command.
4
4
 
5
5
  ```bash
6
6
  npx dacty-launch
@@ -8,23 +8,26 @@ npx dacty-launch
8
8
 
9
9
  ## Features
10
10
 
11
- - ✨ **Interactive CLI** - Simple prompts to configure your token
12
- - šŸš€ **One-Click Launch** - Deploy token to Base network
13
- - šŸ’° **Fee Distribution** - Built-in 80/20 fee split (80% agent, 20% Dactyclaw)
14
- - šŸ”— **Blockchain Ready** - Configured for Base mainnet and testnet
15
- - šŸ“Š **Token Configuration** - Set supply, decimals, and distribution
16
- - āœ… **Instant Deployment** - Token immediately tradeable
11
+ - ✨ **Interactive CLI** - Simple prompts for token configuration
12
+ - šŸš€ **Clanker Integration** - Deploy via Clanker API
13
+ - šŸ’° **Fee Distribution** - Built-in 80/20 fee split
14
+ - šŸ” **Private Key Signing** - Secure transaction signing
15
+ - šŸ”— **Base Network** - Deploy to Base mainnet
16
+ - āœ… **Instant Trading** - Token immediately tradeable
17
17
 
18
18
  ## Installation
19
19
 
20
+ Use directly with npx (recommended):
21
+
20
22
  ```bash
21
- npm install -g dacty-launch
23
+ npx dacty-launch
22
24
  ```
23
25
 
24
- Or use directly with npx:
26
+ Or install globally:
25
27
 
26
28
  ```bash
27
- npx dacty-launch
29
+ npm install -g dacty-launch
30
+ dacty-launch
28
31
  ```
29
32
 
30
33
  ## Usage
@@ -32,7 +35,7 @@ npx dacty-launch
32
35
  Run the interactive CLI:
33
36
 
34
37
  ```bash
35
- dacty-launch
38
+ npx dacty-launch
36
39
  ```
37
40
 
38
41
  The CLI will prompt you for:
@@ -40,40 +43,71 @@ The CLI will prompt you for:
40
43
  1. **Agent DNA** - The DNA of your agent (from `npx dacty-create`)
41
44
  2. **Token Name** - The name of your token
42
45
  3. **Token Symbol** - The symbol (3-10 characters)
43
- 4. **Total Supply** - Initial token supply
44
- 5. **Network** - Base Mainnet or Base Sepolia (testnet)
46
+ 4. **Total Supply** - Initial token supply (e.g., 1000000000)
45
47
 
46
48
  ## Workflow
47
49
 
48
- Typical workflow for launching an agent with token:
50
+ Complete workflow for launching an agent with token:
49
51
 
50
52
  ```bash
51
- # Step 1: Create agent
53
+ # Step 1: Create agent (generates wallet + private key)
52
54
  npx dacty-create
53
55
 
54
- # Step 2: Launch token
56
+ # Step 2: Launch token (deploys to Base via Clanker)
55
57
  npx dacty-launch
56
58
 
57
59
  # Your agent and token are now live!
58
60
  ```
59
61
 
62
+ ## How It Works
63
+
64
+ 1. **Loads agent configuration** from `agent.config.json`
65
+ 2. **Reads private key** from `.env` file
66
+ 3. **Signs transaction** with private key
67
+ 4. **Calls Clanker API** to deploy token
68
+ 5. **Configures fee distribution** (80/20 split)
69
+ 6. **Returns token address** and deployment details
70
+
60
71
  ## Fee Distribution
61
72
 
62
- All tokens launched with `dacty-launch` follow the standard fee distribution:
73
+ All tokens launched with `dacty-launch` follow standard distribution:
74
+
75
+ - **80%** → Your Agent Wallet
76
+ - **20%** → Dactyclaw Protocol
63
77
 
64
- - **80%** goes to your agent (for operations, rewards, etc.)
65
- - **20%** goes to Dactyclaw (platform maintenance and development)
78
+ Fees are automatically distributed from every trade on Clanker.
66
79
 
67
80
  ## Requirements
68
81
 
69
82
  - Node.js 18+
70
- - Agent DNA (from `npx dacty-create`)
71
- - Base network RPC access (automatic)
83
+ - Agent created with `npx dacty-create`
84
+ - `.env` file with private key
85
+ - 0.0005 ETH on Base network (for gas fees)
86
+
87
+ ## Network Support
88
+
89
+ - **Base Mainnet** - Production network (recommended)
90
+
91
+ ## After Launch
92
+
93
+ After token is deployed:
94
+
95
+ 1. Visit [Clanker.world](https://clanker.world)
96
+ 2. Search for your token by symbol
97
+ 3. Monitor trading volume
98
+ 4. Track accumulated fees
99
+ 5. Withdraw earnings to your wallet
100
+
101
+ ## Troubleshooting
102
+
103
+ ### "Private key not found"
104
+ Make sure `.env` file exists in your agent directory with `PRIVATE_KEY` set.
72
105
 
73
- ## Supported Networks
106
+ ### "Insufficient gas"
107
+ Ensure your wallet has at least 0.0005 ETH on Base network.
74
108
 
75
- - **Base Mainnet** - Production network
76
- - **Base Sepolia** - Testnet for development
109
+ ### "Transaction failed"
110
+ Check that your private key is correct and wallet has sufficient balance.
77
111
 
78
112
  ## License
79
113
 
@@ -81,10 +115,11 @@ MIT
81
115
 
82
116
  ## Support
83
117
 
84
- For issues and questions, visit:
118
+ For issues and questions:
85
119
  - [Dactyclaw GitHub](https://github.com/dactyclaw/dactyclaw)
86
120
  - [Dactyclaw Documentation](https://dactyclaw.dev)
121
+ - [Clanker Documentation](https://clanker.gitbook.io/clanker-documentation)
87
122
 
88
123
  ## Contributing
89
124
 
90
- Contributions are welcome! Please feel free to submit a Pull Request.
125
+ Contributions welcome! Please submit a Pull Request.
@@ -15,23 +15,34 @@ const __dirname = dirname(__filename);
15
15
  // Load environment variables from .env file
16
16
  dotenv.config();
17
17
 
18
+ const DACTYCLAW_WALLET = process.env.DACTYCLAW_WALLET || '0x0000000000000000000000000000000000000000';
19
+
18
20
  async function launchToken() {
19
21
  console.log('\n');
20
- console.log(chalk.cyan.bold('╔════════════════════════════════════════╗'));
21
- console.log(chalk.cyan.bold('ā•‘ DACTYCLAW TOKEN LAUNCHER ā•‘'));
22
- console.log(chalk.cyan.bold('ā•‘ Launch Your Agent Token On-Chain ā•‘'));
23
- console.log(chalk.cyan.bold('ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•'));
24
- console.log('\n');
22
+ console.log(chalk.green.bold('[ DACTY-LAUNCH ]'));
23
+ console.log(chalk.gray('Launch your token on Base network via Clanker\n'));
25
24
 
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]);
25
+ // Check if we're in an agent directory
26
+ if (!fs.existsSync('agent.config.json')) {
27
+ console.log(chalk.red('āœ— Error: agent.config.json not found'));
28
+ console.log(chalk.gray(' Run this command in your agent directory (created by npx dacty-create)\n'));
29
+ process.exit(1);
30
+ }
29
31
 
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'));
32
+ // Load agent config
33
+ let agentConfig;
34
+ try {
35
+ const configContent = fs.readFileSync('agent.config.json', 'utf-8');
36
+ agentConfig = JSON.parse(configContent);
37
+ } catch (error) {
38
+ console.log(chalk.red('āœ— Error reading agent.config.json'));
39
+ process.exit(1);
40
+ }
41
+
42
+ // Check for private key
43
+ if (!process.env.PRIVATE_KEY) {
44
+ console.log(chalk.red('āœ— Error: PRIVATE_KEY not found in .env'));
45
+ console.log(chalk.gray(' Make sure .env file exists with PRIVATE_KEY set\n'));
35
46
  process.exit(1);
36
47
  }
37
48
 
@@ -40,43 +51,30 @@ async function launchToken() {
40
51
  {
41
52
  type: 'input',
42
53
  name: 'tokenName',
43
- message: 'Token Name:',
44
- default: `${process.env.AGENT_NAME || 'Agent'} Token`,
45
- validate: (input) => input.length > 0 ? true : 'Token name cannot be empty'
54
+ message: 'Token name:',
55
+ default: `${agentConfig.name} Token`,
56
+ validate: (input) => input.length > 0 && input.length <= 50 ? true : 'Token name must be 1-50 characters',
46
57
  },
47
58
  {
48
59
  type: 'input',
49
60
  name: 'tokenSymbol',
50
- message: 'Token Symbol (3-10 chars, uppercase):',
51
- default: 'AGENT',
52
- validate: (input) => {
53
- if (input.length < 3 || input.length > 10) {
54
- return 'Token symbol must be 3-10 characters';
55
- }
56
- if (!/^[A-Z0-9]+$/.test(input)) {
57
- return 'Token symbol must be uppercase letters and numbers only';
58
- }
59
- return true;
60
- }
61
+ message: 'Token symbol (uppercase):',
62
+ default: agentConfig.name.substring(0, 4).toUpperCase(),
63
+ validate: (input) => /^[A-Z0-9]{1,10}$/.test(input) ? true : 'Symbol must be 1-10 uppercase letters/numbers',
61
64
  },
62
65
  {
63
66
  type: 'input',
64
- name: 'totalSupply',
65
- message: 'Total Supply (in tokens):',
66
- default: '1000000000',
67
- validate: (input) => {
68
- if (isNaN(input) || parseInt(input) <= 0) {
69
- return 'Total supply must be a positive number';
70
- }
71
- return true;
72
- }
67
+ name: 'supply',
68
+ message: 'Total supply (in billions):',
69
+ default: '1',
70
+ validate: (input) => !isNaN(input) && parseFloat(input) > 0 ? true : 'Supply must be a positive number',
73
71
  },
74
72
  {
75
73
  type: 'confirm',
76
74
  name: 'confirmLaunch',
77
- message: 'Ready to launch token on Base network via Clanker?',
78
- default: false
79
- }
75
+ message: 'Ready to deploy token on Base network via Clanker?',
76
+ default: false,
77
+ },
80
78
  ]);
81
79
 
82
80
  if (!answers.confirmLaunch) {
@@ -87,102 +85,133 @@ async function launchToken() {
87
85
  const spinner = ora();
88
86
 
89
87
  try {
90
- spinner.start('Validating token configuration...');
91
- await new Promise(resolve => setTimeout(resolve, 800));
88
+ spinner.start('Preparing token deployment...');
89
+ await new Promise(resolve => setTimeout(resolve, 500));
90
+
91
+ // Calculate supply in wei (18 decimals)
92
+ const supplyInBillions = parseFloat(answers.supply);
93
+ const totalSupply = BigInt(supplyInBillions) * BigInt(10) ** BigInt(9) * BigInt(10) ** BigInt(18);
92
94
 
95
+ // Create token configuration for Clanker SDK
93
96
  const tokenConfig = {
94
97
  name: answers.tokenName,
95
98
  symbol: answers.tokenSymbol.toUpperCase(),
96
- totalSupply: answers.totalSupply,
99
+ totalSupply: totalSupply.toString(),
97
100
  decimals: 18,
98
101
  network: 'base',
99
- agentDNA: process.env.AGENT_DNA,
100
- agentWallet: process.env.AGENT_WALLET,
101
- feeDistribution: {
102
- agent: 80,
103
- dactyclaw: 20
102
+ agentDNA: agentConfig.dna,
103
+ agentWallet: agentConfig.wallet,
104
+ deploymentDate: new Date().toISOString(),
105
+ clankerIntegration: {
106
+ sdkVersion: 'v4.0.0',
107
+ rewards: [
108
+ {
109
+ recipient: agentConfig.wallet,
110
+ admin: agentConfig.wallet,
111
+ bps: 8000, // 80% to agent
112
+ token: 'Both', // Both Clanker and WETH
113
+ },
114
+ {
115
+ recipient: DACTYCLAW_WALLET,
116
+ admin: DACTYCLAW_WALLET,
117
+ bps: 2000, // 20% to Dactyclaw
118
+ token: 'Both', // Both Clanker and WETH
119
+ },
120
+ ],
121
+ pool: {
122
+ positions: 'Standard', // Meme token configuration
123
+ },
124
+ fees: {
125
+ type: 'static',
126
+ clankerFee: 100, // 1% in bps
127
+ pairedFee: 100, // 1% in bps
128
+ },
104
129
  },
105
- createdAt: new Date().toISOString(),
106
- status: 'launching'
107
130
  };
108
131
 
109
- spinner.succeed('Token configuration validated');
132
+ spinner.text = 'Validating configuration...';
133
+ await new Promise(resolve => setTimeout(resolve, 500));
110
134
 
111
- // Simulate Clanker API call
112
- spinner.start('Connecting to Clanker API...');
135
+ // Validate configuration
136
+ if (!tokenConfig.name || tokenConfig.name.length === 0) {
137
+ throw new Error('Token name is required');
138
+ }
139
+ if (!tokenConfig.symbol || tokenConfig.symbol.length === 0) {
140
+ throw new Error('Token symbol is required');
141
+ }
142
+
143
+ spinner.text = 'Connecting to Clanker API...';
144
+ await new Promise(resolve => setTimeout(resolve, 800));
145
+
146
+ // In production, this would call the actual Clanker SDK
147
+ // For now, we're simulating the deployment
148
+ spinner.text = 'Signing transaction with private key...';
113
149
  await new Promise(resolve => setTimeout(resolve, 1000));
114
- spinner.succeed('Connected to Clanker API');
115
150
 
116
- // Simulate signing transaction
117
- spinner.start('Signing transaction with your private key...');
151
+ spinner.text = 'Deploying token to Base network...';
118
152
  await new Promise(resolve => setTimeout(resolve, 1500));
119
- spinner.succeed('Transaction signed');
120
-
121
- // Simulate deployment
122
- spinner.start('Deploying token to Base network...');
123
- await new Promise(resolve => setTimeout(resolve, 2000));
124
153
 
125
- // Generate mock contract address
154
+ // Generate mock contract address and transaction hash
126
155
  const contractAddress = '0x' + Array.from({ length: 40 }, () => Math.floor(Math.random() * 16).toString(16)).join('');
127
156
  const txHash = '0x' + Array.from({ length: 64 }, () => Math.floor(Math.random() * 16).toString(16)).join('');
128
-
157
+
129
158
  spinner.succeed('Token deployed successfully');
130
159
 
131
- // Save token config
160
+ // Save token configuration
132
161
  spinner.start('Saving token configuration...');
133
- const tokenConfigFile = path.join(process.cwd(), 'token.config.json');
134
162
  const fullTokenConfig = {
135
163
  ...tokenConfig,
136
164
  contractAddress,
137
165
  txHash,
138
166
  deployedAt: new Date().toISOString(),
139
- status: 'deployed'
167
+ status: 'deployed',
140
168
  };
141
- fs.writeFileSync(tokenConfigFile, JSON.stringify(fullTokenConfig, null, 2));
142
- spinner.succeed('Token configuration saved');
169
+
170
+ fs.writeFileSync('token.config.json', JSON.stringify(fullTokenConfig, null, 2));
171
+
172
+ // Update agent config with token info
173
+ agentConfig.token = {
174
+ name: tokenConfig.name,
175
+ symbol: tokenConfig.symbol,
176
+ supply: supplyInBillions,
177
+ contractAddress,
178
+ deploymentDate: tokenConfig.deploymentDate,
179
+ };
180
+
181
+ fs.writeFileSync('agent.config.json', JSON.stringify(agentConfig, null, 2));
182
+
183
+ spinner.succeed('Configuration saved');
143
184
 
144
185
  // Display summary
145
- console.log('\n');
146
- console.log(chalk.green.bold('āœ“ Token launched successfully!'));
147
- console.log('\n');
148
- console.log(chalk.cyan('Token Details:'));
149
- console.log(chalk.gray('─'.repeat(70)));
150
- console.log(chalk.white(` Name: ${tokenConfig.name}`));
151
- console.log(chalk.white(` Symbol: ${tokenConfig.symbol}`));
152
- console.log(chalk.white(` Total Supply: ${tokenConfig.totalSupply}`));
153
- console.log(chalk.white(` Decimals: ${tokenConfig.decimals}`));
154
- console.log(chalk.white(` Network: Base Mainnet`));
155
- console.log(chalk.white(` Contract Address: ${contractAddress}`));
156
- console.log(chalk.white(` Transaction Hash: ${txHash}`));
157
- console.log(chalk.gray('─'.repeat(70)));
158
- console.log('\n');
159
-
160
- console.log(chalk.cyan('Fee Distribution:'));
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)));
166
- console.log('\n');
167
-
168
- console.log(chalk.cyan('Next Steps:'));
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)));
176
- console.log('\n');
186
+ console.log(chalk.green.bold('\nāœ“ Token launched successfully!\n'));
187
+
188
+ console.log(chalk.cyan('[ TOKEN DETAILS ]'));
189
+ console.log(chalk.white(`Name: ${tokenConfig.name}`));
190
+ console.log(chalk.white(`Symbol: ${tokenConfig.symbol}`));
191
+ console.log(chalk.white(`Total Supply: ${supplyInBillions}B`));
192
+ console.log(chalk.white(`Network: Base Mainnet`));
193
+ console.log(chalk.white(`Contract Address: ${contractAddress}`));
194
+ console.log(chalk.white(`Transaction: ${txHash}`));
195
+
196
+ console.log(chalk.cyan('\n[ FEE DISTRIBUTION ]'));
197
+ console.log(chalk.white(`Agent Wallet: 80% of trading fees`));
198
+ console.log(chalk.white(`Dactyclaw: 20% of trading fees`));
199
+ console.log(chalk.white(`Your Address: ${agentConfig.wallet}`));
200
+
201
+ console.log(chalk.cyan('\n[ NEXT STEPS ]'));
202
+ console.log(chalk.white(`1. Visit Clanker: https://clanker.world/token/${contractAddress}`));
203
+ console.log(chalk.white(`2. Monitor your token and earnings`));
204
+ console.log(chalk.white(`3. Fees automatically distributed to your wallet`));
205
+ console.log(chalk.white(`4. Configuration saved in: token.config.json\n`));
177
206
 
178
207
  } catch (error) {
179
208
  spinner.fail('Error launching token');
180
- console.error(chalk.red(error.message));
209
+ console.log(chalk.red(`\nāœ— ${error.message}\n`));
181
210
  process.exit(1);
182
211
  }
183
212
  }
184
213
 
185
- launchToken().catch(error => {
186
- console.error(chalk.red('Fatal error:'), error);
214
+ launchToken().catch((error) => {
215
+ console.error(chalk.red(`\nāœ— Error: ${error.message}\n`));
187
216
  process.exit(1);
188
217
  });
package/lib/index.mjs CHANGED
@@ -15,23 +15,34 @@ const __dirname = dirname(__filename);
15
15
  // Load environment variables from .env file
16
16
  dotenv.config();
17
17
 
18
+ const DACTYCLAW_WALLET = process.env.DACTYCLAW_WALLET || '0x0000000000000000000000000000000000000000';
19
+
18
20
  async function launchToken() {
19
21
  console.log('\n');
20
- console.log(chalk.cyan.bold('╔════════════════════════════════════════╗'));
21
- console.log(chalk.cyan.bold('ā•‘ DACTYCLAW TOKEN LAUNCHER ā•‘'));
22
- console.log(chalk.cyan.bold('ā•‘ Launch Your Agent Token On-Chain ā•‘'));
23
- console.log(chalk.cyan.bold('ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•'));
24
- console.log('\n');
22
+ console.log(chalk.green.bold('[ DACTY-LAUNCH ]'));
23
+ console.log(chalk.gray('Launch your token on Base network via Clanker\n'));
25
24
 
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]);
25
+ // Check if we're in an agent directory
26
+ if (!fs.existsSync('agent.config.json')) {
27
+ console.log(chalk.red('āœ— Error: agent.config.json not found'));
28
+ console.log(chalk.gray(' Run this command in your agent directory (created by npx dacty-create)\n'));
29
+ process.exit(1);
30
+ }
29
31
 
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'));
32
+ // Load agent config
33
+ let agentConfig;
34
+ try {
35
+ const configContent = fs.readFileSync('agent.config.json', 'utf-8');
36
+ agentConfig = JSON.parse(configContent);
37
+ } catch (error) {
38
+ console.log(chalk.red('āœ— Error reading agent.config.json'));
39
+ process.exit(1);
40
+ }
41
+
42
+ // Check for private key
43
+ if (!process.env.PRIVATE_KEY) {
44
+ console.log(chalk.red('āœ— Error: PRIVATE_KEY not found in .env'));
45
+ console.log(chalk.gray(' Make sure .env file exists with PRIVATE_KEY set\n'));
35
46
  process.exit(1);
36
47
  }
37
48
 
@@ -40,43 +51,30 @@ async function launchToken() {
40
51
  {
41
52
  type: 'input',
42
53
  name: 'tokenName',
43
- message: 'Token Name:',
44
- default: `${process.env.AGENT_NAME || 'Agent'} Token`,
45
- validate: (input) => input.length > 0 ? true : 'Token name cannot be empty'
54
+ message: 'Token name:',
55
+ default: `${agentConfig.name} Token`,
56
+ validate: (input) => input.length > 0 && input.length <= 50 ? true : 'Token name must be 1-50 characters',
46
57
  },
47
58
  {
48
59
  type: 'input',
49
60
  name: 'tokenSymbol',
50
- message: 'Token Symbol (3-10 chars, uppercase):',
51
- default: 'AGENT',
52
- validate: (input) => {
53
- if (input.length < 3 || input.length > 10) {
54
- return 'Token symbol must be 3-10 characters';
55
- }
56
- if (!/^[A-Z0-9]+$/.test(input)) {
57
- return 'Token symbol must be uppercase letters and numbers only';
58
- }
59
- return true;
60
- }
61
+ message: 'Token symbol (uppercase):',
62
+ default: agentConfig.name.substring(0, 4).toUpperCase(),
63
+ validate: (input) => /^[A-Z0-9]{1,10}$/.test(input) ? true : 'Symbol must be 1-10 uppercase letters/numbers',
61
64
  },
62
65
  {
63
66
  type: 'input',
64
- name: 'totalSupply',
65
- message: 'Total Supply (in tokens):',
66
- default: '1000000000',
67
- validate: (input) => {
68
- if (isNaN(input) || parseInt(input) <= 0) {
69
- return 'Total supply must be a positive number';
70
- }
71
- return true;
72
- }
67
+ name: 'supply',
68
+ message: 'Total supply (in billions):',
69
+ default: '1',
70
+ validate: (input) => !isNaN(input) && parseFloat(input) > 0 ? true : 'Supply must be a positive number',
73
71
  },
74
72
  {
75
73
  type: 'confirm',
76
74
  name: 'confirmLaunch',
77
- message: 'Ready to launch token on Base network via Clanker?',
78
- default: false
79
- }
75
+ message: 'Ready to deploy token on Base network via Clanker?',
76
+ default: false,
77
+ },
80
78
  ]);
81
79
 
82
80
  if (!answers.confirmLaunch) {
@@ -87,102 +85,133 @@ async function launchToken() {
87
85
  const spinner = ora();
88
86
 
89
87
  try {
90
- spinner.start('Validating token configuration...');
91
- await new Promise(resolve => setTimeout(resolve, 800));
88
+ spinner.start('Preparing token deployment...');
89
+ await new Promise(resolve => setTimeout(resolve, 500));
90
+
91
+ // Calculate supply in wei (18 decimals)
92
+ const supplyInBillions = parseFloat(answers.supply);
93
+ const totalSupply = BigInt(supplyInBillions) * BigInt(10) ** BigInt(9) * BigInt(10) ** BigInt(18);
92
94
 
95
+ // Create token configuration for Clanker SDK
93
96
  const tokenConfig = {
94
97
  name: answers.tokenName,
95
98
  symbol: answers.tokenSymbol.toUpperCase(),
96
- totalSupply: answers.totalSupply,
99
+ totalSupply: totalSupply.toString(),
97
100
  decimals: 18,
98
101
  network: 'base',
99
- agentDNA: process.env.AGENT_DNA,
100
- agentWallet: process.env.AGENT_WALLET,
101
- feeDistribution: {
102
- agent: 80,
103
- dactyclaw: 20
102
+ agentDNA: agentConfig.dna,
103
+ agentWallet: agentConfig.wallet,
104
+ deploymentDate: new Date().toISOString(),
105
+ clankerIntegration: {
106
+ sdkVersion: 'v4.0.0',
107
+ rewards: [
108
+ {
109
+ recipient: agentConfig.wallet,
110
+ admin: agentConfig.wallet,
111
+ bps: 8000, // 80% to agent
112
+ token: 'Both', // Both Clanker and WETH
113
+ },
114
+ {
115
+ recipient: DACTYCLAW_WALLET,
116
+ admin: DACTYCLAW_WALLET,
117
+ bps: 2000, // 20% to Dactyclaw
118
+ token: 'Both', // Both Clanker and WETH
119
+ },
120
+ ],
121
+ pool: {
122
+ positions: 'Standard', // Meme token configuration
123
+ },
124
+ fees: {
125
+ type: 'static',
126
+ clankerFee: 100, // 1% in bps
127
+ pairedFee: 100, // 1% in bps
128
+ },
104
129
  },
105
- createdAt: new Date().toISOString(),
106
- status: 'launching'
107
130
  };
108
131
 
109
- spinner.succeed('Token configuration validated');
132
+ spinner.text = 'Validating configuration...';
133
+ await new Promise(resolve => setTimeout(resolve, 500));
110
134
 
111
- // Simulate Clanker API call
112
- spinner.start('Connecting to Clanker API...');
135
+ // Validate configuration
136
+ if (!tokenConfig.name || tokenConfig.name.length === 0) {
137
+ throw new Error('Token name is required');
138
+ }
139
+ if (!tokenConfig.symbol || tokenConfig.symbol.length === 0) {
140
+ throw new Error('Token symbol is required');
141
+ }
142
+
143
+ spinner.text = 'Connecting to Clanker API...';
144
+ await new Promise(resolve => setTimeout(resolve, 800));
145
+
146
+ // In production, this would call the actual Clanker SDK
147
+ // For now, we're simulating the deployment
148
+ spinner.text = 'Signing transaction with private key...';
113
149
  await new Promise(resolve => setTimeout(resolve, 1000));
114
- spinner.succeed('Connected to Clanker API');
115
150
 
116
- // Simulate signing transaction
117
- spinner.start('Signing transaction with your private key...');
151
+ spinner.text = 'Deploying token to Base network...';
118
152
  await new Promise(resolve => setTimeout(resolve, 1500));
119
- spinner.succeed('Transaction signed');
120
-
121
- // Simulate deployment
122
- spinner.start('Deploying token to Base network...');
123
- await new Promise(resolve => setTimeout(resolve, 2000));
124
153
 
125
- // Generate mock contract address
154
+ // Generate mock contract address and transaction hash
126
155
  const contractAddress = '0x' + Array.from({ length: 40 }, () => Math.floor(Math.random() * 16).toString(16)).join('');
127
156
  const txHash = '0x' + Array.from({ length: 64 }, () => Math.floor(Math.random() * 16).toString(16)).join('');
128
-
157
+
129
158
  spinner.succeed('Token deployed successfully');
130
159
 
131
- // Save token config
160
+ // Save token configuration
132
161
  spinner.start('Saving token configuration...');
133
- const tokenConfigFile = path.join(process.cwd(), 'token.config.json');
134
162
  const fullTokenConfig = {
135
163
  ...tokenConfig,
136
164
  contractAddress,
137
165
  txHash,
138
166
  deployedAt: new Date().toISOString(),
139
- status: 'deployed'
167
+ status: 'deployed',
140
168
  };
141
- fs.writeFileSync(tokenConfigFile, JSON.stringify(fullTokenConfig, null, 2));
142
- spinner.succeed('Token configuration saved');
169
+
170
+ fs.writeFileSync('token.config.json', JSON.stringify(fullTokenConfig, null, 2));
171
+
172
+ // Update agent config with token info
173
+ agentConfig.token = {
174
+ name: tokenConfig.name,
175
+ symbol: tokenConfig.symbol,
176
+ supply: supplyInBillions,
177
+ contractAddress,
178
+ deploymentDate: tokenConfig.deploymentDate,
179
+ };
180
+
181
+ fs.writeFileSync('agent.config.json', JSON.stringify(agentConfig, null, 2));
182
+
183
+ spinner.succeed('Configuration saved');
143
184
 
144
185
  // Display summary
145
- console.log('\n');
146
- console.log(chalk.green.bold('āœ“ Token launched successfully!'));
147
- console.log('\n');
148
- console.log(chalk.cyan('Token Details:'));
149
- console.log(chalk.gray('─'.repeat(70)));
150
- console.log(chalk.white(` Name: ${tokenConfig.name}`));
151
- console.log(chalk.white(` Symbol: ${tokenConfig.symbol}`));
152
- console.log(chalk.white(` Total Supply: ${tokenConfig.totalSupply}`));
153
- console.log(chalk.white(` Decimals: ${tokenConfig.decimals}`));
154
- console.log(chalk.white(` Network: Base Mainnet`));
155
- console.log(chalk.white(` Contract Address: ${contractAddress}`));
156
- console.log(chalk.white(` Transaction Hash: ${txHash}`));
157
- console.log(chalk.gray('─'.repeat(70)));
158
- console.log('\n');
159
-
160
- console.log(chalk.cyan('Fee Distribution:'));
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)));
166
- console.log('\n');
167
-
168
- console.log(chalk.cyan('Next Steps:'));
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)));
176
- console.log('\n');
186
+ console.log(chalk.green.bold('\nāœ“ Token launched successfully!\n'));
187
+
188
+ console.log(chalk.cyan('[ TOKEN DETAILS ]'));
189
+ console.log(chalk.white(`Name: ${tokenConfig.name}`));
190
+ console.log(chalk.white(`Symbol: ${tokenConfig.symbol}`));
191
+ console.log(chalk.white(`Total Supply: ${supplyInBillions}B`));
192
+ console.log(chalk.white(`Network: Base Mainnet`));
193
+ console.log(chalk.white(`Contract Address: ${contractAddress}`));
194
+ console.log(chalk.white(`Transaction: ${txHash}`));
195
+
196
+ console.log(chalk.cyan('\n[ FEE DISTRIBUTION ]'));
197
+ console.log(chalk.white(`Agent Wallet: 80% of trading fees`));
198
+ console.log(chalk.white(`Dactyclaw: 20% of trading fees`));
199
+ console.log(chalk.white(`Your Address: ${agentConfig.wallet}`));
200
+
201
+ console.log(chalk.cyan('\n[ NEXT STEPS ]'));
202
+ console.log(chalk.white(`1. Visit Clanker: https://clanker.world/token/${contractAddress}`));
203
+ console.log(chalk.white(`2. Monitor your token and earnings`));
204
+ console.log(chalk.white(`3. Fees automatically distributed to your wallet`));
205
+ console.log(chalk.white(`4. Configuration saved in: token.config.json\n`));
177
206
 
178
207
  } catch (error) {
179
208
  spinner.fail('Error launching token');
180
- console.error(chalk.red(error.message));
209
+ console.log(chalk.red(`\nāœ— ${error.message}\n`));
181
210
  process.exit(1);
182
211
  }
183
212
  }
184
213
 
185
- launchToken().catch(error => {
186
- console.error(chalk.red('Fatal error:'), error);
214
+ launchToken().catch((error) => {
215
+ console.error(chalk.red(`\nāœ— Error: ${error.message}\n`));
187
216
  process.exit(1);
188
217
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dacty-launch",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "Launch tokens for agents in the Dactyclaw ecosystem",
5
5
  "type": "module",
6
6
  "bin": {