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