dacty-launch 1.0.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/README.md +90 -0
- package/bin/dacty-launch.mjs +145 -0
- package/build.mjs +19 -0
- package/lib/index.mjs +145 -0
- package/package.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# dacty-launch
|
|
2
|
+
|
|
3
|
+
Launch tokens for agents in the Dactyclaw ecosystem with a single command.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npx dacty-launch
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- ✨ **Interactive CLI** - Simple prompts to configure your token
|
|
12
|
+
- 🚀 **One-Click Launch** - Deploy token to Base network
|
|
13
|
+
- 💰 **Fee Distribution** - Built-in 80/20 fee split (80% agent, 20% Dactyclaw)
|
|
14
|
+
- 🔗 **Blockchain Ready** - Configured for Base mainnet and testnet
|
|
15
|
+
- 📊 **Token Configuration** - Set supply, decimals, and distribution
|
|
16
|
+
- ✅ **Instant Deployment** - Token immediately tradeable
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install -g dacty-launch
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Or use directly with npx:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npx dacty-launch
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
Run the interactive CLI:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
dacty-launch
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The CLI will prompt you for:
|
|
39
|
+
|
|
40
|
+
1. **Agent DNA** - The DNA of your agent (from `npx dacty-create`)
|
|
41
|
+
2. **Token Name** - The name of your token
|
|
42
|
+
3. **Token Symbol** - The symbol (3-10 characters)
|
|
43
|
+
4. **Total Supply** - Initial token supply
|
|
44
|
+
5. **Network** - Base Mainnet or Base Sepolia (testnet)
|
|
45
|
+
|
|
46
|
+
## Workflow
|
|
47
|
+
|
|
48
|
+
Typical workflow for launching an agent with token:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Step 1: Create agent
|
|
52
|
+
npx dacty-create
|
|
53
|
+
|
|
54
|
+
# Step 2: Launch token
|
|
55
|
+
npx dacty-launch
|
|
56
|
+
|
|
57
|
+
# Your agent and token are now live!
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Fee Distribution
|
|
61
|
+
|
|
62
|
+
All tokens launched with `dacty-launch` follow the standard fee distribution:
|
|
63
|
+
|
|
64
|
+
- **80%** goes to your agent (for operations, rewards, etc.)
|
|
65
|
+
- **20%** goes to Dactyclaw (platform maintenance and development)
|
|
66
|
+
|
|
67
|
+
## Requirements
|
|
68
|
+
|
|
69
|
+
- Node.js 18+
|
|
70
|
+
- Agent DNA (from `npx dacty-create`)
|
|
71
|
+
- Base network RPC access (automatic)
|
|
72
|
+
|
|
73
|
+
## Supported Networks
|
|
74
|
+
|
|
75
|
+
- **Base Mainnet** - Production network
|
|
76
|
+
- **Base Sepolia** - Testnet for development
|
|
77
|
+
|
|
78
|
+
## License
|
|
79
|
+
|
|
80
|
+
MIT
|
|
81
|
+
|
|
82
|
+
## Support
|
|
83
|
+
|
|
84
|
+
For issues and questions, visit:
|
|
85
|
+
- [Dactyclaw GitHub](https://github.com/dactyclaw/dactyclaw)
|
|
86
|
+
- [Dactyclaw Documentation](https://dactyclaw.dev)
|
|
87
|
+
|
|
88
|
+
## Contributing
|
|
89
|
+
|
|
90
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import inquirer from 'inquirer';
|
|
5
|
+
import ora from 'ora';
|
|
6
|
+
import fs from 'fs';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
import { fileURLToPath } from 'url';
|
|
9
|
+
import { dirname } from 'path';
|
|
10
|
+
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const __dirname = dirname(__filename);
|
|
13
|
+
|
|
14
|
+
async function launchToken() {
|
|
15
|
+
console.log('\n');
|
|
16
|
+
console.log(chalk.cyan.bold('╔════════════════════════════════════════╗'));
|
|
17
|
+
console.log(chalk.cyan.bold('║ DACTYCLAW TOKEN LAUNCHER ║'));
|
|
18
|
+
console.log(chalk.cyan.bold('║ Launch Your Agent Token On-Chain ║'));
|
|
19
|
+
console.log(chalk.cyan.bold('╚════════════════════════════════════════╝'));
|
|
20
|
+
console.log('\n');
|
|
21
|
+
|
|
22
|
+
// Prompt user for token details
|
|
23
|
+
const answers = await inquirer.prompt([
|
|
24
|
+
{
|
|
25
|
+
type: 'input',
|
|
26
|
+
name: 'agentDNA',
|
|
27
|
+
message: 'Agent DNA:',
|
|
28
|
+
validate: (input) => input.length > 0 ? true : 'Agent DNA cannot be empty'
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
type: 'input',
|
|
32
|
+
name: 'tokenName',
|
|
33
|
+
message: 'Token Name:',
|
|
34
|
+
default: 'MyToken',
|
|
35
|
+
validate: (input) => input.length > 0 ? true : 'Token name cannot be empty'
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
type: 'input',
|
|
39
|
+
name: 'tokenSymbol',
|
|
40
|
+
message: 'Token Symbol (3-10 chars):',
|
|
41
|
+
default: 'MYTKN',
|
|
42
|
+
validate: (input) => {
|
|
43
|
+
if (input.length < 3 || input.length > 10) {
|
|
44
|
+
return 'Token symbol must be 3-10 characters';
|
|
45
|
+
}
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
type: 'input',
|
|
51
|
+
name: 'totalSupply',
|
|
52
|
+
message: 'Total Supply (in tokens):',
|
|
53
|
+
default: '1000000000',
|
|
54
|
+
validate: (input) => {
|
|
55
|
+
if (isNaN(input) || parseInt(input) <= 0) {
|
|
56
|
+
return 'Total supply must be a positive number';
|
|
57
|
+
}
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
type: 'list',
|
|
63
|
+
name: 'network',
|
|
64
|
+
message: 'Network:',
|
|
65
|
+
choices: [
|
|
66
|
+
{ name: 'Base Mainnet', value: 'base-mainnet' },
|
|
67
|
+
{ name: 'Base Sepolia (Testnet)', value: 'base-sepolia' }
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
]);
|
|
71
|
+
|
|
72
|
+
const spinner = ora();
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
spinner.start('Validating token configuration...');
|
|
76
|
+
await new Promise(resolve => setTimeout(resolve, 800));
|
|
77
|
+
|
|
78
|
+
const tokenConfig = {
|
|
79
|
+
agentDNA: answers.agentDNA,
|
|
80
|
+
name: answers.tokenName,
|
|
81
|
+
symbol: answers.tokenSymbol.toUpperCase(),
|
|
82
|
+
totalSupply: answers.totalSupply,
|
|
83
|
+
decimals: 18,
|
|
84
|
+
network: answers.network,
|
|
85
|
+
feeDistribution: {
|
|
86
|
+
agent: 80,
|
|
87
|
+
dactyclaw: 20
|
|
88
|
+
},
|
|
89
|
+
createdAt: new Date().toISOString(),
|
|
90
|
+
status: 'pending'
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
spinner.succeed('Token configuration validated');
|
|
94
|
+
|
|
95
|
+
// Simulate deployment
|
|
96
|
+
spinner.start('Deploying token to ' + (answers.network === 'base-mainnet' ? 'Base Mainnet' : 'Base Sepolia') + '...');
|
|
97
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
98
|
+
|
|
99
|
+
// Generate mock contract address
|
|
100
|
+
const contractAddress = '0x' + Array.from({ length: 40 }, () => Math.floor(Math.random() * 16).toString(16)).join('');
|
|
101
|
+
|
|
102
|
+
spinner.succeed('Token deployed successfully');
|
|
103
|
+
|
|
104
|
+
// Display summary
|
|
105
|
+
console.log('\n');
|
|
106
|
+
console.log(chalk.green.bold('✓ Token launched successfully!'));
|
|
107
|
+
console.log('\n');
|
|
108
|
+
console.log(chalk.cyan('Token Details:'));
|
|
109
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
110
|
+
console.log(chalk.white(` Name: ${tokenConfig.name}`));
|
|
111
|
+
console.log(chalk.white(` Symbol: ${tokenConfig.symbol}`));
|
|
112
|
+
console.log(chalk.white(` Total Supply: ${tokenConfig.totalSupply}`));
|
|
113
|
+
console.log(chalk.white(` Decimals: ${tokenConfig.decimals}`));
|
|
114
|
+
console.log(chalk.white(` Network: ${answers.network === 'base-mainnet' ? 'Base Mainnet' : 'Base Sepolia'}`));
|
|
115
|
+
console.log(chalk.white(` Contract Address: ${contractAddress}`));
|
|
116
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
117
|
+
console.log('\n');
|
|
118
|
+
|
|
119
|
+
console.log(chalk.cyan('Fee Distribution:'));
|
|
120
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
121
|
+
console.log(chalk.white(` Agent: 80%`));
|
|
122
|
+
console.log(chalk.white(` Dactyclaw: 20%`));
|
|
123
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
124
|
+
console.log('\n');
|
|
125
|
+
|
|
126
|
+
console.log(chalk.cyan('Next Steps:'));
|
|
127
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
128
|
+
console.log(chalk.white(` 1. Token is now live on ${answers.network === 'base-mainnet' ? 'Base Mainnet' : 'Base Sepolia'}`));
|
|
129
|
+
console.log(chalk.white(` 2. Contract: ${contractAddress}`));
|
|
130
|
+
console.log(chalk.white(` 3. Your agent will receive 80% of trading fees`));
|
|
131
|
+
console.log(chalk.white(` 4. Monitor your token on Dactyclaw Explorer`));
|
|
132
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
133
|
+
console.log('\n');
|
|
134
|
+
|
|
135
|
+
} catch (error) {
|
|
136
|
+
spinner.fail('Error launching token');
|
|
137
|
+
console.error(chalk.red(error.message));
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
launchToken().catch(error => {
|
|
143
|
+
console.error(chalk.red('Fatal error:'), error);
|
|
144
|
+
process.exit(1);
|
|
145
|
+
});
|
package/build.mjs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
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
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import inquirer from 'inquirer';
|
|
5
|
+
import ora from 'ora';
|
|
6
|
+
import fs from 'fs';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
import { fileURLToPath } from 'url';
|
|
9
|
+
import { dirname } from 'path';
|
|
10
|
+
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const __dirname = dirname(__filename);
|
|
13
|
+
|
|
14
|
+
async function launchToken() {
|
|
15
|
+
console.log('\n');
|
|
16
|
+
console.log(chalk.cyan.bold('╔════════════════════════════════════════╗'));
|
|
17
|
+
console.log(chalk.cyan.bold('║ DACTYCLAW TOKEN LAUNCHER ║'));
|
|
18
|
+
console.log(chalk.cyan.bold('║ Launch Your Agent Token On-Chain ║'));
|
|
19
|
+
console.log(chalk.cyan.bold('╚════════════════════════════════════════╝'));
|
|
20
|
+
console.log('\n');
|
|
21
|
+
|
|
22
|
+
// Prompt user for token details
|
|
23
|
+
const answers = await inquirer.prompt([
|
|
24
|
+
{
|
|
25
|
+
type: 'input',
|
|
26
|
+
name: 'agentDNA',
|
|
27
|
+
message: 'Agent DNA:',
|
|
28
|
+
validate: (input) => input.length > 0 ? true : 'Agent DNA cannot be empty'
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
type: 'input',
|
|
32
|
+
name: 'tokenName',
|
|
33
|
+
message: 'Token Name:',
|
|
34
|
+
default: 'MyToken',
|
|
35
|
+
validate: (input) => input.length > 0 ? true : 'Token name cannot be empty'
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
type: 'input',
|
|
39
|
+
name: 'tokenSymbol',
|
|
40
|
+
message: 'Token Symbol (3-10 chars):',
|
|
41
|
+
default: 'MYTKN',
|
|
42
|
+
validate: (input) => {
|
|
43
|
+
if (input.length < 3 || input.length > 10) {
|
|
44
|
+
return 'Token symbol must be 3-10 characters';
|
|
45
|
+
}
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
type: 'input',
|
|
51
|
+
name: 'totalSupply',
|
|
52
|
+
message: 'Total Supply (in tokens):',
|
|
53
|
+
default: '1000000000',
|
|
54
|
+
validate: (input) => {
|
|
55
|
+
if (isNaN(input) || parseInt(input) <= 0) {
|
|
56
|
+
return 'Total supply must be a positive number';
|
|
57
|
+
}
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
type: 'list',
|
|
63
|
+
name: 'network',
|
|
64
|
+
message: 'Network:',
|
|
65
|
+
choices: [
|
|
66
|
+
{ name: 'Base Mainnet', value: 'base-mainnet' },
|
|
67
|
+
{ name: 'Base Sepolia (Testnet)', value: 'base-sepolia' }
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
]);
|
|
71
|
+
|
|
72
|
+
const spinner = ora();
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
spinner.start('Validating token configuration...');
|
|
76
|
+
await new Promise(resolve => setTimeout(resolve, 800));
|
|
77
|
+
|
|
78
|
+
const tokenConfig = {
|
|
79
|
+
agentDNA: answers.agentDNA,
|
|
80
|
+
name: answers.tokenName,
|
|
81
|
+
symbol: answers.tokenSymbol.toUpperCase(),
|
|
82
|
+
totalSupply: answers.totalSupply,
|
|
83
|
+
decimals: 18,
|
|
84
|
+
network: answers.network,
|
|
85
|
+
feeDistribution: {
|
|
86
|
+
agent: 80,
|
|
87
|
+
dactyclaw: 20
|
|
88
|
+
},
|
|
89
|
+
createdAt: new Date().toISOString(),
|
|
90
|
+
status: 'pending'
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
spinner.succeed('Token configuration validated');
|
|
94
|
+
|
|
95
|
+
// Simulate deployment
|
|
96
|
+
spinner.start('Deploying token to ' + (answers.network === 'base-mainnet' ? 'Base Mainnet' : 'Base Sepolia') + '...');
|
|
97
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
98
|
+
|
|
99
|
+
// Generate mock contract address
|
|
100
|
+
const contractAddress = '0x' + Array.from({ length: 40 }, () => Math.floor(Math.random() * 16).toString(16)).join('');
|
|
101
|
+
|
|
102
|
+
spinner.succeed('Token deployed successfully');
|
|
103
|
+
|
|
104
|
+
// Display summary
|
|
105
|
+
console.log('\n');
|
|
106
|
+
console.log(chalk.green.bold('✓ Token launched successfully!'));
|
|
107
|
+
console.log('\n');
|
|
108
|
+
console.log(chalk.cyan('Token Details:'));
|
|
109
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
110
|
+
console.log(chalk.white(` Name: ${tokenConfig.name}`));
|
|
111
|
+
console.log(chalk.white(` Symbol: ${tokenConfig.symbol}`));
|
|
112
|
+
console.log(chalk.white(` Total Supply: ${tokenConfig.totalSupply}`));
|
|
113
|
+
console.log(chalk.white(` Decimals: ${tokenConfig.decimals}`));
|
|
114
|
+
console.log(chalk.white(` Network: ${answers.network === 'base-mainnet' ? 'Base Mainnet' : 'Base Sepolia'}`));
|
|
115
|
+
console.log(chalk.white(` Contract Address: ${contractAddress}`));
|
|
116
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
117
|
+
console.log('\n');
|
|
118
|
+
|
|
119
|
+
console.log(chalk.cyan('Fee Distribution:'));
|
|
120
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
121
|
+
console.log(chalk.white(` Agent: 80%`));
|
|
122
|
+
console.log(chalk.white(` Dactyclaw: 20%`));
|
|
123
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
124
|
+
console.log('\n');
|
|
125
|
+
|
|
126
|
+
console.log(chalk.cyan('Next Steps:'));
|
|
127
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
128
|
+
console.log(chalk.white(` 1. Token is now live on ${answers.network === 'base-mainnet' ? 'Base Mainnet' : 'Base Sepolia'}`));
|
|
129
|
+
console.log(chalk.white(` 2. Contract: ${contractAddress}`));
|
|
130
|
+
console.log(chalk.white(` 3. Your agent will receive 80% of trading fees`));
|
|
131
|
+
console.log(chalk.white(` 4. Monitor your token on Dactyclaw Explorer`));
|
|
132
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
133
|
+
console.log('\n');
|
|
134
|
+
|
|
135
|
+
} catch (error) {
|
|
136
|
+
spinner.fail('Error launching token');
|
|
137
|
+
console.error(chalk.red(error.message));
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
launchToken().catch(error => {
|
|
143
|
+
console.error(chalk.red('Fatal error:'), error);
|
|
144
|
+
process.exit(1);
|
|
145
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "dacty-launch",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Launch tokens for agents in the Dactyclaw ecosystem",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"dacty-launch": "./bin/dacty-launch.mjs"
|
|
8
|
+
},
|
|
9
|
+
"main": "lib/index.mjs",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "node build.mjs",
|
|
12
|
+
"prepublishOnly": "npm run build"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"dacty",
|
|
16
|
+
"token",
|
|
17
|
+
"launch",
|
|
18
|
+
"blockchain",
|
|
19
|
+
"cli"
|
|
20
|
+
],
|
|
21
|
+
"author": "Dactyclaw",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"chalk": "^5.3.0",
|
|
25
|
+
"inquirer": "^9.2.12",
|
|
26
|
+
"ora": "^8.0.1",
|
|
27
|
+
"axios": "^1.6.5",
|
|
28
|
+
"dotenv": "^16.3.1"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/node": "^20.10.5"
|
|
32
|
+
},
|
|
33
|
+
"engines": {
|
|
34
|
+
"node": ">=18.0.0"
|
|
35
|
+
},
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "https://github.com/dactyclaw/dacty-launch.git"
|
|
39
|
+
},
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/dactyclaw/dacty-launch/issues"
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://github.com/dactyclaw/dacty-launch#readme"
|
|
44
|
+
}
|