@moltlaunch/sdk 2.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 +240 -0
- package/examples/agent-config.json +12 -0
- package/package.json +27 -0
- package/src/cli.ts +158 -0
- package/src/index.d.ts +145 -0
- package/src/index.js +289 -0
- package/src/index.ts +68 -0
- package/src/launcher.ts +263 -0
- package/src/types.ts +122 -0
- package/src/verification.ts +228 -0
- package/test/basic.js +71 -0
- package/tsconfig.json +17 -0
package/src/index.js
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MoltLaunch SDK
|
|
3
|
+
* On-chain AI verification for AI agents
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* const { MoltLaunch } = require('@moltlaunch/sdk');
|
|
7
|
+
* const ml = new MoltLaunch();
|
|
8
|
+
* const result = await ml.verify({ agentId: 'my-agent', capabilities: ['trading'] });
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const DEFAULT_BASE_URL = 'https://web-production-419d9.up.railway.app';
|
|
12
|
+
|
|
13
|
+
class MoltLaunch {
|
|
14
|
+
/**
|
|
15
|
+
* Create a MoltLaunch client
|
|
16
|
+
* @param {Object} options - Configuration options
|
|
17
|
+
* @param {string} [options.baseUrl] - API base URL (default: production)
|
|
18
|
+
* @param {string} [options.apiKey] - Optional API key for premium features
|
|
19
|
+
*/
|
|
20
|
+
constructor(options = {}) {
|
|
21
|
+
this.baseUrl = options.baseUrl || DEFAULT_BASE_URL;
|
|
22
|
+
this.apiKey = options.apiKey || null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Get on-chain AI deployment info
|
|
27
|
+
* @returns {Promise<OnChainInfo>}
|
|
28
|
+
*/
|
|
29
|
+
async getOnChainInfo() {
|
|
30
|
+
const res = await fetch(`${this.baseUrl}/api/onchain-ai`);
|
|
31
|
+
if (!res.ok) throw new Error(`API error: ${res.status}`);
|
|
32
|
+
return res.json();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Verify an agent using on-chain AI
|
|
37
|
+
* @param {VerifyOptions} options - Verification options
|
|
38
|
+
* @returns {Promise<VerificationResult>}
|
|
39
|
+
*/
|
|
40
|
+
/**
|
|
41
|
+
* Generate a random nonce for replay protection
|
|
42
|
+
* @returns {string}
|
|
43
|
+
*/
|
|
44
|
+
generateNonce() {
|
|
45
|
+
const bytes = new Uint8Array(16);
|
|
46
|
+
if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
|
|
47
|
+
crypto.getRandomValues(bytes);
|
|
48
|
+
} else {
|
|
49
|
+
// Node.js fallback
|
|
50
|
+
const nodeCrypto = require('crypto');
|
|
51
|
+
const buf = nodeCrypto.randomBytes(16);
|
|
52
|
+
bytes.set(buf);
|
|
53
|
+
}
|
|
54
|
+
return Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Verify an agent using on-chain AI (v3.0 with security features)
|
|
59
|
+
* @param {VerifyOptions} options - Verification options
|
|
60
|
+
* @returns {Promise<VerificationResult>}
|
|
61
|
+
*/
|
|
62
|
+
async verify(options) {
|
|
63
|
+
const {
|
|
64
|
+
agentId,
|
|
65
|
+
wallet,
|
|
66
|
+
capabilities = [],
|
|
67
|
+
codeUrl,
|
|
68
|
+
documentation = false,
|
|
69
|
+
testCoverage = 0,
|
|
70
|
+
codeLines = 0,
|
|
71
|
+
apiEndpoint,
|
|
72
|
+
// v3.0 security options
|
|
73
|
+
secureMode = false,
|
|
74
|
+
nonce,
|
|
75
|
+
timestamp,
|
|
76
|
+
signature,
|
|
77
|
+
validityDays = 30
|
|
78
|
+
} = options;
|
|
79
|
+
|
|
80
|
+
if (!agentId) throw new Error('agentId is required');
|
|
81
|
+
|
|
82
|
+
// Build request body
|
|
83
|
+
const body = {
|
|
84
|
+
agentId,
|
|
85
|
+
wallet,
|
|
86
|
+
capabilities,
|
|
87
|
+
codeUrl,
|
|
88
|
+
documentation,
|
|
89
|
+
testCoverage,
|
|
90
|
+
codeLines,
|
|
91
|
+
apiEndpoint
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// Add v3.0 security fields if secure mode
|
|
95
|
+
if (secureMode) {
|
|
96
|
+
body.nonce = nonce || this.generateNonce();
|
|
97
|
+
body.timestamp = timestamp || Math.floor(Date.now() / 1000);
|
|
98
|
+
body.validityDays = validityDays;
|
|
99
|
+
if (signature) body.signature = signature;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const res = await fetch(`${this.baseUrl}/api/verify/deep`, {
|
|
103
|
+
method: 'POST',
|
|
104
|
+
headers: {
|
|
105
|
+
'Content-Type': 'application/json',
|
|
106
|
+
...(this.apiKey && { 'Authorization': `Bearer ${this.apiKey}` })
|
|
107
|
+
},
|
|
108
|
+
body: JSON.stringify(body)
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
if (!res.ok) {
|
|
112
|
+
const error = await res.json().catch(() => ({ error: res.statusText }));
|
|
113
|
+
throw new Error(error.error || `API error: ${res.status}`);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const data = await res.json();
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
agentId: data.agentId,
|
|
120
|
+
verified: data.score >= 60,
|
|
121
|
+
passed: data.passed,
|
|
122
|
+
score: data.score,
|
|
123
|
+
tier: data.scoreTier,
|
|
124
|
+
features: data.features,
|
|
125
|
+
onChainAI: data.onChainAI,
|
|
126
|
+
attestation: data.attestation,
|
|
127
|
+
security: data.security,
|
|
128
|
+
raw: data
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Verify with secure mode enabled (replay-protected)
|
|
134
|
+
* @param {VerifyOptions} options - Verification options
|
|
135
|
+
* @returns {Promise<VerificationResult>}
|
|
136
|
+
*/
|
|
137
|
+
async verifySecure(options) {
|
|
138
|
+
return this.verify({ ...options, secureMode: true });
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Check if an attestation is revoked
|
|
143
|
+
* @param {string} attestationHash - Attestation hash
|
|
144
|
+
* @returns {Promise<{revoked: boolean, checkedAt: string}>}
|
|
145
|
+
*/
|
|
146
|
+
async checkRevocation(attestationHash) {
|
|
147
|
+
const res = await fetch(`${this.baseUrl}/api/verify/revoked/${attestationHash}`);
|
|
148
|
+
if (!res.ok) throw new Error(`API error: ${res.status}`);
|
|
149
|
+
return res.json();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Renew verification before expiry
|
|
154
|
+
* @param {string} agentId - Agent ID
|
|
155
|
+
* @param {object} options - Additional options
|
|
156
|
+
* @returns {Promise<VerificationResult>}
|
|
157
|
+
*/
|
|
158
|
+
async renew(agentId, options = {}) {
|
|
159
|
+
const res = await fetch(`${this.baseUrl}/api/verify/renew/${agentId}`, {
|
|
160
|
+
method: 'POST',
|
|
161
|
+
headers: { 'Content-Type': 'application/json' },
|
|
162
|
+
body: JSON.stringify(options)
|
|
163
|
+
});
|
|
164
|
+
if (!res.ok) {
|
|
165
|
+
const error = await res.json().catch(() => ({ error: res.statusText }));
|
|
166
|
+
throw new Error(error.error || `API error: ${res.status}`);
|
|
167
|
+
}
|
|
168
|
+
return res.json();
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Get verification status for an agent
|
|
173
|
+
* @param {string} agentId - Agent ID
|
|
174
|
+
* @returns {Promise<StatusResult>}
|
|
175
|
+
*/
|
|
176
|
+
async getStatus(agentId) {
|
|
177
|
+
const res = await fetch(`${this.baseUrl}/api/verify/status/${encodeURIComponent(agentId)}`);
|
|
178
|
+
if (!res.ok) throw new Error(`API error: ${res.status}`);
|
|
179
|
+
return res.json();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Get verification status for multiple agents
|
|
184
|
+
* @param {string[]} agentIds - Array of agent IDs
|
|
185
|
+
* @returns {Promise<BatchStatusResult>}
|
|
186
|
+
*/
|
|
187
|
+
async getStatusBatch(agentIds) {
|
|
188
|
+
const res = await fetch(`${this.baseUrl}/api/verify/status/batch`, {
|
|
189
|
+
method: 'POST',
|
|
190
|
+
headers: { 'Content-Type': 'application/json' },
|
|
191
|
+
body: JSON.stringify({ agentIds })
|
|
192
|
+
});
|
|
193
|
+
if (!res.ok) throw new Error(`API error: ${res.status}`);
|
|
194
|
+
return res.json();
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Apply agent to a staking pool
|
|
199
|
+
* @param {PoolApplyOptions} options - Pool application options
|
|
200
|
+
* @returns {Promise<PoolApplyResult>}
|
|
201
|
+
*/
|
|
202
|
+
async applyToPool(options) {
|
|
203
|
+
const { agentId, wallet, topic, strategy } = options;
|
|
204
|
+
|
|
205
|
+
const res = await fetch(`${this.baseUrl}/api/pool/apply`, {
|
|
206
|
+
method: 'POST',
|
|
207
|
+
headers: { 'Content-Type': 'application/json' },
|
|
208
|
+
body: JSON.stringify({ agentId, wallet, topic, strategy })
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
if (!res.ok) {
|
|
212
|
+
const error = await res.json().catch(() => ({ error: res.statusText }));
|
|
213
|
+
throw new Error(error.error || `API error: ${res.status}`);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return res.json();
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Get pool information
|
|
221
|
+
* @param {string} [topic] - Optional topic filter
|
|
222
|
+
* @returns {Promise<PoolInfo>}
|
|
223
|
+
*/
|
|
224
|
+
async getPools(topic) {
|
|
225
|
+
const url = topic
|
|
226
|
+
? `${this.baseUrl}/api/pools/${encodeURIComponent(topic)}`
|
|
227
|
+
: `${this.baseUrl}/api/pools`;
|
|
228
|
+
const res = await fetch(url);
|
|
229
|
+
if (!res.ok) throw new Error(`API error: ${res.status}`);
|
|
230
|
+
return res.json();
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Get leaderboard
|
|
235
|
+
* @returns {Promise<LeaderboardResult>}
|
|
236
|
+
*/
|
|
237
|
+
async getLeaderboard() {
|
|
238
|
+
const res = await fetch(`${this.baseUrl}/api/pools/leaderboard`);
|
|
239
|
+
if (!res.ok) throw new Error(`API error: ${res.status}`);
|
|
240
|
+
return res.json();
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Check API health
|
|
245
|
+
* @returns {Promise<boolean>}
|
|
246
|
+
*/
|
|
247
|
+
async isHealthy() {
|
|
248
|
+
try {
|
|
249
|
+
const res = await fetch(`${this.baseUrl}/api/health`);
|
|
250
|
+
return res.ok;
|
|
251
|
+
} catch {
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Scoring helpers
|
|
258
|
+
const SCORE_TIERS = {
|
|
259
|
+
excellent: { min: 80, max: 100, label: 'Production Ready' },
|
|
260
|
+
good: { min: 60, max: 79, label: 'Verified' },
|
|
261
|
+
needs_work: { min: 40, max: 59, label: 'Needs Improvement' },
|
|
262
|
+
poor: { min: 0, max: 39, label: 'Not Ready' }
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
const getTier = (score) => {
|
|
266
|
+
if (score >= 80) return 'excellent';
|
|
267
|
+
if (score >= 60) return 'good';
|
|
268
|
+
if (score >= 40) return 'needs_work';
|
|
269
|
+
return 'poor';
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
const isVerified = (score) => score >= 60;
|
|
273
|
+
|
|
274
|
+
// On-chain AI deployment info
|
|
275
|
+
const DEPLOYMENT = {
|
|
276
|
+
network: 'solana-devnet',
|
|
277
|
+
vm: 'FHcy35f4NGZK9b6j5TGMYstfB6PXEtmNbMLvjfR1y2Li',
|
|
278
|
+
weights: 'GnSxMWbZEa538vJ9Pf3veDrKP1LkzPiaaVmC4mRnM91N',
|
|
279
|
+
program: 'FRsToriMLgDc1Ud53ngzHUZvCRoazCaGeGUuzkwoha7m'
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
module.exports = {
|
|
283
|
+
MoltLaunch,
|
|
284
|
+
SCORE_TIERS,
|
|
285
|
+
DEPLOYMENT,
|
|
286
|
+
getTier,
|
|
287
|
+
isVerified,
|
|
288
|
+
DEFAULT_BASE_URL
|
|
289
|
+
};
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// MoltLaunch SDK - AI Agent Token Launches on Solana
|
|
2
|
+
// Built on Meteora Dynamic Bonding Curve (DBC)
|
|
3
|
+
|
|
4
|
+
export * from './types';
|
|
5
|
+
export * from './verification';
|
|
6
|
+
export * from './launcher';
|
|
7
|
+
|
|
8
|
+
import { MoltLauncher, LaunchOptions, quickLaunch } from './launcher';
|
|
9
|
+
import { AgentVerifier, verifier } from './verification';
|
|
10
|
+
import {
|
|
11
|
+
AgentProfile,
|
|
12
|
+
LaunchConfig,
|
|
13
|
+
VerificationResult,
|
|
14
|
+
LaunchResult,
|
|
15
|
+
MOLTLAUNCH_CONFIG,
|
|
16
|
+
DBC_PROGRAM_ID,
|
|
17
|
+
} from './types';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* MoltLaunch SDK
|
|
21
|
+
*
|
|
22
|
+
* The first dedicated launchpad for AI agent token sales on Solana.
|
|
23
|
+
* Built on Meteora's Dynamic Bonding Curve for fair, transparent launches.
|
|
24
|
+
*
|
|
25
|
+
* Features:
|
|
26
|
+
* - Proof-of-Agent verification before launch
|
|
27
|
+
* - Customizable bonding curves (linear, exponential, market cap)
|
|
28
|
+
* - Automatic graduation to Meteora AMM
|
|
29
|
+
* - Milestone-based team vesting
|
|
30
|
+
* - 80/20 fee split (creator/platform)
|
|
31
|
+
*
|
|
32
|
+
* Quick Start:
|
|
33
|
+
* ```typescript
|
|
34
|
+
* import { MoltLauncher, AgentProfile } from '@moltlaunch/sdk';
|
|
35
|
+
*
|
|
36
|
+
* const agent: AgentProfile = {
|
|
37
|
+
* name: 'TradingBot Pro',
|
|
38
|
+
* symbol: 'TBP',
|
|
39
|
+
* description: 'Autonomous trading agent with proven alpha generation',
|
|
40
|
+
* capabilities: ['trading', 'analysis', 'automation'],
|
|
41
|
+
* apiEndpoint: 'https://tradingbot.example.com/api',
|
|
42
|
+
* githubRepo: 'https://github.com/example/tradingbot',
|
|
43
|
+
* };
|
|
44
|
+
*
|
|
45
|
+
* const launcher = new MoltLauncher({
|
|
46
|
+
* rpcUrl: 'https://api.devnet.solana.com',
|
|
47
|
+
* payer: yourKeypair,
|
|
48
|
+
* dryRun: true,
|
|
49
|
+
* });
|
|
50
|
+
*
|
|
51
|
+
* const result = await launcher.launchAgent(agent, {
|
|
52
|
+
* targetRaise: 500, // SOL
|
|
53
|
+
* curveType: 'exponential',
|
|
54
|
+
* });
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
|
|
58
|
+
export default {
|
|
59
|
+
MoltLauncher,
|
|
60
|
+
AgentVerifier,
|
|
61
|
+
quickLaunch,
|
|
62
|
+
verifier,
|
|
63
|
+
config: MOLTLAUNCH_CONFIG,
|
|
64
|
+
programId: DBC_PROGRAM_ID,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// Version
|
|
68
|
+
export const VERSION = '1.0.0';
|
package/src/launcher.ts
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
// MoltLaunch - Token Launch on Meteora DBC
|
|
2
|
+
import {
|
|
3
|
+
Connection,
|
|
4
|
+
Keypair,
|
|
5
|
+
PublicKey,
|
|
6
|
+
TransactionInstruction,
|
|
7
|
+
VersionedTransaction,
|
|
8
|
+
TransactionMessage,
|
|
9
|
+
LAMPORTS_PER_SOL,
|
|
10
|
+
} from '@solana/web3.js';
|
|
11
|
+
import {
|
|
12
|
+
AgentProfile,
|
|
13
|
+
LaunchConfig,
|
|
14
|
+
LaunchResult,
|
|
15
|
+
SwapParams,
|
|
16
|
+
SwapResult,
|
|
17
|
+
DBC_PROGRAM_ID,
|
|
18
|
+
MOLTLAUNCH_CONFIG,
|
|
19
|
+
} from './types';
|
|
20
|
+
import { AgentVerifier } from './verification';
|
|
21
|
+
|
|
22
|
+
export interface LaunchOptions {
|
|
23
|
+
rpcUrl: string;
|
|
24
|
+
payer: Keypair;
|
|
25
|
+
dryRun?: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export class MoltLauncher {
|
|
29
|
+
private connection: Connection;
|
|
30
|
+
private payer: Keypair;
|
|
31
|
+
private dryRun: boolean;
|
|
32
|
+
private verifier: AgentVerifier;
|
|
33
|
+
|
|
34
|
+
constructor(options: LaunchOptions) {
|
|
35
|
+
this.connection = new Connection(options.rpcUrl, 'confirmed');
|
|
36
|
+
this.payer = options.payer;
|
|
37
|
+
this.dryRun = options.dryRun ?? false;
|
|
38
|
+
this.verifier = new AgentVerifier();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Full launch flow: verify agent -> create DBC config -> create pool
|
|
43
|
+
*/
|
|
44
|
+
async launchAgent(
|
|
45
|
+
agent: AgentProfile,
|
|
46
|
+
config: Partial<LaunchConfig> = {}
|
|
47
|
+
): Promise<LaunchResult> {
|
|
48
|
+
console.log(`\n🚀 Starting launch for ${agent.name} ($${agent.symbol})\n`);
|
|
49
|
+
|
|
50
|
+
// 1. Verify agent
|
|
51
|
+
console.log('📋 Step 1: Verifying agent...');
|
|
52
|
+
const verification = await this.verifier.verify(agent);
|
|
53
|
+
|
|
54
|
+
if (!verification.passed) {
|
|
55
|
+
return {
|
|
56
|
+
success: false,
|
|
57
|
+
error: `Verification failed with score ${verification.score}/100. Minimum required: ${MOLTLAUNCH_CONFIG.minVerificationScore}`,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
console.log(`✅ Verification passed! Score: ${verification.score}/100\n`);
|
|
61
|
+
|
|
62
|
+
// 2. Merge with default config
|
|
63
|
+
const launchConfig: LaunchConfig = {
|
|
64
|
+
...MOLTLAUNCH_CONFIG.defaultLaunchConfig,
|
|
65
|
+
targetRaise: 100, // Default 100 SOL
|
|
66
|
+
...config,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// 3. Generate DBC configuration
|
|
70
|
+
console.log('⚙️ Step 2: Generating DBC configuration...');
|
|
71
|
+
const dbcConfig = this.generateDbcConfig(agent, launchConfig);
|
|
72
|
+
console.log(` Curve Type: ${launchConfig.curveType}`);
|
|
73
|
+
console.log(` Target Raise: ${launchConfig.targetRaise} SOL`);
|
|
74
|
+
console.log(` Migration: ${launchConfig.migrationTarget}\n`);
|
|
75
|
+
|
|
76
|
+
if (this.dryRun) {
|
|
77
|
+
console.log('🔍 DRY RUN MODE - No transactions will be sent\n');
|
|
78
|
+
console.log('Generated DBC Config:', JSON.stringify(dbcConfig, null, 2));
|
|
79
|
+
return {
|
|
80
|
+
success: true,
|
|
81
|
+
transactionId: 'dry-run-no-tx',
|
|
82
|
+
poolAddress: 'dry-run-pool-address',
|
|
83
|
+
tokenMint: 'dry-run-token-mint',
|
|
84
|
+
configKey: 'dry-run-config-key',
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// 4. Create DBC Config (on-chain)
|
|
89
|
+
console.log('📝 Step 3: Creating DBC config on-chain...');
|
|
90
|
+
// TODO: Implement actual DBC config creation using Meteora SDK
|
|
91
|
+
// This would use the @mercurial-finance/dynamic-amm-sdk or similar
|
|
92
|
+
|
|
93
|
+
// For now, we return a placeholder
|
|
94
|
+
console.log('⚠️ Note: Full DBC integration requires Meteora SDK\n');
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
success: true,
|
|
98
|
+
transactionId: 'pending-integration',
|
|
99
|
+
poolAddress: 'pending-integration',
|
|
100
|
+
tokenMint: 'pending-integration',
|
|
101
|
+
configKey: 'pending-integration',
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Generate DBC-compatible configuration from MoltLaunch config
|
|
107
|
+
*/
|
|
108
|
+
private generateDbcConfig(agent: AgentProfile, config: LaunchConfig) {
|
|
109
|
+
// Map our config to Meteora DBC format
|
|
110
|
+
const buildCurveMode = {
|
|
111
|
+
linear: 0,
|
|
112
|
+
exponential: 1,
|
|
113
|
+
marketcap: 1,
|
|
114
|
+
custom: 3,
|
|
115
|
+
}[config.curveType];
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
// Network
|
|
119
|
+
rpcUrl: this.connection.rpcEndpoint,
|
|
120
|
+
dryRun: this.dryRun,
|
|
121
|
+
computeUnitPriceMicroLamports: 100000,
|
|
122
|
+
quoteMint: config.quoteMint || 'So11111111111111111111111111111111111111112', // SOL
|
|
123
|
+
|
|
124
|
+
// DBC Config
|
|
125
|
+
dbcConfig: {
|
|
126
|
+
buildCurveMode,
|
|
127
|
+
|
|
128
|
+
// Supply & Migration
|
|
129
|
+
totalTokenSupply: config.totalSupply,
|
|
130
|
+
migrationQuoteThreshold: config.targetRaise,
|
|
131
|
+
percentageSupplyOnMigration: 20,
|
|
132
|
+
|
|
133
|
+
// For marketcap mode
|
|
134
|
+
...(config.curveType === 'marketcap' && {
|
|
135
|
+
initialMarketCap: config.initialMarketCap || config.targetRaise * 0.1,
|
|
136
|
+
migrationMarketCap: config.migrationMarketCap || config.targetRaise * 5,
|
|
137
|
+
}),
|
|
138
|
+
|
|
139
|
+
// Migration settings
|
|
140
|
+
migrationOption: config.migrationTarget === 'damm-v2' ? 1 : 0,
|
|
141
|
+
migrationFeeOption: config.migrationFeeOption,
|
|
142
|
+
|
|
143
|
+
// Token settings
|
|
144
|
+
tokenBaseDecimal: 6,
|
|
145
|
+
tokenQuoteDecimal: 9,
|
|
146
|
+
tokenType: 0, // SPL Token
|
|
147
|
+
tokenUpdateAuthority: 1, // Immutable
|
|
148
|
+
|
|
149
|
+
// Fee structure
|
|
150
|
+
baseFeeParams: {
|
|
151
|
+
baseFeeMode: 0,
|
|
152
|
+
feeSchedulerParam: {
|
|
153
|
+
startingFeeBps: config.tradingFeeBps,
|
|
154
|
+
endingFeeBps: config.tradingFeeBps,
|
|
155
|
+
numberOfPeriod: 0,
|
|
156
|
+
totalDuration: 0,
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
dynamicFeeEnabled: true,
|
|
160
|
+
collectFeeMode: 0, // Quote token only
|
|
161
|
+
activationType: 1, // Timestamp
|
|
162
|
+
|
|
163
|
+
// LP Distribution
|
|
164
|
+
partnerLiquidityPercentage: config.platformLpPercentage,
|
|
165
|
+
creatorLiquidityPercentage: config.creatorLpPercentage,
|
|
166
|
+
partnerPermanentLockedLiquidityPercentage: config.platformLockedLpPercentage,
|
|
167
|
+
creatorPermanentLockedLiquidityPercentage: config.creatorLockedLpPercentage,
|
|
168
|
+
creatorTradingFeePercentage: config.creatorFeeShare,
|
|
169
|
+
|
|
170
|
+
// Vesting (if enabled)
|
|
171
|
+
lockedVestingParams: config.vestingEnabled
|
|
172
|
+
? {
|
|
173
|
+
totalLockedVestingAmount: 0,
|
|
174
|
+
numberOfVestingPeriod: Math.ceil((config.vestingDurationDays || 30) / 7),
|
|
175
|
+
cliffUnlockAmount: 0,
|
|
176
|
+
totalVestingDuration: (config.vestingDurationDays || 30) * 24 * 60 * 60,
|
|
177
|
+
cliffDurationFromMigrationTime: (config.cliffDays || 7) * 24 * 60 * 60,
|
|
178
|
+
}
|
|
179
|
+
: {
|
|
180
|
+
totalLockedVestingAmount: 0,
|
|
181
|
+
numberOfVestingPeriod: 0,
|
|
182
|
+
cliffUnlockAmount: 0,
|
|
183
|
+
totalVestingDuration: 0,
|
|
184
|
+
cliffDurationFromMigrationTime: 0,
|
|
185
|
+
},
|
|
186
|
+
|
|
187
|
+
// Addresses
|
|
188
|
+
leftover: 0,
|
|
189
|
+
leftoverReceiver: MOLTLAUNCH_CONFIG.platformWallet,
|
|
190
|
+
feeClaimer: MOLTLAUNCH_CONFIG.platformWallet,
|
|
191
|
+
|
|
192
|
+
// Migration fee
|
|
193
|
+
migrationFee: {
|
|
194
|
+
feePercentage: 0,
|
|
195
|
+
creatorFeePercentage: 0,
|
|
196
|
+
},
|
|
197
|
+
poolCreationFee: 0,
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
// Pool creation
|
|
201
|
+
dbcPool: {
|
|
202
|
+
creator: this.payer.publicKey.toBase58(),
|
|
203
|
+
name: agent.name,
|
|
204
|
+
symbol: agent.symbol,
|
|
205
|
+
metadata: {
|
|
206
|
+
description: agent.description,
|
|
207
|
+
website: agent.website,
|
|
208
|
+
twitter: agent.twitter,
|
|
209
|
+
telegram: agent.telegram,
|
|
210
|
+
image: agent.logo,
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Get current pool status
|
|
218
|
+
*/
|
|
219
|
+
async getPoolStatus(tokenMint: string): Promise<{
|
|
220
|
+
exists: boolean;
|
|
221
|
+
currentRaise: number;
|
|
222
|
+
targetRaise: number;
|
|
223
|
+
progress: number;
|
|
224
|
+
currentPrice: number;
|
|
225
|
+
graduated: boolean;
|
|
226
|
+
} | null> {
|
|
227
|
+
// TODO: Query DBC program for pool state
|
|
228
|
+
return null;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Buy/sell tokens on bonding curve
|
|
233
|
+
*/
|
|
234
|
+
async swap(params: SwapParams): Promise<SwapResult> {
|
|
235
|
+
// TODO: Implement swap via DBC program
|
|
236
|
+
return {
|
|
237
|
+
success: false,
|
|
238
|
+
error: 'Swap not yet implemented - requires Meteora DBC SDK integration',
|
|
239
|
+
amountIn: params.amountIn,
|
|
240
|
+
amountOut: 0,
|
|
241
|
+
priceImpact: 0,
|
|
242
|
+
newPrice: 0,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Quick launch helper function
|
|
249
|
+
*/
|
|
250
|
+
export async function quickLaunch(
|
|
251
|
+
agent: AgentProfile,
|
|
252
|
+
payerSecretKey: Uint8Array,
|
|
253
|
+
rpcUrl: string = 'https://api.devnet.solana.com',
|
|
254
|
+
config: Partial<LaunchConfig> = {}
|
|
255
|
+
): Promise<LaunchResult> {
|
|
256
|
+
const launcher = new MoltLauncher({
|
|
257
|
+
rpcUrl,
|
|
258
|
+
payer: Keypair.fromSecretKey(payerSecretKey),
|
|
259
|
+
dryRun: true, // Default to dry run for safety
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
return launcher.launchAgent(agent, config);
|
|
263
|
+
}
|