dacty-launch 1.4.5 ā 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 -258
- package/build.mjs +0 -19
- package/lib/index.mjs +0 -258
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,258 +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 { Clanker } from 'clanker-sdk/v4';
|
|
8
|
-
import { createWalletClient, createPublicClient, http } from 'viem';
|
|
9
|
-
import { privateKeyToAccount } from 'viem/accounts';
|
|
10
|
-
import { base } from 'viem/chains';
|
|
11
|
-
|
|
12
|
-
// Polyfill fetch for Node.js - use undici
|
|
13
|
-
if (typeof globalThis.fetch === 'undefined') {
|
|
14
|
-
const { fetch: undiciFetch } = await import('undici');
|
|
15
|
-
globalThis.fetch = undiciFetch;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
19
|
-
const __dirname = path.dirname(__filename);
|
|
20
|
-
|
|
21
|
-
const rl = readline.createInterface({
|
|
22
|
-
input: process.stdin,
|
|
23
|
-
output: process.stdout,
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
function question(prompt) {
|
|
27
|
-
return new Promise((resolve) => {
|
|
28
|
-
rl.question(prompt, (answer) => {
|
|
29
|
-
resolve(answer);
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Find agent.config.json in current directory or subdirectories
|
|
35
|
-
function findAgentConfig(startPath = process.cwd()) {
|
|
36
|
-
// Check current directory first
|
|
37
|
-
const currentPath = path.join(startPath, 'agent.config.json');
|
|
38
|
-
if (fs.existsSync(currentPath)) {
|
|
39
|
-
return currentPath;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Check subdirectories (one level deep)
|
|
43
|
-
try {
|
|
44
|
-
const entries = fs.readdirSync(startPath, { withFileTypes: true });
|
|
45
|
-
for (const entry of entries) {
|
|
46
|
-
if (entry.isDirectory() && !entry.name.startsWith('.')) {
|
|
47
|
-
const subPath = path.join(startPath, entry.name, 'agent.config.json');
|
|
48
|
-
if (fs.existsSync(subPath)) {
|
|
49
|
-
return subPath;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
} catch (error) {
|
|
54
|
-
// Ignore read errors
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return null;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
async function main() {
|
|
61
|
-
console.log('\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
62
|
-
console.log('ā DACTYCLAW - Token Launch ā');
|
|
63
|
-
console.log('ā Powered by Clanker v4.0.0 ā');
|
|
64
|
-
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n');
|
|
65
|
-
|
|
66
|
-
// Find agent.config.json (current dir or subdirectories)
|
|
67
|
-
const agentConfigPath = findAgentConfig();
|
|
68
|
-
if (!agentConfigPath) {
|
|
69
|
-
console.error('ā Error: agent.config.json not found!');
|
|
70
|
-
console.error(' Please run `npx dacty-create` first to create an agent.');
|
|
71
|
-
process.exit(1);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Load agent configuration
|
|
75
|
-
const agentConfig = JSON.parse(fs.readFileSync(agentConfigPath, 'utf-8'));
|
|
76
|
-
console.log(`ā Agent loaded: ${agentConfig.name} (DNA: ${agentConfig.dna})`);
|
|
77
|
-
console.log(`ā Wallet: ${agentConfig.wallet}\n`);
|
|
78
|
-
|
|
79
|
-
// Check if .env exists with private key (same directory as agent.config.json)
|
|
80
|
-
const agentDir = path.dirname(agentConfigPath);
|
|
81
|
-
const envPath = path.join(agentDir, '.env');
|
|
82
|
-
if (!fs.existsSync(envPath)) {
|
|
83
|
-
console.error('ā Error: .env file not found!');
|
|
84
|
-
console.error(' Private key should be in .env file.');
|
|
85
|
-
process.exit(1);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const envContent = fs.readFileSync(envPath, 'utf-8');
|
|
89
|
-
process.chdir(agentDir); // Change to agent directory for token config save
|
|
90
|
-
const privateKeyMatch = envContent.match(/AGENT_PRIVATE_KEY=(.+)/);
|
|
91
|
-
if (!privateKeyMatch) {
|
|
92
|
-
console.error('ā Error: AGENT_PRIVATE_KEY not found in .env file!');
|
|
93
|
-
process.exit(1);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Parse private key: remove quotes, newlines, and trim whitespace
|
|
97
|
-
let privateKey = privateKeyMatch[1]
|
|
98
|
-
.trim() // Remove leading/trailing whitespace
|
|
99
|
-
.replace(/\r?\n/g, '') // Remove newlines
|
|
100
|
-
.replace(/^["']|["']$/g, '') // Remove surrounding quotes
|
|
101
|
-
.trim(); // Trim again after removing quotes
|
|
102
|
-
console.log('ā Private key loaded from .env\n');
|
|
103
|
-
|
|
104
|
-
// Get token details from user
|
|
105
|
-
const tokenName = await question('Token Name: ');
|
|
106
|
-
const tokenSymbol = await question('Token Symbol: ');
|
|
107
|
-
const initialSupply = '1000000000'; // Default supply
|
|
108
|
-
|
|
109
|
-
console.log('\nš Configuration:');
|
|
110
|
-
console.log(` Name: ${tokenName}`);
|
|
111
|
-
console.log(` Symbol: ${tokenSymbol}`);
|
|
112
|
-
console.log(` Supply: ${initialSupply}`);
|
|
113
|
-
console.log(` Agent Wallet: ${agentConfig.wallet}`);
|
|
114
|
-
console.log(` Fee Distribution: 80% Agent, 20% Clanker\n`);
|
|
115
|
-
|
|
116
|
-
// Clanker protocol addresses (for interface rewards)
|
|
117
|
-
// Using Clanker's official fee recipient
|
|
118
|
-
const CLANKER_INTERFACE_ADMIN = agentConfig.wallet; // Can be agent or clanker
|
|
119
|
-
const CLANKER_INTERFACE_RECIPIENT = agentConfig.wallet; // Clanker fees go to agent for now
|
|
120
|
-
|
|
121
|
-
try {
|
|
122
|
-
console.log('š Initializing Clanker SDK...');
|
|
123
|
-
|
|
124
|
-
// Setup viem clients with explicit fetch
|
|
125
|
-
const account = privateKeyToAccount(privateKey);
|
|
126
|
-
const publicClient = createPublicClient({
|
|
127
|
-
chain: base,
|
|
128
|
-
transport: http(undefined, { fetch: globalThis.fetch })
|
|
129
|
-
});
|
|
130
|
-
const walletClient = createWalletClient({
|
|
131
|
-
account,
|
|
132
|
-
chain: base,
|
|
133
|
-
transport: http(undefined, { fetch: globalThis.fetch })
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
// Initialize Clanker SDK
|
|
137
|
-
const clanker = new Clanker({
|
|
138
|
-
publicClient,
|
|
139
|
-
wallet: walletClient,
|
|
140
|
-
fetch: globalThis.fetch,
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
console.log('ā Clanker SDK initialized');
|
|
144
|
-
console.log('ā Connected to Base network');
|
|
145
|
-
console.log('ā Account:', account.address);
|
|
146
|
-
|
|
147
|
-
console.log('\nš Deploying token...');
|
|
148
|
-
|
|
149
|
-
// Deploy token with 80/20 fee split
|
|
150
|
-
// Using Clanker v4 deploy() method with correct token structure
|
|
151
|
-
const { txHash, waitForTransaction } = await clanker.deploy({
|
|
152
|
-
name: tokenName,
|
|
153
|
-
symbol: tokenSymbol,
|
|
154
|
-
tokenAdmin: agentConfig.wallet,
|
|
155
|
-
rewards: {
|
|
156
|
-
recipients: [
|
|
157
|
-
{
|
|
158
|
-
recipient: agentConfig.wallet,
|
|
159
|
-
admin: agentConfig.wallet,
|
|
160
|
-
bps: 8000, // 80% to agent (basis points: 10000 = 100%)
|
|
161
|
-
token: 'Both', // Receive fees in both tokens
|
|
162
|
-
},
|
|
163
|
-
{
|
|
164
|
-
recipient: CLANKER_INTERFACE_RECIPIENT,
|
|
165
|
-
admin: CLANKER_INTERFACE_ADMIN,
|
|
166
|
-
bps: 2000, // 20% to clanker protocol
|
|
167
|
-
token: 'Both',
|
|
168
|
-
},
|
|
169
|
-
],
|
|
170
|
-
},
|
|
171
|
-
vanity: true, // Try to get vanity address with "b07" suffix
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
console.log(`ā Transaction submitted: ${txHash}`);
|
|
175
|
-
console.log('ā³ Waiting for confirmation...\n');
|
|
176
|
-
|
|
177
|
-
const result = await waitForTransaction();
|
|
178
|
-
|
|
179
|
-
if (result.error) {
|
|
180
|
-
console.error('ā Deployment error:', result.error);
|
|
181
|
-
process.exit(1);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const tokenAddress = result.address;
|
|
185
|
-
|
|
186
|
-
console.log('ā
Token deployed successfully!');
|
|
187
|
-
console.log(`\nš Token Details:`);
|
|
188
|
-
console.log(` Address: ${tokenAddress}`);
|
|
189
|
-
console.log(` Name: ${tokenName}`);
|
|
190
|
-
console.log(` Symbol: ${tokenSymbol}`);
|
|
191
|
-
console.log(` Supply: ${initialSupply}`);
|
|
192
|
-
console.log(` Network: Base`);
|
|
193
|
-
console.log(` Explorer: https://basescan.org/token/${tokenAddress}`);
|
|
194
|
-
|
|
195
|
-
console.log(`\nš° Fee Distribution:`);
|
|
196
|
-
console.log(` Agent (${agentConfig.wallet}): 80%`);
|
|
197
|
-
console.log(` Clanker Protocol: 20%`);
|
|
198
|
-
|
|
199
|
-
// Save token configuration
|
|
200
|
-
const tokenConfig = {
|
|
201
|
-
name: tokenName,
|
|
202
|
-
symbol: tokenSymbol,
|
|
203
|
-
address: tokenAddress,
|
|
204
|
-
supply: initialSupply,
|
|
205
|
-
deployedAt: new Date().toISOString(),
|
|
206
|
-
network: 'base',
|
|
207
|
-
agentDNA: agentConfig.dna,
|
|
208
|
-
agentWallet: agentConfig.wallet,
|
|
209
|
-
fees: {
|
|
210
|
-
agent: 80,
|
|
211
|
-
clanker: 20,
|
|
212
|
-
},
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
fs.writeFileSync(
|
|
216
|
-
path.join(agentDir, 'token.config.json'),
|
|
217
|
-
JSON.stringify(tokenConfig, null, 2)
|
|
218
|
-
);
|
|
219
|
-
|
|
220
|
-
console.log('\nā Token configuration saved to token.config.json');
|
|
221
|
-
|
|
222
|
-
// Update agent config with token info
|
|
223
|
-
agentConfig.token = {
|
|
224
|
-
name: tokenName,
|
|
225
|
-
symbol: tokenSymbol,
|
|
226
|
-
address: tokenAddress,
|
|
227
|
-
deployedAt: new Date().toISOString(),
|
|
228
|
-
};
|
|
229
|
-
|
|
230
|
-
fs.writeFileSync(agentConfigPath, JSON.stringify(agentConfig, null, 2));
|
|
231
|
-
console.log('ā Agent configuration updated');
|
|
232
|
-
|
|
233
|
-
console.log('\nš Ready to trade!');
|
|
234
|
-
console.log(`\nš± View on Clanker: https://clanker.world/token/${tokenAddress}`);
|
|
235
|
-
console.log(`š View on Basescan: https://basescan.org/token/${tokenAddress}`);
|
|
236
|
-
console.log(`\nš” Next steps:`);
|
|
237
|
-
console.log(` 1. Fund your wallet with ETH for gas fees`);
|
|
238
|
-
console.log(` 2. Monitor your token on Clanker.world`);
|
|
239
|
-
console.log(` 3. Check your earnings: npx dacty-status`);
|
|
240
|
-
|
|
241
|
-
rl.close();
|
|
242
|
-
} catch (error) {
|
|
243
|
-
console.error('ā Error:', error.message);
|
|
244
|
-
if (typeof error === 'object' && Array.isArray(error)) {
|
|
245
|
-
console.error(' Validation errors:');
|
|
246
|
-
error.forEach(e => console.error(` - ${e.path?.join('.')}: ${e.message}`));
|
|
247
|
-
} else if (error.message.includes('invalid private key')) {
|
|
248
|
-
console.error(' Hint: Check that AGENT_PRIVATE_KEY in .env is valid and properly formatted');
|
|
249
|
-
}
|
|
250
|
-
rl.close();
|
|
251
|
-
process.exit(1);
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
main().catch((error) => {
|
|
256
|
-
console.error('ā Fatal error:', error);
|
|
257
|
-
process.exit(1);
|
|
258
|
-
});
|
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,258 +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 { Clanker } from 'clanker-sdk/v4';
|
|
8
|
-
import { createWalletClient, createPublicClient, http } from 'viem';
|
|
9
|
-
import { privateKeyToAccount } from 'viem/accounts';
|
|
10
|
-
import { base } from 'viem/chains';
|
|
11
|
-
|
|
12
|
-
// Polyfill fetch for Node.js - use undici
|
|
13
|
-
if (typeof globalThis.fetch === 'undefined') {
|
|
14
|
-
const { fetch: undiciFetch } = await import('undici');
|
|
15
|
-
globalThis.fetch = undiciFetch;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
19
|
-
const __dirname = path.dirname(__filename);
|
|
20
|
-
|
|
21
|
-
const rl = readline.createInterface({
|
|
22
|
-
input: process.stdin,
|
|
23
|
-
output: process.stdout,
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
function question(prompt) {
|
|
27
|
-
return new Promise((resolve) => {
|
|
28
|
-
rl.question(prompt, (answer) => {
|
|
29
|
-
resolve(answer);
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Find agent.config.json in current directory or subdirectories
|
|
35
|
-
function findAgentConfig(startPath = process.cwd()) {
|
|
36
|
-
// Check current directory first
|
|
37
|
-
const currentPath = path.join(startPath, 'agent.config.json');
|
|
38
|
-
if (fs.existsSync(currentPath)) {
|
|
39
|
-
return currentPath;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Check subdirectories (one level deep)
|
|
43
|
-
try {
|
|
44
|
-
const entries = fs.readdirSync(startPath, { withFileTypes: true });
|
|
45
|
-
for (const entry of entries) {
|
|
46
|
-
if (entry.isDirectory() && !entry.name.startsWith('.')) {
|
|
47
|
-
const subPath = path.join(startPath, entry.name, 'agent.config.json');
|
|
48
|
-
if (fs.existsSync(subPath)) {
|
|
49
|
-
return subPath;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
} catch (error) {
|
|
54
|
-
// Ignore read errors
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return null;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
async function main() {
|
|
61
|
-
console.log('\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
62
|
-
console.log('ā DACTYCLAW - Token Launch ā');
|
|
63
|
-
console.log('ā Powered by Clanker v4.0.0 ā');
|
|
64
|
-
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n');
|
|
65
|
-
|
|
66
|
-
// Find agent.config.json (current dir or subdirectories)
|
|
67
|
-
const agentConfigPath = findAgentConfig();
|
|
68
|
-
if (!agentConfigPath) {
|
|
69
|
-
console.error('ā Error: agent.config.json not found!');
|
|
70
|
-
console.error(' Please run `npx dacty-create` first to create an agent.');
|
|
71
|
-
process.exit(1);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Load agent configuration
|
|
75
|
-
const agentConfig = JSON.parse(fs.readFileSync(agentConfigPath, 'utf-8'));
|
|
76
|
-
console.log(`ā Agent loaded: ${agentConfig.name} (DNA: ${agentConfig.dna})`);
|
|
77
|
-
console.log(`ā Wallet: ${agentConfig.wallet}\n`);
|
|
78
|
-
|
|
79
|
-
// Check if .env exists with private key (same directory as agent.config.json)
|
|
80
|
-
const agentDir = path.dirname(agentConfigPath);
|
|
81
|
-
const envPath = path.join(agentDir, '.env');
|
|
82
|
-
if (!fs.existsSync(envPath)) {
|
|
83
|
-
console.error('ā Error: .env file not found!');
|
|
84
|
-
console.error(' Private key should be in .env file.');
|
|
85
|
-
process.exit(1);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const envContent = fs.readFileSync(envPath, 'utf-8');
|
|
89
|
-
process.chdir(agentDir); // Change to agent directory for token config save
|
|
90
|
-
const privateKeyMatch = envContent.match(/AGENT_PRIVATE_KEY=(.+)/);
|
|
91
|
-
if (!privateKeyMatch) {
|
|
92
|
-
console.error('ā Error: AGENT_PRIVATE_KEY not found in .env file!');
|
|
93
|
-
process.exit(1);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Parse private key: remove quotes, newlines, and trim whitespace
|
|
97
|
-
let privateKey = privateKeyMatch[1]
|
|
98
|
-
.trim() // Remove leading/trailing whitespace
|
|
99
|
-
.replace(/\r?\n/g, '') // Remove newlines
|
|
100
|
-
.replace(/^["']|["']$/g, '') // Remove surrounding quotes
|
|
101
|
-
.trim(); // Trim again after removing quotes
|
|
102
|
-
console.log('ā Private key loaded from .env\n');
|
|
103
|
-
|
|
104
|
-
// Get token details from user
|
|
105
|
-
const tokenName = await question('Token Name: ');
|
|
106
|
-
const tokenSymbol = await question('Token Symbol: ');
|
|
107
|
-
const initialSupply = '1000000000'; // Default supply
|
|
108
|
-
|
|
109
|
-
console.log('\nš Configuration:');
|
|
110
|
-
console.log(` Name: ${tokenName}`);
|
|
111
|
-
console.log(` Symbol: ${tokenSymbol}`);
|
|
112
|
-
console.log(` Supply: ${initialSupply}`);
|
|
113
|
-
console.log(` Agent Wallet: ${agentConfig.wallet}`);
|
|
114
|
-
console.log(` Fee Distribution: 80% Agent, 20% Clanker\n`);
|
|
115
|
-
|
|
116
|
-
// Clanker protocol addresses (for interface rewards)
|
|
117
|
-
// Using Clanker's official fee recipient
|
|
118
|
-
const CLANKER_INTERFACE_ADMIN = agentConfig.wallet; // Can be agent or clanker
|
|
119
|
-
const CLANKER_INTERFACE_RECIPIENT = agentConfig.wallet; // Clanker fees go to agent for now
|
|
120
|
-
|
|
121
|
-
try {
|
|
122
|
-
console.log('š Initializing Clanker SDK...');
|
|
123
|
-
|
|
124
|
-
// Setup viem clients with explicit fetch
|
|
125
|
-
const account = privateKeyToAccount(privateKey);
|
|
126
|
-
const publicClient = createPublicClient({
|
|
127
|
-
chain: base,
|
|
128
|
-
transport: http(undefined, { fetch: globalThis.fetch })
|
|
129
|
-
});
|
|
130
|
-
const walletClient = createWalletClient({
|
|
131
|
-
account,
|
|
132
|
-
chain: base,
|
|
133
|
-
transport: http(undefined, { fetch: globalThis.fetch })
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
// Initialize Clanker SDK
|
|
137
|
-
const clanker = new Clanker({
|
|
138
|
-
publicClient,
|
|
139
|
-
wallet: walletClient,
|
|
140
|
-
fetch: globalThis.fetch,
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
console.log('ā Clanker SDK initialized');
|
|
144
|
-
console.log('ā Connected to Base network');
|
|
145
|
-
console.log('ā Account:', account.address);
|
|
146
|
-
|
|
147
|
-
console.log('\nš Deploying token...');
|
|
148
|
-
|
|
149
|
-
// Deploy token with 80/20 fee split
|
|
150
|
-
// Using Clanker v4 deploy() method with correct token structure
|
|
151
|
-
const { txHash, waitForTransaction } = await clanker.deploy({
|
|
152
|
-
name: tokenName,
|
|
153
|
-
symbol: tokenSymbol,
|
|
154
|
-
tokenAdmin: agentConfig.wallet,
|
|
155
|
-
rewards: {
|
|
156
|
-
recipients: [
|
|
157
|
-
{
|
|
158
|
-
recipient: agentConfig.wallet,
|
|
159
|
-
admin: agentConfig.wallet,
|
|
160
|
-
bps: 8000, // 80% to agent (basis points: 10000 = 100%)
|
|
161
|
-
token: 'Both', // Receive fees in both tokens
|
|
162
|
-
},
|
|
163
|
-
{
|
|
164
|
-
recipient: CLANKER_INTERFACE_RECIPIENT,
|
|
165
|
-
admin: CLANKER_INTERFACE_ADMIN,
|
|
166
|
-
bps: 2000, // 20% to clanker protocol
|
|
167
|
-
token: 'Both',
|
|
168
|
-
},
|
|
169
|
-
],
|
|
170
|
-
},
|
|
171
|
-
vanity: true, // Try to get vanity address with "b07" suffix
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
console.log(`ā Transaction submitted: ${txHash}`);
|
|
175
|
-
console.log('ā³ Waiting for confirmation...\n');
|
|
176
|
-
|
|
177
|
-
const result = await waitForTransaction();
|
|
178
|
-
|
|
179
|
-
if (result.error) {
|
|
180
|
-
console.error('ā Deployment error:', result.error);
|
|
181
|
-
process.exit(1);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const tokenAddress = result.address;
|
|
185
|
-
|
|
186
|
-
console.log('ā
Token deployed successfully!');
|
|
187
|
-
console.log(`\nš Token Details:`);
|
|
188
|
-
console.log(` Address: ${tokenAddress}`);
|
|
189
|
-
console.log(` Name: ${tokenName}`);
|
|
190
|
-
console.log(` Symbol: ${tokenSymbol}`);
|
|
191
|
-
console.log(` Supply: ${initialSupply}`);
|
|
192
|
-
console.log(` Network: Base`);
|
|
193
|
-
console.log(` Explorer: https://basescan.org/token/${tokenAddress}`);
|
|
194
|
-
|
|
195
|
-
console.log(`\nš° Fee Distribution:`);
|
|
196
|
-
console.log(` Agent (${agentConfig.wallet}): 80%`);
|
|
197
|
-
console.log(` Clanker Protocol: 20%`);
|
|
198
|
-
|
|
199
|
-
// Save token configuration
|
|
200
|
-
const tokenConfig = {
|
|
201
|
-
name: tokenName,
|
|
202
|
-
symbol: tokenSymbol,
|
|
203
|
-
address: tokenAddress,
|
|
204
|
-
supply: initialSupply,
|
|
205
|
-
deployedAt: new Date().toISOString(),
|
|
206
|
-
network: 'base',
|
|
207
|
-
agentDNA: agentConfig.dna,
|
|
208
|
-
agentWallet: agentConfig.wallet,
|
|
209
|
-
fees: {
|
|
210
|
-
agent: 80,
|
|
211
|
-
clanker: 20,
|
|
212
|
-
},
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
fs.writeFileSync(
|
|
216
|
-
path.join(agentDir, 'token.config.json'),
|
|
217
|
-
JSON.stringify(tokenConfig, null, 2)
|
|
218
|
-
);
|
|
219
|
-
|
|
220
|
-
console.log('\nā Token configuration saved to token.config.json');
|
|
221
|
-
|
|
222
|
-
// Update agent config with token info
|
|
223
|
-
agentConfig.token = {
|
|
224
|
-
name: tokenName,
|
|
225
|
-
symbol: tokenSymbol,
|
|
226
|
-
address: tokenAddress,
|
|
227
|
-
deployedAt: new Date().toISOString(),
|
|
228
|
-
};
|
|
229
|
-
|
|
230
|
-
fs.writeFileSync(agentConfigPath, JSON.stringify(agentConfig, null, 2));
|
|
231
|
-
console.log('ā Agent configuration updated');
|
|
232
|
-
|
|
233
|
-
console.log('\nš Ready to trade!');
|
|
234
|
-
console.log(`\nš± View on Clanker: https://clanker.world/token/${tokenAddress}`);
|
|
235
|
-
console.log(`š View on Basescan: https://basescan.org/token/${tokenAddress}`);
|
|
236
|
-
console.log(`\nš” Next steps:`);
|
|
237
|
-
console.log(` 1. Fund your wallet with ETH for gas fees`);
|
|
238
|
-
console.log(` 2. Monitor your token on Clanker.world`);
|
|
239
|
-
console.log(` 3. Check your earnings: npx dacty-status`);
|
|
240
|
-
|
|
241
|
-
rl.close();
|
|
242
|
-
} catch (error) {
|
|
243
|
-
console.error('ā Error:', error.message);
|
|
244
|
-
if (typeof error === 'object' && Array.isArray(error)) {
|
|
245
|
-
console.error(' Validation errors:');
|
|
246
|
-
error.forEach(e => console.error(` - ${e.path?.join('.')}: ${e.message}`));
|
|
247
|
-
} else if (error.message.includes('invalid private key')) {
|
|
248
|
-
console.error(' Hint: Check that AGENT_PRIVATE_KEY in .env is valid and properly formatted');
|
|
249
|
-
}
|
|
250
|
-
rl.close();
|
|
251
|
-
process.exit(1);
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
main().catch((error) => {
|
|
256
|
-
console.error('ā Fatal error:', error);
|
|
257
|
-
process.exit(1);
|
|
258
|
-
});
|