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.
- package/bin/dacty-launch.mjs +157 -197
- package/lib/index.mjs +157 -197
- package/package.json +2 -1
package/bin/dacty-launch.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
|
|
10
|
-
import
|
|
11
|
-
import
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
function question(prompt) {
|
|
21
|
+
return new Promise((resolve) => {
|
|
22
|
+
rl.question(prompt, (answer) => {
|
|
23
|
+
resolve(answer);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
console.
|
|
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
|
-
|
|
53
|
-
|
|
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
|
-
|
|
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
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
-
|
|
101
|
-
|
|
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
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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:
|
|
122
|
-
token: '
|
|
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:
|
|
128
|
-
token: 'Both', //
|
|
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
|
-
|
|
143
|
-
|
|
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
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|
-
|
|
154
|
-
|
|
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
|
-
|
|
168
|
-
await new Promise(resolve => setTimeout(resolve, 600));
|
|
143
|
+
const result = await waitForTransaction();
|
|
169
144
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
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
|
-
|
|
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
|
-
|
|
185
|
-
|
|
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
|
-
|
|
188
|
-
|
|
189
|
-
|
|
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
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
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
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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(
|
|
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:
|
|
210
|
-
symbol:
|
|
211
|
-
|
|
212
|
-
|
|
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(
|
|
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(
|
|
243
|
-
console.log(
|
|
244
|
-
console.log(
|
|
245
|
-
console.log(
|
|
246
|
-
console.log(
|
|
247
|
-
console.log(
|
|
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
|
-
|
|
251
|
-
|
|
210
|
+
console.error('❌ Error:', error.message);
|
|
211
|
+
rl.close();
|
|
252
212
|
process.exit(1);
|
|
253
213
|
}
|
|
254
214
|
}
|
|
255
215
|
|
|
256
|
-
|
|
257
|
-
console.error(
|
|
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
|
|
10
|
-
import
|
|
11
|
-
import
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
function question(prompt) {
|
|
21
|
+
return new Promise((resolve) => {
|
|
22
|
+
rl.question(prompt, (answer) => {
|
|
23
|
+
resolve(answer);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
console.
|
|
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
|
-
|
|
53
|
-
|
|
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
|
-
|
|
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
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
-
|
|
101
|
-
|
|
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
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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:
|
|
122
|
-
token: '
|
|
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:
|
|
128
|
-
token: 'Both', //
|
|
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
|
-
|
|
143
|
-
|
|
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
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|
-
|
|
154
|
-
|
|
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
|
-
|
|
168
|
-
await new Promise(resolve => setTimeout(resolve, 600));
|
|
143
|
+
const result = await waitForTransaction();
|
|
169
144
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
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
|
-
|
|
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
|
-
|
|
185
|
-
|
|
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
|
-
|
|
188
|
-
|
|
189
|
-
|
|
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
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
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
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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(
|
|
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:
|
|
210
|
-
symbol:
|
|
211
|
-
|
|
212
|
-
|
|
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(
|
|
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(
|
|
243
|
-
console.log(
|
|
244
|
-
console.log(
|
|
245
|
-
console.log(
|
|
246
|
-
console.log(
|
|
247
|
-
console.log(
|
|
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
|
-
|
|
251
|
-
|
|
210
|
+
console.error('❌ Error:', error.message);
|
|
211
|
+
rl.close();
|
|
252
212
|
process.exit(1);
|
|
253
213
|
}
|
|
254
214
|
}
|
|
255
215
|
|
|
256
|
-
|
|
257
|
-
console.error(
|
|
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
|
+
"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",
|