dacty-launch 1.1.3 → 1.1.5

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,219 @@
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, http } from 'viem';
9
+ import { privateKeyToAccount } from 'viem/accounts';
10
+ import { base } from 'viem/chains';
12
11
 
13
12
  const __filename = fileURLToPath(import.meta.url);
14
- const __dirname = dirname(__filename);
13
+ const __dirname = path.dirname(__filename);
15
14
 
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';
15
+ const rl = readline.createInterface({
16
+ input: process.stdin,
17
+ output: process.stdout,
18
+ });
22
19
 
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'));
20
+ function question(prompt) {
21
+ return new Promise((resolve) => {
22
+ rl.question(prompt, (answer) => {
23
+ resolve(answer);
24
+ });
25
+ });
26
+ }
27
27
 
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'));
28
+ async function main() {
29
+ console.log('\n╔═══════════════════════════════════════╗');
30
+ console.log('║ DACTYCLAW - Token Launch ║');
31
+ console.log(' Powered by Clanker v4.0.0 ');
32
+ console.log('╚═══════════════════════════════════════╝\n');
33
+
34
+ // Check if agent.config.json exists
35
+ const agentConfigPath = path.join(process.cwd(), 'agent.config.json');
36
+ if (!fs.existsSync(agentConfigPath)) {
37
+ console.error('❌ Error: agent.config.json not found!');
38
+ console.error(' Please run `npx dacty-create` first to create an agent.');
32
39
  process.exit(1);
33
40
  }
34
41
 
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'));
42
+ // Load agent configuration
43
+ const agentConfig = JSON.parse(fs.readFileSync(agentConfigPath, 'utf-8'));
44
+ console.log(`✓ Agent loaded: ${agentConfig.name} (DNA: ${agentConfig.dna})`);
45
+ console.log(`✓ Wallet: ${agentConfig.wallet}\n`);
46
+
47
+ // Check if .env exists with private key
48
+ const envPath = path.join(process.cwd(), '.env');
49
+ if (!fs.existsSync(envPath)) {
50
+ console.error('❌ Error: .env file not found!');
51
+ console.error(' Private key should be in .env file.');
42
52
  process.exit(1);
43
53
  }
44
54
 
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'));
55
+ const envContent = fs.readFileSync(envPath, 'utf-8');
56
+ const privateKeyMatch = envContent.match(/PRIVATE_KEY=(.+)/);
57
+ if (!privateKeyMatch) {
58
+ console.error(' Error: PRIVATE_KEY not found in .env file!');
49
59
  process.exit(1);
50
60
  }
51
61
 
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
- }
62
+ const privateKey = privateKeyMatch[1].trim();
63
+ console.log('✓ Private key loaded from .env\n');
93
64
 
94
- const spinner = ora();
65
+ // Get token details from user
66
+ const tokenName = await question('Token Name: ');
67
+ const tokenSymbol = await question('Token Symbol: ');
68
+ const initialSupply = await question('Initial Supply (default: 1000000000): ') || '1000000000';
95
69
 
96
- try {
97
- spinner.start('Preparing token deployment...');
98
- await new Promise(resolve => setTimeout(resolve, 500));
70
+ console.log('\n📋 Configuration:');
71
+ console.log(` Name: ${tokenName}`);
72
+ console.log(` Symbol: ${tokenSymbol}`);
73
+ console.log(` Supply: ${initialSupply}`);
74
+ console.log(` Agent Wallet: ${agentConfig.wallet}`);
75
+ console.log(` Fee Distribution: 80% Agent, 20% Dactyclaw\n`);
99
76
 
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);
77
+ // Dactyclaw wallet address (should be configured)
78
+ const DACTYCLAW_WALLET = process.env.DACTYCLAW_WALLET || '0x0000000000000000000000000000000000000000';
103
79
 
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: [
80
+ try {
81
+ console.log('🔄 Initializing Clanker SDK...');
82
+
83
+ // Setup viem clients
84
+ const account = privateKeyToAccount(`0x${privateKey.replace(/^0x/, '')}`);
85
+ const publicClient = createPublicClient({ chain: base, transport: http() });
86
+ const walletClient = createWalletClient({ account, chain: base, transport: http() });
87
+
88
+ // Initialize Clanker SDK
89
+ const clanker = new Clanker({
90
+ publicClient,
91
+ wallet: walletClient,
92
+ });
93
+
94
+ console.log('✓ Clanker SDK initialized');
95
+ console.log('✓ Connected to Base network');
96
+ console.log('✓ Account:', account.address);
97
+
98
+ console.log('\n🚀 Deploying token...');
99
+
100
+ // Deploy token with 80/20 reward split
101
+ const { txHash, waitForTransaction, error } = await clanker.deploy({
102
+ name: tokenName,
103
+ symbol: tokenSymbol,
104
+ tokenAdmin: account.address,
105
+ vanity: true, // Generate vanity address with "b07" suffix
106
+ rewards: {
107
+ recipients: [
118
108
  {
119
109
  recipient: agentConfig.wallet,
120
110
  admin: agentConfig.wallet,
121
- bps: 8000, // 80% to agent
122
- token: 'Both', // Both Clanker and WETH
111
+ bps: 8_000, // 80% of rewards
112
+ token: 'Paired', // Take fees in WETH
123
113
  },
124
114
  {
125
115
  recipient: DACTYCLAW_WALLET,
126
116
  admin: DACTYCLAW_WALLET,
127
- bps: 2000, // 20% to Dactyclaw
128
- token: 'Both', // Both Clanker and WETH
117
+ bps: 2_000, // 20% of rewards
118
+ token: 'Both', // Take fees in both tokens
129
119
  },
130
120
  ],
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
121
  },
140
- };
141
-
142
- spinner.text = 'Validating configuration...';
143
- await new Promise(resolve => setTimeout(resolve, 500));
122
+ fees: {
123
+ type: 'static',
124
+ clankerFee: 100, // 1%
125
+ pairedFee: 100, // 1%
126
+ },
127
+ metadata: {
128
+ description: `${tokenName} - Created with DACTYCLAW`,
129
+ },
130
+ context: {
131
+ interface: 'DACTYCLAW',
132
+ },
133
+ });
144
134
 
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');
135
+ if (error) {
136
+ console.error('❌ Deployment error:', error);
137
+ process.exit(1);
151
138
  }
152
139
 
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
- }
140
+ console.log(`✓ Transaction submitted: ${txHash}`);
141
+ console.log('⏳ Waiting for confirmation...\n');
166
142
 
167
- spinner.text = 'Validating private key...';
168
- await new Promise(resolve => setTimeout(resolve, 600));
143
+ const result = await waitForTransaction();
169
144
 
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');
145
+ if (result.error) {
146
+ console.error('❌ Transaction failed:', result.error);
147
+ process.exit(1);
174
148
  }
175
149
 
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));
150
+ const tokenAddress = result.address;
183
151
 
184
- spinner.text = 'Broadcasting to Base network...';
185
- await new Promise(resolve => setTimeout(resolve, 1500));
152
+ console.log(' Token deployed successfully!');
153
+ console.log(`\n📊 Token Details:`);
154
+ console.log(` Address: ${tokenAddress}`);
155
+ console.log(` Name: ${tokenName}`);
156
+ console.log(` Symbol: ${tokenSymbol}`);
157
+ console.log(` Supply: ${initialSupply}`);
158
+ console.log(` Network: Base`);
159
+ console.log(` Explorer: https://basescan.org/token/${tokenAddress}`);
186
160
 
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');
161
+ console.log(`\n💰 Fee Distribution:`);
162
+ console.log(` Agent (${agentConfig.wallet}): 80%`);
163
+ console.log(` Dactyclaw: 20%`);
192
164
 
193
165
  // Save token configuration
194
- spinner.start('Saving token configuration...');
195
- const fullTokenConfig = {
196
- ...tokenConfig,
197
- contractAddress,
166
+ const tokenConfig = {
167
+ name: tokenName,
168
+ symbol: tokenSymbol,
169
+ address: tokenAddress,
170
+ supply: initialSupply,
198
171
  txHash,
199
172
  deployedAt: new Date().toISOString(),
200
- status: 'deployed',
201
- blockExplorerUrl: `https://basescan.org/token/${contractAddress}`,
202
- clankerUrl: `https://clanker.world/token/${contractAddress}`,
173
+ network: 'base',
174
+ agentDNA: agentConfig.dna,
175
+ agentWallet: agentConfig.wallet,
176
+ fees: {
177
+ agent: 80,
178
+ dactyclaw: 20,
179
+ },
203
180
  };
204
181
 
205
- fs.writeFileSync('token.config.json', JSON.stringify(fullTokenConfig, null, 2));
182
+ fs.writeFileSync(
183
+ path.join(process.cwd(), 'token.config.json'),
184
+ JSON.stringify(tokenConfig, null, 2)
185
+ );
186
+
187
+ console.log('\n✓ Token configuration saved to token.config.json');
206
188
 
207
189
  // Update agent config with token info
208
190
  agentConfig.token = {
209
- name: tokenConfig.name,
210
- symbol: tokenConfig.symbol,
211
- supply: supplyInBillions,
212
- contractAddress,
213
- deploymentDate: tokenConfig.deploymentDate,
214
- txHash,
191
+ name: tokenName,
192
+ symbol: tokenSymbol,
193
+ address: tokenAddress,
194
+ deployedAt: new Date().toISOString(),
215
195
  };
216
196
 
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}`));
197
+ fs.writeFileSync(agentConfigPath, JSON.stringify(agentConfig, null, 2));
198
+ console.log('✓ Agent configuration updated');
241
199
 
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`));
200
+ console.log('\n🎉 Ready to trade!');
201
+ console.log(`\n📱 View on Clanker: https://clanker.world/token/${tokenAddress}`);
202
+ console.log(`🔗 View on Basescan: https://basescan.org/token/${tokenAddress}`);
203
+ console.log(`\n💡 Next steps:`);
204
+ console.log(` 1. Fund your wallet with ETH for gas fees`);
205
+ console.log(` 2. Monitor your token on Clanker.world`);
206
+ console.log(` 3. Check your earnings: npx dacty-status`);
248
207
 
208
+ rl.close();
249
209
  } catch (error) {
250
- spinner.fail('Error launching token');
251
- console.log(chalk.red(`\n✗ ${error.message}\n`));
210
+ console.error('Error:', error.message);
211
+ rl.close();
252
212
  process.exit(1);
253
213
  }
254
214
  }
255
215
 
256
- launchToken().catch((error) => {
257
- console.error(chalk.red(`\n✗ Error: ${error.message}\n`));
216
+ main().catch((error) => {
217
+ console.error('❌ Fatal error:', error);
258
218
  process.exit(1);
259
219
  });
package/lib/index.mjs CHANGED
@@ -1,259 +1,219 @@
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, http } from 'viem';
9
+ import { privateKeyToAccount } from 'viem/accounts';
10
+ import { base } from 'viem/chains';
12
11
 
13
12
  const __filename = fileURLToPath(import.meta.url);
14
- const __dirname = dirname(__filename);
13
+ const __dirname = path.dirname(__filename);
15
14
 
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';
15
+ const rl = readline.createInterface({
16
+ input: process.stdin,
17
+ output: process.stdout,
18
+ });
22
19
 
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'));
20
+ function question(prompt) {
21
+ return new Promise((resolve) => {
22
+ rl.question(prompt, (answer) => {
23
+ resolve(answer);
24
+ });
25
+ });
26
+ }
27
27
 
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'));
28
+ async function main() {
29
+ console.log('\n╔═══════════════════════════════════════╗');
30
+ console.log('║ DACTYCLAW - Token Launch ║');
31
+ console.log(' Powered by Clanker v4.0.0 ');
32
+ console.log('╚═══════════════════════════════════════╝\n');
33
+
34
+ // Check if agent.config.json exists
35
+ const agentConfigPath = path.join(process.cwd(), 'agent.config.json');
36
+ if (!fs.existsSync(agentConfigPath)) {
37
+ console.error('❌ Error: agent.config.json not found!');
38
+ console.error(' Please run `npx dacty-create` first to create an agent.');
32
39
  process.exit(1);
33
40
  }
34
41
 
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'));
42
+ // Load agent configuration
43
+ const agentConfig = JSON.parse(fs.readFileSync(agentConfigPath, 'utf-8'));
44
+ console.log(`✓ Agent loaded: ${agentConfig.name} (DNA: ${agentConfig.dna})`);
45
+ console.log(`✓ Wallet: ${agentConfig.wallet}\n`);
46
+
47
+ // Check if .env exists with private key
48
+ const envPath = path.join(process.cwd(), '.env');
49
+ if (!fs.existsSync(envPath)) {
50
+ console.error('❌ Error: .env file not found!');
51
+ console.error(' Private key should be in .env file.');
42
52
  process.exit(1);
43
53
  }
44
54
 
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'));
55
+ const envContent = fs.readFileSync(envPath, 'utf-8');
56
+ const privateKeyMatch = envContent.match(/PRIVATE_KEY=(.+)/);
57
+ if (!privateKeyMatch) {
58
+ console.error(' Error: PRIVATE_KEY not found in .env file!');
49
59
  process.exit(1);
50
60
  }
51
61
 
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
- }
62
+ const privateKey = privateKeyMatch[1].trim();
63
+ console.log('✓ Private key loaded from .env\n');
93
64
 
94
- const spinner = ora();
65
+ // Get token details from user
66
+ const tokenName = await question('Token Name: ');
67
+ const tokenSymbol = await question('Token Symbol: ');
68
+ const initialSupply = await question('Initial Supply (default: 1000000000): ') || '1000000000';
95
69
 
96
- try {
97
- spinner.start('Preparing token deployment...');
98
- await new Promise(resolve => setTimeout(resolve, 500));
70
+ console.log('\n📋 Configuration:');
71
+ console.log(` Name: ${tokenName}`);
72
+ console.log(` Symbol: ${tokenSymbol}`);
73
+ console.log(` Supply: ${initialSupply}`);
74
+ console.log(` Agent Wallet: ${agentConfig.wallet}`);
75
+ console.log(` Fee Distribution: 80% Agent, 20% Dactyclaw\n`);
99
76
 
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);
77
+ // Dactyclaw wallet address (should be configured)
78
+ const DACTYCLAW_WALLET = process.env.DACTYCLAW_WALLET || '0x0000000000000000000000000000000000000000';
103
79
 
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: [
80
+ try {
81
+ console.log('🔄 Initializing Clanker SDK...');
82
+
83
+ // Setup viem clients
84
+ const account = privateKeyToAccount(`0x${privateKey.replace(/^0x/, '')}`);
85
+ const publicClient = createPublicClient({ chain: base, transport: http() });
86
+ const walletClient = createWalletClient({ account, chain: base, transport: http() });
87
+
88
+ // Initialize Clanker SDK
89
+ const clanker = new Clanker({
90
+ publicClient,
91
+ wallet: walletClient,
92
+ });
93
+
94
+ console.log('✓ Clanker SDK initialized');
95
+ console.log('✓ Connected to Base network');
96
+ console.log('✓ Account:', account.address);
97
+
98
+ console.log('\n🚀 Deploying token...');
99
+
100
+ // Deploy token with 80/20 reward split
101
+ const { txHash, waitForTransaction, error } = await clanker.deploy({
102
+ name: tokenName,
103
+ symbol: tokenSymbol,
104
+ tokenAdmin: account.address,
105
+ vanity: true, // Generate vanity address with "b07" suffix
106
+ rewards: {
107
+ recipients: [
118
108
  {
119
109
  recipient: agentConfig.wallet,
120
110
  admin: agentConfig.wallet,
121
- bps: 8000, // 80% to agent
122
- token: 'Both', // Both Clanker and WETH
111
+ bps: 8_000, // 80% of rewards
112
+ token: 'Paired', // Take fees in WETH
123
113
  },
124
114
  {
125
115
  recipient: DACTYCLAW_WALLET,
126
116
  admin: DACTYCLAW_WALLET,
127
- bps: 2000, // 20% to Dactyclaw
128
- token: 'Both', // Both Clanker and WETH
117
+ bps: 2_000, // 20% of rewards
118
+ token: 'Both', // Take fees in both tokens
129
119
  },
130
120
  ],
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
121
  },
140
- };
141
-
142
- spinner.text = 'Validating configuration...';
143
- await new Promise(resolve => setTimeout(resolve, 500));
122
+ fees: {
123
+ type: 'static',
124
+ clankerFee: 100, // 1%
125
+ pairedFee: 100, // 1%
126
+ },
127
+ metadata: {
128
+ description: `${tokenName} - Created with DACTYCLAW`,
129
+ },
130
+ context: {
131
+ interface: 'DACTYCLAW',
132
+ },
133
+ });
144
134
 
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');
135
+ if (error) {
136
+ console.error('❌ Deployment error:', error);
137
+ process.exit(1);
151
138
  }
152
139
 
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
- }
140
+ console.log(`✓ Transaction submitted: ${txHash}`);
141
+ console.log('⏳ Waiting for confirmation...\n');
166
142
 
167
- spinner.text = 'Validating private key...';
168
- await new Promise(resolve => setTimeout(resolve, 600));
143
+ const result = await waitForTransaction();
169
144
 
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');
145
+ if (result.error) {
146
+ console.error('❌ Transaction failed:', result.error);
147
+ process.exit(1);
174
148
  }
175
149
 
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));
150
+ const tokenAddress = result.address;
183
151
 
184
- spinner.text = 'Broadcasting to Base network...';
185
- await new Promise(resolve => setTimeout(resolve, 1500));
152
+ console.log(' Token deployed successfully!');
153
+ console.log(`\n📊 Token Details:`);
154
+ console.log(` Address: ${tokenAddress}`);
155
+ console.log(` Name: ${tokenName}`);
156
+ console.log(` Symbol: ${tokenSymbol}`);
157
+ console.log(` Supply: ${initialSupply}`);
158
+ console.log(` Network: Base`);
159
+ console.log(` Explorer: https://basescan.org/token/${tokenAddress}`);
186
160
 
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');
161
+ console.log(`\n💰 Fee Distribution:`);
162
+ console.log(` Agent (${agentConfig.wallet}): 80%`);
163
+ console.log(` Dactyclaw: 20%`);
192
164
 
193
165
  // Save token configuration
194
- spinner.start('Saving token configuration...');
195
- const fullTokenConfig = {
196
- ...tokenConfig,
197
- contractAddress,
166
+ const tokenConfig = {
167
+ name: tokenName,
168
+ symbol: tokenSymbol,
169
+ address: tokenAddress,
170
+ supply: initialSupply,
198
171
  txHash,
199
172
  deployedAt: new Date().toISOString(),
200
- status: 'deployed',
201
- blockExplorerUrl: `https://basescan.org/token/${contractAddress}`,
202
- clankerUrl: `https://clanker.world/token/${contractAddress}`,
173
+ network: 'base',
174
+ agentDNA: agentConfig.dna,
175
+ agentWallet: agentConfig.wallet,
176
+ fees: {
177
+ agent: 80,
178
+ dactyclaw: 20,
179
+ },
203
180
  };
204
181
 
205
- fs.writeFileSync('token.config.json', JSON.stringify(fullTokenConfig, null, 2));
182
+ fs.writeFileSync(
183
+ path.join(process.cwd(), 'token.config.json'),
184
+ JSON.stringify(tokenConfig, null, 2)
185
+ );
186
+
187
+ console.log('\n✓ Token configuration saved to token.config.json');
206
188
 
207
189
  // Update agent config with token info
208
190
  agentConfig.token = {
209
- name: tokenConfig.name,
210
- symbol: tokenConfig.symbol,
211
- supply: supplyInBillions,
212
- contractAddress,
213
- deploymentDate: tokenConfig.deploymentDate,
214
- txHash,
191
+ name: tokenName,
192
+ symbol: tokenSymbol,
193
+ address: tokenAddress,
194
+ deployedAt: new Date().toISOString(),
215
195
  };
216
196
 
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}`));
197
+ fs.writeFileSync(agentConfigPath, JSON.stringify(agentConfig, null, 2));
198
+ console.log('✓ Agent configuration updated');
241
199
 
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`));
200
+ console.log('\n🎉 Ready to trade!');
201
+ console.log(`\n📱 View on Clanker: https://clanker.world/token/${tokenAddress}`);
202
+ console.log(`🔗 View on Basescan: https://basescan.org/token/${tokenAddress}`);
203
+ console.log(`\n💡 Next steps:`);
204
+ console.log(` 1. Fund your wallet with ETH for gas fees`);
205
+ console.log(` 2. Monitor your token on Clanker.world`);
206
+ console.log(` 3. Check your earnings: npx dacty-status`);
248
207
 
208
+ rl.close();
249
209
  } catch (error) {
250
- spinner.fail('Error launching token');
251
- console.log(chalk.red(`\n✗ ${error.message}\n`));
210
+ console.error('Error:', error.message);
211
+ rl.close();
252
212
  process.exit(1);
253
213
  }
254
214
  }
255
215
 
256
- launchToken().catch((error) => {
257
- console.error(chalk.red(`\n✗ Error: ${error.message}\n`));
216
+ main().catch((error) => {
217
+ console.error('❌ Fatal error:', error);
258
218
  process.exit(1);
259
219
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dacty-launch",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
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",