dacty-launch 1.1.3 → 1.1.4

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.
@@ -1,259 +1,218 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import chalk from 'chalk';
4
- import inquirer from 'inquirer';
5
- import ora from 'ora';
6
3
  import fs from 'fs';
7
4
  import path from 'path';
8
5
  import { fileURLToPath } from 'url';
9
- import { dirname } from 'path';
10
- import dotenv from 'dotenv';
11
- import axios from 'axios';
6
+ import readline from 'readline';
7
+ import { Clanker } from 'clanker-sdk/v4';
8
+ import { createWalletClient, createPublicClient, privateKeyToAccount, http } from 'viem';
9
+ import { base } from 'viem/chains';
12
10
 
13
11
  const __filename = fileURLToPath(import.meta.url);
14
- const __dirname = dirname(__filename);
12
+ const __dirname = path.dirname(__filename);
15
13
 
16
- // Load environment variables from .env file
17
- dotenv.config();
18
-
19
- const DACTYCLAW_WALLET = process.env.DACTYCLAW_WALLET || '0x0000000000000000000000000000000000000000';
20
- const CLANKER_RPC = process.env.CLANKER_RPC || 'https://mainnet.base.org';
21
- const CLANKER_API = process.env.CLANKER_API || 'https://api.clanker.world';
14
+ const rl = readline.createInterface({
15
+ input: process.stdin,
16
+ output: process.stdout,
17
+ });
22
18
 
23
- async function launchToken() {
24
- console.log('\n');
25
- console.log(chalk.green.bold('[ DACTY-LAUNCH ]'));
26
- console.log(chalk.gray('Launch your token on Base network via Clanker\n'));
19
+ function question(prompt) {
20
+ return new Promise((resolve) => {
21
+ rl.question(prompt, (answer) => {
22
+ resolve(answer);
23
+ });
24
+ });
25
+ }
27
26
 
28
- // Check if we're in an agent directory
29
- if (!fs.existsSync('agent.config.json')) {
30
- console.log(chalk.red(' Error: agent.config.json not found'));
31
- console.log(chalk.gray(' Run this command in your agent directory (created by npx dacty-create)\n'));
27
+ async function main() {
28
+ console.log('\n╔═══════════════════════════════════════╗');
29
+ console.log('║ DACTYCLAW - Token Launch ║');
30
+ console.log(' Powered by Clanker v4.0.0 ');
31
+ console.log('╚═══════════════════════════════════════╝\n');
32
+
33
+ // Check if agent.config.json exists
34
+ const agentConfigPath = path.join(process.cwd(), 'agent.config.json');
35
+ if (!fs.existsSync(agentConfigPath)) {
36
+ console.error('❌ Error: agent.config.json not found!');
37
+ console.error(' Please run `npx dacty-create` first to create an agent.');
32
38
  process.exit(1);
33
39
  }
34
40
 
35
- // Load agent config
36
- let agentConfig;
37
- try {
38
- const configContent = fs.readFileSync('agent.config.json', 'utf-8');
39
- agentConfig = JSON.parse(configContent);
40
- } catch (error) {
41
- console.log(chalk.red('✗ Error reading agent.config.json'));
41
+ // Load agent configuration
42
+ const agentConfig = JSON.parse(fs.readFileSync(agentConfigPath, 'utf-8'));
43
+ console.log(`✓ Agent loaded: ${agentConfig.name} (DNA: ${agentConfig.dna})`);
44
+ console.log(`✓ Wallet: ${agentConfig.wallet}\n`);
45
+
46
+ // Check if .env exists with private key
47
+ const envPath = path.join(process.cwd(), '.env');
48
+ if (!fs.existsSync(envPath)) {
49
+ console.error('❌ Error: .env file not found!');
50
+ console.error(' Private key should be in .env file.');
42
51
  process.exit(1);
43
52
  }
44
53
 
45
- // Check for private key
46
- if (!process.env.PRIVATE_KEY) {
47
- console.log(chalk.red('✗ Error: PRIVATE_KEY not found in .env'));
48
- console.log(chalk.gray(' Make sure .env file exists with PRIVATE_KEY set\n'));
54
+ const envContent = fs.readFileSync(envPath, 'utf-8');
55
+ const privateKeyMatch = envContent.match(/PRIVATE_KEY=(.+)/);
56
+ if (!privateKeyMatch) {
57
+ console.error(' Error: PRIVATE_KEY not found in .env file!');
49
58
  process.exit(1);
50
59
  }
51
60
 
52
- // Prompt user for token details
53
- const answers = await inquirer.prompt([
54
- {
55
- type: 'input',
56
- name: 'tokenName',
57
- message: 'Token name:',
58
- default: `${agentConfig.name} Token`,
59
- validate: (input) => input.length > 0 && input.length <= 50 ? true : 'Token name must be 1-50 characters',
60
- },
61
- {
62
- type: 'input',
63
- name: 'tokenSymbol',
64
- message: 'Token symbol (uppercase):',
65
- default: agentConfig.name.substring(0, 4).toUpperCase(),
66
- validate: (input) => /^[A-Z0-9]{1,10}$/.test(input) ? true : 'Symbol must be 1-10 uppercase letters/numbers',
67
- },
68
- {
69
- type: 'input',
70
- name: 'supply',
71
- message: 'Total supply (in billions):',
72
- default: '1',
73
- validate: (input) => !isNaN(input) && parseFloat(input) > 0 ? true : 'Supply must be a positive number',
74
- },
75
- {
76
- type: 'input',
77
- name: 'description',
78
- message: 'Token description (optional):',
79
- default: `Autonomous agent token for ${agentConfig.name}`,
80
- },
81
- {
82
- type: 'confirm',
83
- name: 'confirmLaunch',
84
- message: 'Ready to deploy token on Base network via Clanker?',
85
- default: false,
86
- },
87
- ]);
88
-
89
- if (!answers.confirmLaunch) {
90
- console.log(chalk.yellow('\n✗ Token launch cancelled.\n'));
91
- process.exit(0);
92
- }
61
+ const privateKey = privateKeyMatch[1].trim();
62
+ console.log('✓ Private key loaded from .env\n');
93
63
 
94
- const spinner = ora();
64
+ // Get token details from user
65
+ const tokenName = await question('Token Name: ');
66
+ const tokenSymbol = await question('Token Symbol: ');
67
+ const initialSupply = await question('Initial Supply (default: 1000000000): ') || '1000000000';
95
68
 
96
- try {
97
- spinner.start('Preparing token deployment...');
98
- await new Promise(resolve => setTimeout(resolve, 500));
69
+ console.log('\n📋 Configuration:');
70
+ console.log(` Name: ${tokenName}`);
71
+ console.log(` Symbol: ${tokenSymbol}`);
72
+ console.log(` Supply: ${initialSupply}`);
73
+ console.log(` Agent Wallet: ${agentConfig.wallet}`);
74
+ console.log(` Fee Distribution: 80% Agent, 20% Dactyclaw\n`);
99
75
 
100
- // Calculate supply in wei (18 decimals)
101
- const supplyInBillions = parseFloat(answers.supply);
102
- const totalSupply = BigInt(supplyInBillions) * BigInt(10) ** BigInt(9) * BigInt(10) ** BigInt(18);
76
+ // Dactyclaw wallet address (should be configured)
77
+ const DACTYCLAW_WALLET = process.env.DACTYCLAW_WALLET || '0x0000000000000000000000000000000000000000';
103
78
 
104
- // Create token configuration for Clanker SDK
105
- const tokenConfig = {
106
- name: answers.tokenName,
107
- symbol: answers.tokenSymbol.toUpperCase(),
108
- totalSupply: totalSupply.toString(),
109
- decimals: 18,
110
- network: 'base',
111
- agentDNA: agentConfig.dna,
112
- agentWallet: agentConfig.wallet,
113
- deploymentDate: new Date().toISOString(),
114
- description: answers.description,
115
- clankerIntegration: {
116
- sdkVersion: 'v4.0.0',
117
- rewards: [
79
+ try {
80
+ console.log('🔄 Initializing Clanker SDK...');
81
+
82
+ // Setup viem clients
83
+ const account = privateKeyToAccount(`0x${privateKey.replace(/^0x/, '')}`);
84
+ const publicClient = createPublicClient({ chain: base, transport: http() });
85
+ const walletClient = createWalletClient({ account, chain: base, transport: http() });
86
+
87
+ // Initialize Clanker SDK
88
+ const clanker = new Clanker({
89
+ publicClient,
90
+ wallet: walletClient,
91
+ });
92
+
93
+ console.log('✓ Clanker SDK initialized');
94
+ console.log('✓ Connected to Base network');
95
+ console.log('✓ Account:', account.address);
96
+
97
+ console.log('\n🚀 Deploying token...');
98
+
99
+ // Deploy token with 80/20 reward split
100
+ const { txHash, waitForTransaction, error } = await clanker.deploy({
101
+ name: tokenName,
102
+ symbol: tokenSymbol,
103
+ tokenAdmin: account.address,
104
+ vanity: true, // Generate vanity address with "b07" suffix
105
+ rewards: {
106
+ recipients: [
118
107
  {
119
108
  recipient: agentConfig.wallet,
120
109
  admin: agentConfig.wallet,
121
- bps: 8000, // 80% to agent
122
- token: 'Both', // Both Clanker and WETH
110
+ bps: 8_000, // 80% of rewards
111
+ token: 'Paired', // Take fees in WETH
123
112
  },
124
113
  {
125
114
  recipient: DACTYCLAW_WALLET,
126
115
  admin: DACTYCLAW_WALLET,
127
- bps: 2000, // 20% to Dactyclaw
128
- token: 'Both', // Both Clanker and WETH
116
+ bps: 2_000, // 20% of rewards
117
+ token: 'Both', // Take fees in both tokens
129
118
  },
130
119
  ],
131
- pool: {
132
- positions: 'Standard', // Meme token configuration
133
- },
134
- fees: {
135
- type: 'static',
136
- clankerFee: 100, // 1% in bps
137
- pairedFee: 100, // 1% in bps
138
- },
139
120
  },
140
- };
141
-
142
- spinner.text = 'Validating configuration...';
143
- await new Promise(resolve => setTimeout(resolve, 500));
121
+ fees: {
122
+ type: 'static',
123
+ clankerFee: 100, // 1%
124
+ pairedFee: 100, // 1%
125
+ },
126
+ metadata: {
127
+ description: `${tokenName} - Created with DACTYCLAW`,
128
+ },
129
+ context: {
130
+ interface: 'DACTYCLAW',
131
+ },
132
+ });
144
133
 
145
- // Validate configuration
146
- if (!tokenConfig.name || tokenConfig.name.length === 0) {
147
- throw new Error('Token name is required');
148
- }
149
- if (!tokenConfig.symbol || tokenConfig.symbol.length === 0) {
150
- throw new Error('Token symbol is required');
134
+ if (error) {
135
+ console.error('❌ Deployment error:', error);
136
+ process.exit(1);
151
137
  }
152
138
 
153
- spinner.text = 'Connecting to Clanker network...';
154
- await new Promise(resolve => setTimeout(resolve, 800));
155
-
156
- // Verify network connectivity
157
- try {
158
- const response = await axios.get(`${CLANKER_API}/health`, { timeout: 5000 });
159
- if (response.status !== 200) {
160
- throw new Error('Clanker API unavailable');
161
- }
162
- } catch (error) {
163
- console.log(chalk.yellow('\n⚠ Warning: Clanker API temporarily unavailable'));
164
- console.log(chalk.gray(' Proceeding with local configuration...\n'));
165
- }
139
+ console.log(`✓ Transaction submitted: ${txHash}`);
140
+ console.log('⏳ Waiting for confirmation...\n');
166
141
 
167
- spinner.text = 'Validating private key...';
168
- await new Promise(resolve => setTimeout(resolve, 600));
142
+ const result = await waitForTransaction();
169
143
 
170
- // Validate private key format
171
- const privateKey = process.env.PRIVATE_KEY;
172
- if (!privateKey.match(/^0x[a-fA-F0-9]{64}$/)) {
173
- throw new Error('Invalid private key format. Must be 0x followed by 64 hex characters');
144
+ if (result.error) {
145
+ console.error('❌ Transaction failed:', result.error);
146
+ process.exit(1);
174
147
  }
175
148
 
176
- spinner.text = 'Preparing Clanker SDK deployment...';
177
- await new Promise(resolve => setTimeout(resolve, 800));
178
-
179
- // In production, this would call the actual Clanker SDK
180
- // For now, we're simulating the deployment with proper configuration
181
- spinner.text = 'Signing transaction with private key...';
182
- await new Promise(resolve => setTimeout(resolve, 1000));
149
+ const tokenAddress = result.address;
183
150
 
184
- spinner.text = 'Broadcasting to Base network...';
185
- await new Promise(resolve => setTimeout(resolve, 1500));
151
+ console.log(' Token deployed successfully!');
152
+ console.log(`\n📊 Token Details:`);
153
+ console.log(` Address: ${tokenAddress}`);
154
+ console.log(` Name: ${tokenName}`);
155
+ console.log(` Symbol: ${tokenSymbol}`);
156
+ console.log(` Supply: ${initialSupply}`);
157
+ console.log(` Network: Base`);
158
+ console.log(` Explorer: https://basescan.org/token/${tokenAddress}`);
186
159
 
187
- // Generate contract address and transaction hash (in production, from actual deployment)
188
- const contractAddress = '0x' + Array.from({ length: 40 }, () => Math.floor(Math.random() * 16).toString(16)).join('');
189
- const txHash = '0x' + Array.from({ length: 64 }, () => Math.floor(Math.random() * 16).toString(16)).join('');
190
-
191
- spinner.succeed('Token deployed successfully');
160
+ console.log(`\n💰 Fee Distribution:`);
161
+ console.log(` Agent (${agentConfig.wallet}): 80%`);
162
+ console.log(` Dactyclaw: 20%`);
192
163
 
193
164
  // Save token configuration
194
- spinner.start('Saving token configuration...');
195
- const fullTokenConfig = {
196
- ...tokenConfig,
197
- contractAddress,
165
+ const tokenConfig = {
166
+ name: tokenName,
167
+ symbol: tokenSymbol,
168
+ address: tokenAddress,
169
+ supply: initialSupply,
198
170
  txHash,
199
171
  deployedAt: new Date().toISOString(),
200
- status: 'deployed',
201
- blockExplorerUrl: `https://basescan.org/token/${contractAddress}`,
202
- clankerUrl: `https://clanker.world/token/${contractAddress}`,
172
+ network: 'base',
173
+ agentDNA: agentConfig.dna,
174
+ agentWallet: agentConfig.wallet,
175
+ fees: {
176
+ agent: 80,
177
+ dactyclaw: 20,
178
+ },
203
179
  };
204
180
 
205
- fs.writeFileSync('token.config.json', JSON.stringify(fullTokenConfig, null, 2));
181
+ fs.writeFileSync(
182
+ path.join(process.cwd(), 'token.config.json'),
183
+ JSON.stringify(tokenConfig, null, 2)
184
+ );
185
+
186
+ console.log('\n✓ Token configuration saved to token.config.json');
206
187
 
207
188
  // Update agent config with token info
208
189
  agentConfig.token = {
209
- name: tokenConfig.name,
210
- symbol: tokenConfig.symbol,
211
- supply: supplyInBillions,
212
- contractAddress,
213
- deploymentDate: tokenConfig.deploymentDate,
214
- txHash,
190
+ name: tokenName,
191
+ symbol: tokenSymbol,
192
+ address: tokenAddress,
193
+ deployedAt: new Date().toISOString(),
215
194
  };
216
195
 
217
- fs.writeFileSync('agent.config.json', JSON.stringify(agentConfig, null, 2));
218
-
219
- spinner.succeed('Configuration saved');
220
-
221
- // Display summary
222
- console.log(chalk.green.bold('\n✓ Token launched successfully!\n'));
223
-
224
- console.log(chalk.cyan('[ TOKEN DETAILS ]'));
225
- console.log(chalk.white(`Name: ${tokenConfig.name}`));
226
- console.log(chalk.white(`Symbol: ${tokenConfig.symbol}`));
227
- console.log(chalk.white(`Total Supply: ${supplyInBillions}B`));
228
- console.log(chalk.white(`Decimals: 18`));
229
- console.log(chalk.white(`Network: Base Mainnet`));
230
- console.log(chalk.white(`Contract Address: ${contractAddress}`));
231
- console.log(chalk.white(`Transaction: ${txHash}`));
232
-
233
- console.log(chalk.cyan('\n[ FEE DISTRIBUTION ]'));
234
- console.log(chalk.white(`Agent Wallet: 80% of trading fees`));
235
- console.log(chalk.white(`Dactyclaw: 20% of trading fees`));
236
- console.log(chalk.white(`Your Address: ${agentConfig.wallet}`));
237
-
238
- console.log(chalk.cyan('\n[ BLOCKCHAIN LINKS ]'));
239
- console.log(chalk.white(`BaseScan: https://basescan.org/token/${contractAddress}`));
240
- console.log(chalk.white(`Clanker: https://clanker.world/token/${contractAddress}`));
196
+ fs.writeFileSync(agentConfigPath, JSON.stringify(agentConfig, null, 2));
197
+ console.log('✓ Agent configuration updated');
241
198
 
242
- console.log(chalk.cyan('\n[ NEXT STEPS ]'));
243
- console.log(chalk.white(`1. Monitor your token on Clanker`));
244
- console.log(chalk.white(`2. Track earnings in real-time`));
245
- console.log(chalk.white(`3. Fees automatically distributed to your wallet`));
246
- console.log(chalk.white(`4. Run 'npx dacty-status' to check deployment status`));
247
- console.log(chalk.white(`5. Configuration saved in: token.config.json\n`));
199
+ console.log('\n🎉 Ready to trade!');
200
+ console.log(`\n📱 View on Clanker: https://clanker.world/token/${tokenAddress}`);
201
+ console.log(`🔗 View on Basescan: https://basescan.org/token/${tokenAddress}`);
202
+ console.log(`\n💡 Next steps:`);
203
+ console.log(` 1. Fund your wallet with ETH for gas fees`);
204
+ console.log(` 2. Monitor your token on Clanker.world`);
205
+ console.log(` 3. Check your earnings: npx dacty-status`);
248
206
 
207
+ rl.close();
249
208
  } catch (error) {
250
- spinner.fail('Error launching token');
251
- console.log(chalk.red(`\n✗ ${error.message}\n`));
209
+ console.error('Error:', error.message);
210
+ rl.close();
252
211
  process.exit(1);
253
212
  }
254
213
  }
255
214
 
256
- launchToken().catch((error) => {
257
- console.error(chalk.red(`\n✗ Error: ${error.message}\n`));
215
+ main().catch((error) => {
216
+ console.error('❌ Fatal error:', error);
258
217
  process.exit(1);
259
218
  });
package/lib/index.mjs CHANGED
@@ -1,259 +1,218 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import chalk from 'chalk';
4
- import inquirer from 'inquirer';
5
- import ora from 'ora';
6
3
  import fs from 'fs';
7
4
  import path from 'path';
8
5
  import { fileURLToPath } from 'url';
9
- import { dirname } from 'path';
10
- import dotenv from 'dotenv';
11
- import axios from 'axios';
6
+ import readline from 'readline';
7
+ import { Clanker } from 'clanker-sdk/v4';
8
+ import { createWalletClient, createPublicClient, privateKeyToAccount, http } from 'viem';
9
+ import { base } from 'viem/chains';
12
10
 
13
11
  const __filename = fileURLToPath(import.meta.url);
14
- const __dirname = dirname(__filename);
12
+ const __dirname = path.dirname(__filename);
15
13
 
16
- // Load environment variables from .env file
17
- dotenv.config();
18
-
19
- const DACTYCLAW_WALLET = process.env.DACTYCLAW_WALLET || '0x0000000000000000000000000000000000000000';
20
- const CLANKER_RPC = process.env.CLANKER_RPC || 'https://mainnet.base.org';
21
- const CLANKER_API = process.env.CLANKER_API || 'https://api.clanker.world';
14
+ const rl = readline.createInterface({
15
+ input: process.stdin,
16
+ output: process.stdout,
17
+ });
22
18
 
23
- async function launchToken() {
24
- console.log('\n');
25
- console.log(chalk.green.bold('[ DACTY-LAUNCH ]'));
26
- console.log(chalk.gray('Launch your token on Base network via Clanker\n'));
19
+ function question(prompt) {
20
+ return new Promise((resolve) => {
21
+ rl.question(prompt, (answer) => {
22
+ resolve(answer);
23
+ });
24
+ });
25
+ }
27
26
 
28
- // Check if we're in an agent directory
29
- if (!fs.existsSync('agent.config.json')) {
30
- console.log(chalk.red(' Error: agent.config.json not found'));
31
- console.log(chalk.gray(' Run this command in your agent directory (created by npx dacty-create)\n'));
27
+ async function main() {
28
+ console.log('\n╔═══════════════════════════════════════╗');
29
+ console.log('║ DACTYCLAW - Token Launch ║');
30
+ console.log(' Powered by Clanker v4.0.0 ');
31
+ console.log('╚═══════════════════════════════════════╝\n');
32
+
33
+ // Check if agent.config.json exists
34
+ const agentConfigPath = path.join(process.cwd(), 'agent.config.json');
35
+ if (!fs.existsSync(agentConfigPath)) {
36
+ console.error('❌ Error: agent.config.json not found!');
37
+ console.error(' Please run `npx dacty-create` first to create an agent.');
32
38
  process.exit(1);
33
39
  }
34
40
 
35
- // Load agent config
36
- let agentConfig;
37
- try {
38
- const configContent = fs.readFileSync('agent.config.json', 'utf-8');
39
- agentConfig = JSON.parse(configContent);
40
- } catch (error) {
41
- console.log(chalk.red('✗ Error reading agent.config.json'));
41
+ // Load agent configuration
42
+ const agentConfig = JSON.parse(fs.readFileSync(agentConfigPath, 'utf-8'));
43
+ console.log(`✓ Agent loaded: ${agentConfig.name} (DNA: ${agentConfig.dna})`);
44
+ console.log(`✓ Wallet: ${agentConfig.wallet}\n`);
45
+
46
+ // Check if .env exists with private key
47
+ const envPath = path.join(process.cwd(), '.env');
48
+ if (!fs.existsSync(envPath)) {
49
+ console.error('❌ Error: .env file not found!');
50
+ console.error(' Private key should be in .env file.');
42
51
  process.exit(1);
43
52
  }
44
53
 
45
- // Check for private key
46
- if (!process.env.PRIVATE_KEY) {
47
- console.log(chalk.red('✗ Error: PRIVATE_KEY not found in .env'));
48
- console.log(chalk.gray(' Make sure .env file exists with PRIVATE_KEY set\n'));
54
+ const envContent = fs.readFileSync(envPath, 'utf-8');
55
+ const privateKeyMatch = envContent.match(/PRIVATE_KEY=(.+)/);
56
+ if (!privateKeyMatch) {
57
+ console.error(' Error: PRIVATE_KEY not found in .env file!');
49
58
  process.exit(1);
50
59
  }
51
60
 
52
- // Prompt user for token details
53
- const answers = await inquirer.prompt([
54
- {
55
- type: 'input',
56
- name: 'tokenName',
57
- message: 'Token name:',
58
- default: `${agentConfig.name} Token`,
59
- validate: (input) => input.length > 0 && input.length <= 50 ? true : 'Token name must be 1-50 characters',
60
- },
61
- {
62
- type: 'input',
63
- name: 'tokenSymbol',
64
- message: 'Token symbol (uppercase):',
65
- default: agentConfig.name.substring(0, 4).toUpperCase(),
66
- validate: (input) => /^[A-Z0-9]{1,10}$/.test(input) ? true : 'Symbol must be 1-10 uppercase letters/numbers',
67
- },
68
- {
69
- type: 'input',
70
- name: 'supply',
71
- message: 'Total supply (in billions):',
72
- default: '1',
73
- validate: (input) => !isNaN(input) && parseFloat(input) > 0 ? true : 'Supply must be a positive number',
74
- },
75
- {
76
- type: 'input',
77
- name: 'description',
78
- message: 'Token description (optional):',
79
- default: `Autonomous agent token for ${agentConfig.name}`,
80
- },
81
- {
82
- type: 'confirm',
83
- name: 'confirmLaunch',
84
- message: 'Ready to deploy token on Base network via Clanker?',
85
- default: false,
86
- },
87
- ]);
88
-
89
- if (!answers.confirmLaunch) {
90
- console.log(chalk.yellow('\n✗ Token launch cancelled.\n'));
91
- process.exit(0);
92
- }
61
+ const privateKey = privateKeyMatch[1].trim();
62
+ console.log('✓ Private key loaded from .env\n');
93
63
 
94
- const spinner = ora();
64
+ // Get token details from user
65
+ const tokenName = await question('Token Name: ');
66
+ const tokenSymbol = await question('Token Symbol: ');
67
+ const initialSupply = await question('Initial Supply (default: 1000000000): ') || '1000000000';
95
68
 
96
- try {
97
- spinner.start('Preparing token deployment...');
98
- await new Promise(resolve => setTimeout(resolve, 500));
69
+ console.log('\n📋 Configuration:');
70
+ console.log(` Name: ${tokenName}`);
71
+ console.log(` Symbol: ${tokenSymbol}`);
72
+ console.log(` Supply: ${initialSupply}`);
73
+ console.log(` Agent Wallet: ${agentConfig.wallet}`);
74
+ console.log(` Fee Distribution: 80% Agent, 20% Dactyclaw\n`);
99
75
 
100
- // Calculate supply in wei (18 decimals)
101
- const supplyInBillions = parseFloat(answers.supply);
102
- const totalSupply = BigInt(supplyInBillions) * BigInt(10) ** BigInt(9) * BigInt(10) ** BigInt(18);
76
+ // Dactyclaw wallet address (should be configured)
77
+ const DACTYCLAW_WALLET = process.env.DACTYCLAW_WALLET || '0x0000000000000000000000000000000000000000';
103
78
 
104
- // Create token configuration for Clanker SDK
105
- const tokenConfig = {
106
- name: answers.tokenName,
107
- symbol: answers.tokenSymbol.toUpperCase(),
108
- totalSupply: totalSupply.toString(),
109
- decimals: 18,
110
- network: 'base',
111
- agentDNA: agentConfig.dna,
112
- agentWallet: agentConfig.wallet,
113
- deploymentDate: new Date().toISOString(),
114
- description: answers.description,
115
- clankerIntegration: {
116
- sdkVersion: 'v4.0.0',
117
- rewards: [
79
+ try {
80
+ console.log('🔄 Initializing Clanker SDK...');
81
+
82
+ // Setup viem clients
83
+ const account = privateKeyToAccount(`0x${privateKey.replace(/^0x/, '')}`);
84
+ const publicClient = createPublicClient({ chain: base, transport: http() });
85
+ const walletClient = createWalletClient({ account, chain: base, transport: http() });
86
+
87
+ // Initialize Clanker SDK
88
+ const clanker = new Clanker({
89
+ publicClient,
90
+ wallet: walletClient,
91
+ });
92
+
93
+ console.log('✓ Clanker SDK initialized');
94
+ console.log('✓ Connected to Base network');
95
+ console.log('✓ Account:', account.address);
96
+
97
+ console.log('\n🚀 Deploying token...');
98
+
99
+ // Deploy token with 80/20 reward split
100
+ const { txHash, waitForTransaction, error } = await clanker.deploy({
101
+ name: tokenName,
102
+ symbol: tokenSymbol,
103
+ tokenAdmin: account.address,
104
+ vanity: true, // Generate vanity address with "b07" suffix
105
+ rewards: {
106
+ recipients: [
118
107
  {
119
108
  recipient: agentConfig.wallet,
120
109
  admin: agentConfig.wallet,
121
- bps: 8000, // 80% to agent
122
- token: 'Both', // Both Clanker and WETH
110
+ bps: 8_000, // 80% of rewards
111
+ token: 'Paired', // Take fees in WETH
123
112
  },
124
113
  {
125
114
  recipient: DACTYCLAW_WALLET,
126
115
  admin: DACTYCLAW_WALLET,
127
- bps: 2000, // 20% to Dactyclaw
128
- token: 'Both', // Both Clanker and WETH
116
+ bps: 2_000, // 20% of rewards
117
+ token: 'Both', // Take fees in both tokens
129
118
  },
130
119
  ],
131
- pool: {
132
- positions: 'Standard', // Meme token configuration
133
- },
134
- fees: {
135
- type: 'static',
136
- clankerFee: 100, // 1% in bps
137
- pairedFee: 100, // 1% in bps
138
- },
139
120
  },
140
- };
141
-
142
- spinner.text = 'Validating configuration...';
143
- await new Promise(resolve => setTimeout(resolve, 500));
121
+ fees: {
122
+ type: 'static',
123
+ clankerFee: 100, // 1%
124
+ pairedFee: 100, // 1%
125
+ },
126
+ metadata: {
127
+ description: `${tokenName} - Created with DACTYCLAW`,
128
+ },
129
+ context: {
130
+ interface: 'DACTYCLAW',
131
+ },
132
+ });
144
133
 
145
- // Validate configuration
146
- if (!tokenConfig.name || tokenConfig.name.length === 0) {
147
- throw new Error('Token name is required');
148
- }
149
- if (!tokenConfig.symbol || tokenConfig.symbol.length === 0) {
150
- throw new Error('Token symbol is required');
134
+ if (error) {
135
+ console.error('❌ Deployment error:', error);
136
+ process.exit(1);
151
137
  }
152
138
 
153
- spinner.text = 'Connecting to Clanker network...';
154
- await new Promise(resolve => setTimeout(resolve, 800));
155
-
156
- // Verify network connectivity
157
- try {
158
- const response = await axios.get(`${CLANKER_API}/health`, { timeout: 5000 });
159
- if (response.status !== 200) {
160
- throw new Error('Clanker API unavailable');
161
- }
162
- } catch (error) {
163
- console.log(chalk.yellow('\n⚠ Warning: Clanker API temporarily unavailable'));
164
- console.log(chalk.gray(' Proceeding with local configuration...\n'));
165
- }
139
+ console.log(`✓ Transaction submitted: ${txHash}`);
140
+ console.log('⏳ Waiting for confirmation...\n');
166
141
 
167
- spinner.text = 'Validating private key...';
168
- await new Promise(resolve => setTimeout(resolve, 600));
142
+ const result = await waitForTransaction();
169
143
 
170
- // Validate private key format
171
- const privateKey = process.env.PRIVATE_KEY;
172
- if (!privateKey.match(/^0x[a-fA-F0-9]{64}$/)) {
173
- throw new Error('Invalid private key format. Must be 0x followed by 64 hex characters');
144
+ if (result.error) {
145
+ console.error('❌ Transaction failed:', result.error);
146
+ process.exit(1);
174
147
  }
175
148
 
176
- spinner.text = 'Preparing Clanker SDK deployment...';
177
- await new Promise(resolve => setTimeout(resolve, 800));
178
-
179
- // In production, this would call the actual Clanker SDK
180
- // For now, we're simulating the deployment with proper configuration
181
- spinner.text = 'Signing transaction with private key...';
182
- await new Promise(resolve => setTimeout(resolve, 1000));
149
+ const tokenAddress = result.address;
183
150
 
184
- spinner.text = 'Broadcasting to Base network...';
185
- await new Promise(resolve => setTimeout(resolve, 1500));
151
+ console.log(' Token deployed successfully!');
152
+ console.log(`\n📊 Token Details:`);
153
+ console.log(` Address: ${tokenAddress}`);
154
+ console.log(` Name: ${tokenName}`);
155
+ console.log(` Symbol: ${tokenSymbol}`);
156
+ console.log(` Supply: ${initialSupply}`);
157
+ console.log(` Network: Base`);
158
+ console.log(` Explorer: https://basescan.org/token/${tokenAddress}`);
186
159
 
187
- // Generate contract address and transaction hash (in production, from actual deployment)
188
- const contractAddress = '0x' + Array.from({ length: 40 }, () => Math.floor(Math.random() * 16).toString(16)).join('');
189
- const txHash = '0x' + Array.from({ length: 64 }, () => Math.floor(Math.random() * 16).toString(16)).join('');
190
-
191
- spinner.succeed('Token deployed successfully');
160
+ console.log(`\n💰 Fee Distribution:`);
161
+ console.log(` Agent (${agentConfig.wallet}): 80%`);
162
+ console.log(` Dactyclaw: 20%`);
192
163
 
193
164
  // Save token configuration
194
- spinner.start('Saving token configuration...');
195
- const fullTokenConfig = {
196
- ...tokenConfig,
197
- contractAddress,
165
+ const tokenConfig = {
166
+ name: tokenName,
167
+ symbol: tokenSymbol,
168
+ address: tokenAddress,
169
+ supply: initialSupply,
198
170
  txHash,
199
171
  deployedAt: new Date().toISOString(),
200
- status: 'deployed',
201
- blockExplorerUrl: `https://basescan.org/token/${contractAddress}`,
202
- clankerUrl: `https://clanker.world/token/${contractAddress}`,
172
+ network: 'base',
173
+ agentDNA: agentConfig.dna,
174
+ agentWallet: agentConfig.wallet,
175
+ fees: {
176
+ agent: 80,
177
+ dactyclaw: 20,
178
+ },
203
179
  };
204
180
 
205
- fs.writeFileSync('token.config.json', JSON.stringify(fullTokenConfig, null, 2));
181
+ fs.writeFileSync(
182
+ path.join(process.cwd(), 'token.config.json'),
183
+ JSON.stringify(tokenConfig, null, 2)
184
+ );
185
+
186
+ console.log('\n✓ Token configuration saved to token.config.json');
206
187
 
207
188
  // Update agent config with token info
208
189
  agentConfig.token = {
209
- name: tokenConfig.name,
210
- symbol: tokenConfig.symbol,
211
- supply: supplyInBillions,
212
- contractAddress,
213
- deploymentDate: tokenConfig.deploymentDate,
214
- txHash,
190
+ name: tokenName,
191
+ symbol: tokenSymbol,
192
+ address: tokenAddress,
193
+ deployedAt: new Date().toISOString(),
215
194
  };
216
195
 
217
- fs.writeFileSync('agent.config.json', JSON.stringify(agentConfig, null, 2));
218
-
219
- spinner.succeed('Configuration saved');
220
-
221
- // Display summary
222
- console.log(chalk.green.bold('\n✓ Token launched successfully!\n'));
223
-
224
- console.log(chalk.cyan('[ TOKEN DETAILS ]'));
225
- console.log(chalk.white(`Name: ${tokenConfig.name}`));
226
- console.log(chalk.white(`Symbol: ${tokenConfig.symbol}`));
227
- console.log(chalk.white(`Total Supply: ${supplyInBillions}B`));
228
- console.log(chalk.white(`Decimals: 18`));
229
- console.log(chalk.white(`Network: Base Mainnet`));
230
- console.log(chalk.white(`Contract Address: ${contractAddress}`));
231
- console.log(chalk.white(`Transaction: ${txHash}`));
232
-
233
- console.log(chalk.cyan('\n[ FEE DISTRIBUTION ]'));
234
- console.log(chalk.white(`Agent Wallet: 80% of trading fees`));
235
- console.log(chalk.white(`Dactyclaw: 20% of trading fees`));
236
- console.log(chalk.white(`Your Address: ${agentConfig.wallet}`));
237
-
238
- console.log(chalk.cyan('\n[ BLOCKCHAIN LINKS ]'));
239
- console.log(chalk.white(`BaseScan: https://basescan.org/token/${contractAddress}`));
240
- console.log(chalk.white(`Clanker: https://clanker.world/token/${contractAddress}`));
196
+ fs.writeFileSync(agentConfigPath, JSON.stringify(agentConfig, null, 2));
197
+ console.log('✓ Agent configuration updated');
241
198
 
242
- console.log(chalk.cyan('\n[ NEXT STEPS ]'));
243
- console.log(chalk.white(`1. Monitor your token on Clanker`));
244
- console.log(chalk.white(`2. Track earnings in real-time`));
245
- console.log(chalk.white(`3. Fees automatically distributed to your wallet`));
246
- console.log(chalk.white(`4. Run 'npx dacty-status' to check deployment status`));
247
- console.log(chalk.white(`5. Configuration saved in: token.config.json\n`));
199
+ console.log('\n🎉 Ready to trade!');
200
+ console.log(`\n📱 View on Clanker: https://clanker.world/token/${tokenAddress}`);
201
+ console.log(`🔗 View on Basescan: https://basescan.org/token/${tokenAddress}`);
202
+ console.log(`\n💡 Next steps:`);
203
+ console.log(` 1. Fund your wallet with ETH for gas fees`);
204
+ console.log(` 2. Monitor your token on Clanker.world`);
205
+ console.log(` 3. Check your earnings: npx dacty-status`);
248
206
 
207
+ rl.close();
249
208
  } catch (error) {
250
- spinner.fail('Error launching token');
251
- console.log(chalk.red(`\n✗ ${error.message}\n`));
209
+ console.error('Error:', error.message);
210
+ rl.close();
252
211
  process.exit(1);
253
212
  }
254
213
  }
255
214
 
256
- launchToken().catch((error) => {
257
- console.error(chalk.red(`\n✗ Error: ${error.message}\n`));
215
+ main().catch((error) => {
216
+ console.error('❌ Fatal error:', error);
258
217
  process.exit(1);
259
218
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dacty-launch",
3
- "version": "1.1.3",
3
+ "version": "1.1.4",
4
4
  "description": "Launch tokens for agents in the Dactyclaw ecosystem",
5
5
  "type": "module",
6
6
  "bin": {
@@ -21,6 +21,7 @@
21
21
  "author": "Dactyclaw",
22
22
  "license": "MIT",
23
23
  "dependencies": {
24
+ "clanker-sdk": "^4.0.0",
24
25
  "chalk": "^5.3.0",
25
26
  "inquirer": "^9.2.12",
26
27
  "ora": "^8.0.1",