dacty-launch 1.5.0 ā 1.6.0
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/index.js +10 -0
- package/package.json +7 -42
- package/README.md +0 -125
- package/bin/dacty-launch.mjs +0 -245
- package/build.mjs +0 -19
- package/lib/index.mjs +0 -245
package/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const { execSync } = require('child_process');
|
|
3
|
+
|
|
4
|
+
try {
|
|
5
|
+
// Forward the command to the main dactyclaw package transparently
|
|
6
|
+
const args = process.argv.slice(2).join(' ');
|
|
7
|
+
execSync(`npx --yes --package dactyclaw@latest dacty-launch ${args}`, { stdio: 'inherit' });
|
|
8
|
+
} catch (error) {
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
package/package.json
CHANGED
|
@@ -1,48 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dacty-launch",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
5
|
-
"type": "module",
|
|
3
|
+
"version": "1.6.0",
|
|
4
|
+
"description": "Proxy for launching Dactyclaw agent tokens (Alias)",
|
|
6
5
|
"bin": {
|
|
7
|
-
"dacty-launch": "
|
|
6
|
+
"dacty-launch": "index.js"
|
|
8
7
|
},
|
|
9
|
-
"main": "lib/index.mjs",
|
|
10
8
|
"scripts": {
|
|
11
|
-
"
|
|
12
|
-
"prepublishOnly": "npm run build"
|
|
9
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
13
10
|
},
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"launch",
|
|
18
|
-
"blockchain",
|
|
19
|
-
"cli"
|
|
20
|
-
],
|
|
21
|
-
"author": "Dactyclaw",
|
|
22
|
-
"license": "MIT",
|
|
23
|
-
"dependencies": {
|
|
24
|
-
"axios": "^1.6.5",
|
|
25
|
-
"chalk": "^5.3.0",
|
|
26
|
-
"clanker-sdk": "^4.0.0",
|
|
27
|
-
"dotenv": "^16.3.1",
|
|
28
|
-
"inquirer": "^9.2.12",
|
|
29
|
-
"node-fetch": "^3.3.2",
|
|
30
|
-
"ora": "^8.0.1",
|
|
31
|
-
"undici": "^7.22.0",
|
|
32
|
-
"viem": "^2.0.0"
|
|
33
|
-
},
|
|
34
|
-
"devDependencies": {
|
|
35
|
-
"@types/node": "^20.10.5"
|
|
36
|
-
},
|
|
37
|
-
"engines": {
|
|
38
|
-
"node": ">=18.0.0"
|
|
39
|
-
},
|
|
40
|
-
"repository": {
|
|
41
|
-
"type": "git",
|
|
42
|
-
"url": "https://github.com/dactyclaw/dacty-launch.git"
|
|
43
|
-
},
|
|
44
|
-
"bugs": {
|
|
45
|
-
"url": "https://github.com/dactyclaw/dacty-launch/issues"
|
|
46
|
-
},
|
|
47
|
-
"homepage": "https://github.com/dactyclaw/dacty-launch#readme"
|
|
48
|
-
}
|
|
11
|
+
"author": "dactyclaw",
|
|
12
|
+
"license": "ISC"
|
|
13
|
+
}
|
package/README.md
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
# dacty-launch
|
|
2
|
-
|
|
3
|
-
Launch tokens on Base network via Clanker with a single command.
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
npx dacty-launch
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
## Features
|
|
10
|
-
|
|
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
|
-
|
|
18
|
-
## Installation
|
|
19
|
-
|
|
20
|
-
Use directly with npx (recommended):
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
npx dacty-launch
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Or install globally:
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
npm install -g dacty-launch
|
|
30
|
-
dacty-launch
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## Usage
|
|
34
|
-
|
|
35
|
-
Run the interactive CLI:
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
npx dacty-launch
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
The CLI will prompt you for:
|
|
42
|
-
|
|
43
|
-
1. **Token Name** - The name of your token
|
|
44
|
-
2. **Token Symbol** - The symbol (3-10 characters)
|
|
45
|
-
|
|
46
|
-
Initial supply defaults to 1,000,000,000 tokens.
|
|
47
|
-
|
|
48
|
-
## Workflow
|
|
49
|
-
|
|
50
|
-
Complete workflow for launching an agent with token:
|
|
51
|
-
|
|
52
|
-
```bash
|
|
53
|
-
# Step 1: Create agent (generates wallet + private key)
|
|
54
|
-
npx dacty-create
|
|
55
|
-
|
|
56
|
-
# Step 2: Launch token (deploys to Base via Clanker)
|
|
57
|
-
npx dacty-launch
|
|
58
|
-
|
|
59
|
-
# Your agent and token are now live!
|
|
60
|
-
```
|
|
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. **Initializes Clanker SDK** with viem wallet
|
|
67
|
-
4. **Calls deployToken()** with correct rewardsConfig structure
|
|
68
|
-
5. **Configures fee distribution** (80% Agent, 20% Dactyclaw)
|
|
69
|
-
6. **Returns token address** and deployment details
|
|
70
|
-
|
|
71
|
-
## Fee Distribution
|
|
72
|
-
|
|
73
|
-
All tokens launched with `dacty-launch` follow standard distribution:
|
|
74
|
-
|
|
75
|
-
- **80%** ā Your Agent Wallet
|
|
76
|
-
- **20%** ā Dactyclaw Protocol
|
|
77
|
-
|
|
78
|
-
Fees are automatically distributed from every trade on Clanker.
|
|
79
|
-
|
|
80
|
-
## Requirements
|
|
81
|
-
|
|
82
|
-
- Node.js 18+
|
|
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.
|
|
105
|
-
|
|
106
|
-
### "Insufficient gas"
|
|
107
|
-
Ensure your wallet has at least 0.0005 ETH on Base network.
|
|
108
|
-
|
|
109
|
-
### "Transaction failed"
|
|
110
|
-
Check that your private key is correct and wallet has sufficient balance.
|
|
111
|
-
|
|
112
|
-
## License
|
|
113
|
-
|
|
114
|
-
MIT
|
|
115
|
-
|
|
116
|
-
## Support
|
|
117
|
-
|
|
118
|
-
For issues and questions:
|
|
119
|
-
- [Dactyclaw GitHub](https://github.com/dactyclaw/dactyclaw)
|
|
120
|
-
- [Dactyclaw Documentation](https://dactyclaw.dev)
|
|
121
|
-
- [Clanker Documentation](https://clanker.gitbook.io/clanker-documentation)
|
|
122
|
-
|
|
123
|
-
## Contributing
|
|
124
|
-
|
|
125
|
-
Contributions welcome! Please submit a Pull Request.
|
package/bin/dacty-launch.mjs
DELETED
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import fs from 'fs';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
import { fileURLToPath } from 'url';
|
|
6
|
-
import readline from 'readline';
|
|
7
|
-
import crypto from 'crypto';
|
|
8
|
-
|
|
9
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
-
const __dirname = path.dirname(__filename);
|
|
11
|
-
|
|
12
|
-
const rl = readline.createInterface({
|
|
13
|
-
input: process.stdin,
|
|
14
|
-
output: process.stdout,
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
function question(prompt) {
|
|
18
|
-
return new Promise((resolve) => {
|
|
19
|
-
rl.question(prompt, (answer) => {
|
|
20
|
-
resolve(answer);
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Find agent.config.json in current directory or subdirectories
|
|
26
|
-
function findAgentConfig(startPath = process.cwd()) {
|
|
27
|
-
// Check current directory first
|
|
28
|
-
const currentPath = path.join(startPath, 'agent.config.json');
|
|
29
|
-
if (fs.existsSync(currentPath)) {
|
|
30
|
-
return currentPath;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Check subdirectories (one level deep)
|
|
34
|
-
try {
|
|
35
|
-
const entries = fs.readdirSync(startPath, { withFileTypes: true });
|
|
36
|
-
for (const entry of entries) {
|
|
37
|
-
if (entry.isDirectory() && !entry.name.startsWith('.')) {
|
|
38
|
-
const subPath = path.join(startPath, entry.name, 'agent.config.json');
|
|
39
|
-
if (fs.existsSync(subPath)) {
|
|
40
|
-
return subPath;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
} catch (error) {
|
|
45
|
-
// Ignore read errors
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async function main() {
|
|
52
|
-
console.log('\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
53
|
-
console.log('ā DACTYCLAW - Token Launch ā');
|
|
54
|
-
console.log('ā Powered by Clanker v4.0.0 ā');
|
|
55
|
-
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n');
|
|
56
|
-
|
|
57
|
-
// Find agent.config.json (current dir or subdirectories)
|
|
58
|
-
const agentConfigPath = findAgentConfig();
|
|
59
|
-
if (!agentConfigPath) {
|
|
60
|
-
console.error('ā Error: agent.config.json not found!');
|
|
61
|
-
console.error(' Please run `npx dacty-create` first to create an agent.');
|
|
62
|
-
process.exit(1);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Load agent configuration
|
|
66
|
-
const agentConfig = JSON.parse(fs.readFileSync(agentConfigPath, 'utf-8'));
|
|
67
|
-
console.log(`ā Agent loaded: ${agentConfig.name} (DNA: ${agentConfig.dna})`);
|
|
68
|
-
console.log(`ā Wallet: ${agentConfig.wallet}\n`);
|
|
69
|
-
|
|
70
|
-
// Check if .env exists with private key (same directory as agent.config.json)
|
|
71
|
-
const agentDir = path.dirname(agentConfigPath);
|
|
72
|
-
const envPath = path.join(agentDir, '.env');
|
|
73
|
-
if (!fs.existsSync(envPath)) {
|
|
74
|
-
console.error('ā Error: .env file not found!');
|
|
75
|
-
console.error(' Private key should be in .env file.');
|
|
76
|
-
process.exit(1);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const envContent = fs.readFileSync(envPath, 'utf-8');
|
|
80
|
-
process.chdir(agentDir); // Change to agent directory for token config save
|
|
81
|
-
const privateKeyMatch = envContent.match(/AGENT_PRIVATE_KEY=(.+)/);
|
|
82
|
-
if (!privateKeyMatch) {
|
|
83
|
-
console.error('ā Error: AGENT_PRIVATE_KEY not found in .env file!');
|
|
84
|
-
process.exit(1);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Parse private key: remove quotes, newlines, and trim whitespace
|
|
88
|
-
let privateKey = privateKeyMatch[1]
|
|
89
|
-
.trim() // Remove leading/trailing whitespace
|
|
90
|
-
.replace(/\r?\n/g, '') // Remove newlines
|
|
91
|
-
.replace(/^["']|["']$/g, '') // Remove surrounding quotes
|
|
92
|
-
.trim(); // Trim again after removing quotes
|
|
93
|
-
console.log('ā Private key loaded from .env\n');
|
|
94
|
-
|
|
95
|
-
// Get token details from user
|
|
96
|
-
const tokenName = await question('Token Name: ');
|
|
97
|
-
const tokenSymbol = await question('Token Symbol: ');
|
|
98
|
-
const initialSupply = '1000000000'; // Default supply
|
|
99
|
-
|
|
100
|
-
console.log('\nš Configuration:');
|
|
101
|
-
console.log(` Name: ${tokenName}`);
|
|
102
|
-
console.log(` Symbol: ${tokenSymbol}`);
|
|
103
|
-
console.log(` Supply: ${initialSupply}`);
|
|
104
|
-
console.log(` Agent Wallet: ${agentConfig.wallet}`);
|
|
105
|
-
console.log(` Fee Distribution: 80% Agent, 20% Clanker\n`);
|
|
106
|
-
|
|
107
|
-
try {
|
|
108
|
-
console.log('š Deploying token via Clanker API...');
|
|
109
|
-
|
|
110
|
-
// Generate unique request key
|
|
111
|
-
const requestKey = crypto.randomBytes(16).toString('hex');
|
|
112
|
-
|
|
113
|
-
// Prepare deployment payload according to Clanker v4 API spec
|
|
114
|
-
const deploymentPayload = {
|
|
115
|
-
token: {
|
|
116
|
-
name: tokenName,
|
|
117
|
-
symbol: tokenSymbol,
|
|
118
|
-
tokenAdmin: agentConfig.wallet,
|
|
119
|
-
description: `${tokenName} - Created with DACTYCLAW`,
|
|
120
|
-
requestKey: requestKey,
|
|
121
|
-
},
|
|
122
|
-
rewards: [
|
|
123
|
-
{
|
|
124
|
-
admin: agentConfig.wallet,
|
|
125
|
-
recipient: agentConfig.wallet,
|
|
126
|
-
allocation: 80,
|
|
127
|
-
rewardsToken: 'Both',
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
admin: '0x0000000000000000000000000000000000000000',
|
|
131
|
-
recipient: '0x0000000000000000000000000000000000000000',
|
|
132
|
-
allocation: 20,
|
|
133
|
-
rewardsToken: 'Both',
|
|
134
|
-
},
|
|
135
|
-
],
|
|
136
|
-
pool: {
|
|
137
|
-
type: 'standard',
|
|
138
|
-
pairedToken: '0x4200000000000000000000000000000000000006', // WETH on Base
|
|
139
|
-
initialMarketCap: 10,
|
|
140
|
-
},
|
|
141
|
-
fees: {
|
|
142
|
-
type: 'static',
|
|
143
|
-
clankerFee: 1,
|
|
144
|
-
pairedFee: 1,
|
|
145
|
-
},
|
|
146
|
-
chainId: 8453, // Base network
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
// Call Clanker API
|
|
150
|
-
const response = await fetch('https://www.clanker.world/api/tokens/deploy', {
|
|
151
|
-
method: 'POST',
|
|
152
|
-
headers: {
|
|
153
|
-
'Content-Type': 'application/json',
|
|
154
|
-
'x-api-key': 'public', // Public endpoint doesn't require API key
|
|
155
|
-
},
|
|
156
|
-
body: JSON.stringify(deploymentPayload),
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
const result = await response.json();
|
|
160
|
-
|
|
161
|
-
if (!response.ok || !result.success) {
|
|
162
|
-
console.error('ā Deployment error:');
|
|
163
|
-
if (result.data) {
|
|
164
|
-
result.data.forEach(err => {
|
|
165
|
-
console.error(` - ${err.path?.join('.')}: ${err.message}`);
|
|
166
|
-
});
|
|
167
|
-
} else {
|
|
168
|
-
console.error(` ${result.error || result.message || 'Unknown error'}`);
|
|
169
|
-
}
|
|
170
|
-
process.exit(1);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const tokenAddress = result.expectedAddress;
|
|
174
|
-
|
|
175
|
-
console.log('ā
Token deployment enqueued!');
|
|
176
|
-
console.log(`\nš Token Details:`);
|
|
177
|
-
console.log(` Name: ${tokenName}`);
|
|
178
|
-
console.log(` Symbol: ${tokenSymbol}`);
|
|
179
|
-
console.log(` Supply: ${initialSupply}`);
|
|
180
|
-
console.log(` Expected Address: ${tokenAddress}`);
|
|
181
|
-
console.log(` Network: Base`);
|
|
182
|
-
console.log(` Explorer: https://basescan.org/token/${tokenAddress}`);
|
|
183
|
-
|
|
184
|
-
console.log(`\nš° Fee Distribution:`);
|
|
185
|
-
console.log(` Agent (${agentConfig.wallet}): 80%`);
|
|
186
|
-
console.log(` Clanker Protocol: 20%`);
|
|
187
|
-
|
|
188
|
-
// Save token configuration
|
|
189
|
-
const tokenConfig = {
|
|
190
|
-
name: tokenName,
|
|
191
|
-
symbol: tokenSymbol,
|
|
192
|
-
address: tokenAddress,
|
|
193
|
-
supply: initialSupply,
|
|
194
|
-
deployedAt: new Date().toISOString(),
|
|
195
|
-
network: 'base',
|
|
196
|
-
agentDNA: agentConfig.dna,
|
|
197
|
-
agentWallet: agentConfig.wallet,
|
|
198
|
-
fees: {
|
|
199
|
-
agent: 80,
|
|
200
|
-
clanker: 20,
|
|
201
|
-
},
|
|
202
|
-
requestKey: requestKey,
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
fs.writeFileSync(
|
|
206
|
-
path.join(agentDir, 'token.config.json'),
|
|
207
|
-
JSON.stringify(tokenConfig, null, 2)
|
|
208
|
-
);
|
|
209
|
-
|
|
210
|
-
console.log('\nā Token configuration saved to token.config.json');
|
|
211
|
-
|
|
212
|
-
// Update agent config with token info
|
|
213
|
-
agentConfig.token = {
|
|
214
|
-
name: tokenName,
|
|
215
|
-
symbol: tokenSymbol,
|
|
216
|
-
address: tokenAddress,
|
|
217
|
-
deployedAt: new Date().toISOString(),
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
fs.writeFileSync(agentConfigPath, JSON.stringify(agentConfig, null, 2));
|
|
221
|
-
console.log('ā Agent configuration updated');
|
|
222
|
-
|
|
223
|
-
console.log('\nš Ready to trade!');
|
|
224
|
-
console.log(`\nš± View on Clanker: https://clanker.world/token/${tokenAddress}`);
|
|
225
|
-
console.log(`š View on Basescan: https://basescan.org/token/${tokenAddress}`);
|
|
226
|
-
console.log(`\nš” Next steps:`);
|
|
227
|
-
console.log(` 1. Fund your wallet with ETH for gas fees`);
|
|
228
|
-
console.log(` 2. Monitor your token on Clanker.world`);
|
|
229
|
-
console.log(` 3. Check your earnings: npx dacty-status`);
|
|
230
|
-
|
|
231
|
-
rl.close();
|
|
232
|
-
} catch (error) {
|
|
233
|
-
console.error('ā Error:', error.message);
|
|
234
|
-
if (error.message.includes('fetch')) {
|
|
235
|
-
console.error(' Hint: Network error. Check your internet connection.');
|
|
236
|
-
}
|
|
237
|
-
rl.close();
|
|
238
|
-
process.exit(1);
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
main().catch((error) => {
|
|
243
|
-
console.error('ā Fatal error:', error);
|
|
244
|
-
process.exit(1);
|
|
245
|
-
});
|
package/build.mjs
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import fs from 'fs';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
import { fileURLToPath } from 'url';
|
|
6
|
-
|
|
7
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
8
|
-
|
|
9
|
-
// Create lib directory if it doesn't exist
|
|
10
|
-
const libDir = path.join(__dirname, 'lib');
|
|
11
|
-
if (!fs.existsSync(libDir)) {
|
|
12
|
-
fs.mkdirSync(libDir, { recursive: true });
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// Copy main entry point
|
|
16
|
-
const binContent = fs.readFileSync(path.join(__dirname, 'bin', 'dacty-launch.mjs'), 'utf-8');
|
|
17
|
-
fs.writeFileSync(path.join(libDir, 'index.mjs'), binContent);
|
|
18
|
-
|
|
19
|
-
console.log('ā Build complete');
|
package/lib/index.mjs
DELETED
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import fs from 'fs';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
import { fileURLToPath } from 'url';
|
|
6
|
-
import readline from 'readline';
|
|
7
|
-
import crypto from 'crypto';
|
|
8
|
-
|
|
9
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
-
const __dirname = path.dirname(__filename);
|
|
11
|
-
|
|
12
|
-
const rl = readline.createInterface({
|
|
13
|
-
input: process.stdin,
|
|
14
|
-
output: process.stdout,
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
function question(prompt) {
|
|
18
|
-
return new Promise((resolve) => {
|
|
19
|
-
rl.question(prompt, (answer) => {
|
|
20
|
-
resolve(answer);
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Find agent.config.json in current directory or subdirectories
|
|
26
|
-
function findAgentConfig(startPath = process.cwd()) {
|
|
27
|
-
// Check current directory first
|
|
28
|
-
const currentPath = path.join(startPath, 'agent.config.json');
|
|
29
|
-
if (fs.existsSync(currentPath)) {
|
|
30
|
-
return currentPath;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Check subdirectories (one level deep)
|
|
34
|
-
try {
|
|
35
|
-
const entries = fs.readdirSync(startPath, { withFileTypes: true });
|
|
36
|
-
for (const entry of entries) {
|
|
37
|
-
if (entry.isDirectory() && !entry.name.startsWith('.')) {
|
|
38
|
-
const subPath = path.join(startPath, entry.name, 'agent.config.json');
|
|
39
|
-
if (fs.existsSync(subPath)) {
|
|
40
|
-
return subPath;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
} catch (error) {
|
|
45
|
-
// Ignore read errors
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async function main() {
|
|
52
|
-
console.log('\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
53
|
-
console.log('ā DACTYCLAW - Token Launch ā');
|
|
54
|
-
console.log('ā Powered by Clanker v4.0.0 ā');
|
|
55
|
-
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n');
|
|
56
|
-
|
|
57
|
-
// Find agent.config.json (current dir or subdirectories)
|
|
58
|
-
const agentConfigPath = findAgentConfig();
|
|
59
|
-
if (!agentConfigPath) {
|
|
60
|
-
console.error('ā Error: agent.config.json not found!');
|
|
61
|
-
console.error(' Please run `npx dacty-create` first to create an agent.');
|
|
62
|
-
process.exit(1);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Load agent configuration
|
|
66
|
-
const agentConfig = JSON.parse(fs.readFileSync(agentConfigPath, 'utf-8'));
|
|
67
|
-
console.log(`ā Agent loaded: ${agentConfig.name} (DNA: ${agentConfig.dna})`);
|
|
68
|
-
console.log(`ā Wallet: ${agentConfig.wallet}\n`);
|
|
69
|
-
|
|
70
|
-
// Check if .env exists with private key (same directory as agent.config.json)
|
|
71
|
-
const agentDir = path.dirname(agentConfigPath);
|
|
72
|
-
const envPath = path.join(agentDir, '.env');
|
|
73
|
-
if (!fs.existsSync(envPath)) {
|
|
74
|
-
console.error('ā Error: .env file not found!');
|
|
75
|
-
console.error(' Private key should be in .env file.');
|
|
76
|
-
process.exit(1);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const envContent = fs.readFileSync(envPath, 'utf-8');
|
|
80
|
-
process.chdir(agentDir); // Change to agent directory for token config save
|
|
81
|
-
const privateKeyMatch = envContent.match(/AGENT_PRIVATE_KEY=(.+)/);
|
|
82
|
-
if (!privateKeyMatch) {
|
|
83
|
-
console.error('ā Error: AGENT_PRIVATE_KEY not found in .env file!');
|
|
84
|
-
process.exit(1);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Parse private key: remove quotes, newlines, and trim whitespace
|
|
88
|
-
let privateKey = privateKeyMatch[1]
|
|
89
|
-
.trim() // Remove leading/trailing whitespace
|
|
90
|
-
.replace(/\r?\n/g, '') // Remove newlines
|
|
91
|
-
.replace(/^["']|["']$/g, '') // Remove surrounding quotes
|
|
92
|
-
.trim(); // Trim again after removing quotes
|
|
93
|
-
console.log('ā Private key loaded from .env\n');
|
|
94
|
-
|
|
95
|
-
// Get token details from user
|
|
96
|
-
const tokenName = await question('Token Name: ');
|
|
97
|
-
const tokenSymbol = await question('Token Symbol: ');
|
|
98
|
-
const initialSupply = '1000000000'; // Default supply
|
|
99
|
-
|
|
100
|
-
console.log('\nš Configuration:');
|
|
101
|
-
console.log(` Name: ${tokenName}`);
|
|
102
|
-
console.log(` Symbol: ${tokenSymbol}`);
|
|
103
|
-
console.log(` Supply: ${initialSupply}`);
|
|
104
|
-
console.log(` Agent Wallet: ${agentConfig.wallet}`);
|
|
105
|
-
console.log(` Fee Distribution: 80% Agent, 20% Clanker\n`);
|
|
106
|
-
|
|
107
|
-
try {
|
|
108
|
-
console.log('š Deploying token via Clanker API...');
|
|
109
|
-
|
|
110
|
-
// Generate unique request key
|
|
111
|
-
const requestKey = crypto.randomBytes(16).toString('hex');
|
|
112
|
-
|
|
113
|
-
// Prepare deployment payload according to Clanker v4 API spec
|
|
114
|
-
const deploymentPayload = {
|
|
115
|
-
token: {
|
|
116
|
-
name: tokenName,
|
|
117
|
-
symbol: tokenSymbol,
|
|
118
|
-
tokenAdmin: agentConfig.wallet,
|
|
119
|
-
description: `${tokenName} - Created with DACTYCLAW`,
|
|
120
|
-
requestKey: requestKey,
|
|
121
|
-
},
|
|
122
|
-
rewards: [
|
|
123
|
-
{
|
|
124
|
-
admin: agentConfig.wallet,
|
|
125
|
-
recipient: agentConfig.wallet,
|
|
126
|
-
allocation: 80,
|
|
127
|
-
rewardsToken: 'Both',
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
admin: '0x0000000000000000000000000000000000000000',
|
|
131
|
-
recipient: '0x0000000000000000000000000000000000000000',
|
|
132
|
-
allocation: 20,
|
|
133
|
-
rewardsToken: 'Both',
|
|
134
|
-
},
|
|
135
|
-
],
|
|
136
|
-
pool: {
|
|
137
|
-
type: 'standard',
|
|
138
|
-
pairedToken: '0x4200000000000000000000000000000000000006', // WETH on Base
|
|
139
|
-
initialMarketCap: 10,
|
|
140
|
-
},
|
|
141
|
-
fees: {
|
|
142
|
-
type: 'static',
|
|
143
|
-
clankerFee: 1,
|
|
144
|
-
pairedFee: 1,
|
|
145
|
-
},
|
|
146
|
-
chainId: 8453, // Base network
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
// Call Clanker API
|
|
150
|
-
const response = await fetch('https://www.clanker.world/api/tokens/deploy', {
|
|
151
|
-
method: 'POST',
|
|
152
|
-
headers: {
|
|
153
|
-
'Content-Type': 'application/json',
|
|
154
|
-
'x-api-key': 'public', // Public endpoint doesn't require API key
|
|
155
|
-
},
|
|
156
|
-
body: JSON.stringify(deploymentPayload),
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
const result = await response.json();
|
|
160
|
-
|
|
161
|
-
if (!response.ok || !result.success) {
|
|
162
|
-
console.error('ā Deployment error:');
|
|
163
|
-
if (result.data) {
|
|
164
|
-
result.data.forEach(err => {
|
|
165
|
-
console.error(` - ${err.path?.join('.')}: ${err.message}`);
|
|
166
|
-
});
|
|
167
|
-
} else {
|
|
168
|
-
console.error(` ${result.error || result.message || 'Unknown error'}`);
|
|
169
|
-
}
|
|
170
|
-
process.exit(1);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const tokenAddress = result.expectedAddress;
|
|
174
|
-
|
|
175
|
-
console.log('ā
Token deployment enqueued!');
|
|
176
|
-
console.log(`\nš Token Details:`);
|
|
177
|
-
console.log(` Name: ${tokenName}`);
|
|
178
|
-
console.log(` Symbol: ${tokenSymbol}`);
|
|
179
|
-
console.log(` Supply: ${initialSupply}`);
|
|
180
|
-
console.log(` Expected Address: ${tokenAddress}`);
|
|
181
|
-
console.log(` Network: Base`);
|
|
182
|
-
console.log(` Explorer: https://basescan.org/token/${tokenAddress}`);
|
|
183
|
-
|
|
184
|
-
console.log(`\nš° Fee Distribution:`);
|
|
185
|
-
console.log(` Agent (${agentConfig.wallet}): 80%`);
|
|
186
|
-
console.log(` Clanker Protocol: 20%`);
|
|
187
|
-
|
|
188
|
-
// Save token configuration
|
|
189
|
-
const tokenConfig = {
|
|
190
|
-
name: tokenName,
|
|
191
|
-
symbol: tokenSymbol,
|
|
192
|
-
address: tokenAddress,
|
|
193
|
-
supply: initialSupply,
|
|
194
|
-
deployedAt: new Date().toISOString(),
|
|
195
|
-
network: 'base',
|
|
196
|
-
agentDNA: agentConfig.dna,
|
|
197
|
-
agentWallet: agentConfig.wallet,
|
|
198
|
-
fees: {
|
|
199
|
-
agent: 80,
|
|
200
|
-
clanker: 20,
|
|
201
|
-
},
|
|
202
|
-
requestKey: requestKey,
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
fs.writeFileSync(
|
|
206
|
-
path.join(agentDir, 'token.config.json'),
|
|
207
|
-
JSON.stringify(tokenConfig, null, 2)
|
|
208
|
-
);
|
|
209
|
-
|
|
210
|
-
console.log('\nā Token configuration saved to token.config.json');
|
|
211
|
-
|
|
212
|
-
// Update agent config with token info
|
|
213
|
-
agentConfig.token = {
|
|
214
|
-
name: tokenName,
|
|
215
|
-
symbol: tokenSymbol,
|
|
216
|
-
address: tokenAddress,
|
|
217
|
-
deployedAt: new Date().toISOString(),
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
fs.writeFileSync(agentConfigPath, JSON.stringify(agentConfig, null, 2));
|
|
221
|
-
console.log('ā Agent configuration updated');
|
|
222
|
-
|
|
223
|
-
console.log('\nš Ready to trade!');
|
|
224
|
-
console.log(`\nš± View on Clanker: https://clanker.world/token/${tokenAddress}`);
|
|
225
|
-
console.log(`š View on Basescan: https://basescan.org/token/${tokenAddress}`);
|
|
226
|
-
console.log(`\nš” Next steps:`);
|
|
227
|
-
console.log(` 1. Fund your wallet with ETH for gas fees`);
|
|
228
|
-
console.log(` 2. Monitor your token on Clanker.world`);
|
|
229
|
-
console.log(` 3. Check your earnings: npx dacty-status`);
|
|
230
|
-
|
|
231
|
-
rl.close();
|
|
232
|
-
} catch (error) {
|
|
233
|
-
console.error('ā Error:', error.message);
|
|
234
|
-
if (error.message.includes('fetch')) {
|
|
235
|
-
console.error(' Hint: Network error. Check your internet connection.');
|
|
236
|
-
}
|
|
237
|
-
rl.close();
|
|
238
|
-
process.exit(1);
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
main().catch((error) => {
|
|
243
|
-
console.error('ā Fatal error:', error);
|
|
244
|
-
process.exit(1);
|
|
245
|
-
});
|