clanker-sdk 3.9.5 → 3.9.8
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/dist/cli/cli.js +1353 -0
- package/dist/cli/create-clanker.js +419 -413
- package/dist/index.js +23 -42
- package/package.json +15 -11
- package/dist/cli/create-clanker.d.ts +0 -1
- package/dist/index.d.mts +0 -109
- package/dist/index.d.ts +0 -109
- package/dist/index.mjs +0 -857
package/dist/cli/cli.js
ADDED
|
@@ -0,0 +1,1353 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __esm = (fn, res) => function __init() {
|
|
5
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
6
|
+
};
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
// node_modules/tsup/assets/esm_shims.js
|
|
13
|
+
var init_esm_shims = __esm({
|
|
14
|
+
"node_modules/tsup/assets/esm_shims.js"() {
|
|
15
|
+
"use strict";
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// src/constants.ts
|
|
20
|
+
var WETH_ADDRESS, CLANKER_FACTORY_V3_1;
|
|
21
|
+
var init_constants = __esm({
|
|
22
|
+
"src/constants.ts"() {
|
|
23
|
+
"use strict";
|
|
24
|
+
init_esm_shims();
|
|
25
|
+
WETH_ADDRESS = "0x4200000000000000000000000000000000000006";
|
|
26
|
+
CLANKER_FACTORY_V3_1 = "0x2A787b2362021cC3eEa3C24C4748a6cD5B687382";
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// src/abis/Clanker_V3_1.ts
|
|
31
|
+
var Clanker_v3_1_abi;
|
|
32
|
+
var init_Clanker_V3_1 = __esm({
|
|
33
|
+
"src/abis/Clanker_V3_1.ts"() {
|
|
34
|
+
"use strict";
|
|
35
|
+
init_esm_shims();
|
|
36
|
+
Clanker_v3_1_abi = [
|
|
37
|
+
{
|
|
38
|
+
inputs: [{ internalType: "address", name: "owner_", type: "address" }],
|
|
39
|
+
stateMutability: "nonpayable",
|
|
40
|
+
type: "constructor"
|
|
41
|
+
},
|
|
42
|
+
{ inputs: [], name: "Deprecated", type: "error" },
|
|
43
|
+
{ inputs: [], name: "InvalidCreatorInfo", type: "error" },
|
|
44
|
+
{ inputs: [], name: "InvalidCreatorReward", type: "error" },
|
|
45
|
+
{ inputs: [], name: "InvalidInterfaceInfo", type: "error" },
|
|
46
|
+
{ inputs: [], name: "InvalidTick", type: "error" },
|
|
47
|
+
{ inputs: [], name: "InvalidVaultConfiguration", type: "error" },
|
|
48
|
+
{ inputs: [], name: "NotFound", type: "error" },
|
|
49
|
+
{ inputs: [], name: "OnlyNonOriginatingChains", type: "error" },
|
|
50
|
+
{ inputs: [], name: "OnlyOriginatingChain", type: "error" },
|
|
51
|
+
{
|
|
52
|
+
inputs: [{ internalType: "address", name: "owner", type: "address" }],
|
|
53
|
+
name: "OwnableInvalidOwner",
|
|
54
|
+
type: "error"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
inputs: [{ internalType: "address", name: "account", type: "address" }],
|
|
58
|
+
name: "OwnableUnauthorizedAccount",
|
|
59
|
+
type: "error"
|
|
60
|
+
},
|
|
61
|
+
{ inputs: [], name: "ReentrancyGuardReentrantCall", type: "error" },
|
|
62
|
+
{ inputs: [], name: "Unauthorized", type: "error" },
|
|
63
|
+
{ inputs: [], name: "ZeroTeamRewardRecipient", type: "error" },
|
|
64
|
+
{
|
|
65
|
+
anonymous: false,
|
|
66
|
+
inputs: [
|
|
67
|
+
{ indexed: false, internalType: "address", name: "oldClankerDeployer", type: "address" },
|
|
68
|
+
{ indexed: false, internalType: "address", name: "newClankerDeployer", type: "address" }
|
|
69
|
+
],
|
|
70
|
+
name: "ClankerDeployerUpdated",
|
|
71
|
+
type: "event"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
anonymous: false,
|
|
75
|
+
inputs: [
|
|
76
|
+
{ indexed: false, internalType: "address", name: "oldLocker", type: "address" },
|
|
77
|
+
{ indexed: false, internalType: "address", name: "newLocker", type: "address" }
|
|
78
|
+
],
|
|
79
|
+
name: "LiquidityLockerUpdated",
|
|
80
|
+
type: "event"
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
anonymous: false,
|
|
84
|
+
inputs: [
|
|
85
|
+
{ indexed: true, internalType: "address", name: "previousOwner", type: "address" },
|
|
86
|
+
{ indexed: true, internalType: "address", name: "newOwner", type: "address" }
|
|
87
|
+
],
|
|
88
|
+
name: "OwnershipTransferred",
|
|
89
|
+
type: "event"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
anonymous: false,
|
|
93
|
+
inputs: [
|
|
94
|
+
{ indexed: false, internalType: "address", name: "admin", type: "address" },
|
|
95
|
+
{ indexed: false, internalType: "bool", name: "isAdmin", type: "bool" }
|
|
96
|
+
],
|
|
97
|
+
name: "SetAdmin",
|
|
98
|
+
type: "event"
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
anonymous: false,
|
|
102
|
+
inputs: [{ indexed: false, internalType: "bool", name: "deprecated", type: "bool" }],
|
|
103
|
+
name: "SetDeprecated",
|
|
104
|
+
type: "event"
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
anonymous: false,
|
|
108
|
+
inputs: [
|
|
109
|
+
{ indexed: true, internalType: "address", name: "tokenAddress", type: "address" },
|
|
110
|
+
{ indexed: true, internalType: "address", name: "creatorAdmin", type: "address" },
|
|
111
|
+
{ indexed: true, internalType: "address", name: "interfaceAdmin", type: "address" },
|
|
112
|
+
{ indexed: false, internalType: "address", name: "creatorRewardRecipient", type: "address" },
|
|
113
|
+
{
|
|
114
|
+
indexed: false,
|
|
115
|
+
internalType: "address",
|
|
116
|
+
name: "interfaceRewardRecipient",
|
|
117
|
+
type: "address"
|
|
118
|
+
},
|
|
119
|
+
{ indexed: false, internalType: "uint256", name: "positionId", type: "uint256" },
|
|
120
|
+
{ indexed: false, internalType: "string", name: "name", type: "string" },
|
|
121
|
+
{ indexed: false, internalType: "string", name: "symbol", type: "string" },
|
|
122
|
+
{
|
|
123
|
+
indexed: false,
|
|
124
|
+
internalType: "int24",
|
|
125
|
+
name: "startingTickIfToken0IsNewToken",
|
|
126
|
+
type: "int24"
|
|
127
|
+
},
|
|
128
|
+
{ indexed: false, internalType: "string", name: "metadata", type: "string" },
|
|
129
|
+
{ indexed: false, internalType: "uint256", name: "amountTokensBought", type: "uint256" },
|
|
130
|
+
{ indexed: false, internalType: "uint256", name: "vaultDuration", type: "uint256" },
|
|
131
|
+
{ indexed: false, internalType: "uint8", name: "vaultPercentage", type: "uint8" },
|
|
132
|
+
{ indexed: false, internalType: "address", name: "msgSender", type: "address" }
|
|
133
|
+
],
|
|
134
|
+
name: "TokenCreated",
|
|
135
|
+
type: "event"
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
anonymous: false,
|
|
139
|
+
inputs: [
|
|
140
|
+
{ indexed: false, internalType: "address", name: "oldVault", type: "address" },
|
|
141
|
+
{ indexed: false, internalType: "address", name: "newVault", type: "address" }
|
|
142
|
+
],
|
|
143
|
+
name: "VaultUpdated",
|
|
144
|
+
type: "event"
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
inputs: [],
|
|
148
|
+
name: "MAX_CREATOR_REWARD",
|
|
149
|
+
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
|
|
150
|
+
stateMutability: "view",
|
|
151
|
+
type: "function"
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
inputs: [],
|
|
155
|
+
name: "MAX_TICK",
|
|
156
|
+
outputs: [{ internalType: "int24", name: "", type: "int24" }],
|
|
157
|
+
stateMutability: "view",
|
|
158
|
+
type: "function"
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
inputs: [],
|
|
162
|
+
name: "MAX_VAULT_PERCENTAGE",
|
|
163
|
+
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
|
|
164
|
+
stateMutability: "view",
|
|
165
|
+
type: "function"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
inputs: [],
|
|
169
|
+
name: "POOL_FEE",
|
|
170
|
+
outputs: [{ internalType: "uint24", name: "", type: "uint24" }],
|
|
171
|
+
stateMutability: "view",
|
|
172
|
+
type: "function"
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
inputs: [],
|
|
176
|
+
name: "TICK_SPACING",
|
|
177
|
+
outputs: [{ internalType: "int24", name: "", type: "int24" }],
|
|
178
|
+
stateMutability: "view",
|
|
179
|
+
type: "function"
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
inputs: [],
|
|
183
|
+
name: "TOKEN_SUPPLY",
|
|
184
|
+
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
|
|
185
|
+
stateMutability: "view",
|
|
186
|
+
type: "function"
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
inputs: [{ internalType: "address", name: "", type: "address" }],
|
|
190
|
+
name: "admins",
|
|
191
|
+
outputs: [{ internalType: "bool", name: "", type: "bool" }],
|
|
192
|
+
stateMutability: "view",
|
|
193
|
+
type: "function"
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
inputs: [{ internalType: "address", name: "token", type: "address" }],
|
|
197
|
+
name: "claimRewards",
|
|
198
|
+
outputs: [],
|
|
199
|
+
stateMutability: "nonpayable",
|
|
200
|
+
type: "function"
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
inputs: [
|
|
204
|
+
{
|
|
205
|
+
components: [
|
|
206
|
+
{
|
|
207
|
+
components: [
|
|
208
|
+
{ internalType: "string", name: "name", type: "string" },
|
|
209
|
+
{ internalType: "string", name: "symbol", type: "string" },
|
|
210
|
+
{ internalType: "bytes32", name: "salt", type: "bytes32" },
|
|
211
|
+
{ internalType: "string", name: "image", type: "string" },
|
|
212
|
+
{ internalType: "string", name: "metadata", type: "string" },
|
|
213
|
+
{ internalType: "string", name: "context", type: "string" },
|
|
214
|
+
{ internalType: "uint256", name: "originatingChainId", type: "uint256" }
|
|
215
|
+
],
|
|
216
|
+
internalType: "struct IClanker.TokenConfig",
|
|
217
|
+
name: "tokenConfig",
|
|
218
|
+
type: "tuple"
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
components: [
|
|
222
|
+
{ internalType: "uint8", name: "vaultPercentage", type: "uint8" },
|
|
223
|
+
{ internalType: "uint256", name: "vaultDuration", type: "uint256" }
|
|
224
|
+
],
|
|
225
|
+
internalType: "struct IClanker.VaultConfig",
|
|
226
|
+
name: "vaultConfig",
|
|
227
|
+
type: "tuple"
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
components: [
|
|
231
|
+
{ internalType: "address", name: "pairedToken", type: "address" },
|
|
232
|
+
{ internalType: "int24", name: "tickIfToken0IsNewToken", type: "int24" }
|
|
233
|
+
],
|
|
234
|
+
internalType: "struct IClanker.PoolConfig",
|
|
235
|
+
name: "poolConfig",
|
|
236
|
+
type: "tuple"
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
components: [
|
|
240
|
+
{ internalType: "uint24", name: "pairedTokenPoolFee", type: "uint24" },
|
|
241
|
+
{ internalType: "uint256", name: "pairedTokenSwapAmountOutMinimum", type: "uint256" }
|
|
242
|
+
],
|
|
243
|
+
internalType: "struct IClanker.InitialBuyConfig",
|
|
244
|
+
name: "initialBuyConfig",
|
|
245
|
+
type: "tuple"
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
components: [
|
|
249
|
+
{ internalType: "uint256", name: "creatorReward", type: "uint256" },
|
|
250
|
+
{ internalType: "address", name: "creatorAdmin", type: "address" },
|
|
251
|
+
{ internalType: "address", name: "creatorRewardRecipient", type: "address" },
|
|
252
|
+
{ internalType: "address", name: "interfaceAdmin", type: "address" },
|
|
253
|
+
{ internalType: "address", name: "interfaceRewardRecipient", type: "address" }
|
|
254
|
+
],
|
|
255
|
+
internalType: "struct IClanker.RewardsConfig",
|
|
256
|
+
name: "rewardsConfig",
|
|
257
|
+
type: "tuple"
|
|
258
|
+
}
|
|
259
|
+
],
|
|
260
|
+
internalType: "struct IClanker.DeploymentConfig",
|
|
261
|
+
name: "deploymentConfig",
|
|
262
|
+
type: "tuple"
|
|
263
|
+
}
|
|
264
|
+
],
|
|
265
|
+
name: "deployToken",
|
|
266
|
+
outputs: [
|
|
267
|
+
{ internalType: "address", name: "tokenAddress", type: "address" },
|
|
268
|
+
{ internalType: "uint256", name: "positionId", type: "uint256" }
|
|
269
|
+
],
|
|
270
|
+
stateMutability: "payable",
|
|
271
|
+
type: "function"
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
inputs: [
|
|
275
|
+
{
|
|
276
|
+
components: [
|
|
277
|
+
{
|
|
278
|
+
components: [
|
|
279
|
+
{ internalType: "string", name: "name", type: "string" },
|
|
280
|
+
{ internalType: "string", name: "symbol", type: "string" },
|
|
281
|
+
{ internalType: "bytes32", name: "salt", type: "bytes32" },
|
|
282
|
+
{ internalType: "string", name: "image", type: "string" },
|
|
283
|
+
{ internalType: "string", name: "metadata", type: "string" },
|
|
284
|
+
{ internalType: "string", name: "context", type: "string" },
|
|
285
|
+
{ internalType: "uint256", name: "originatingChainId", type: "uint256" }
|
|
286
|
+
],
|
|
287
|
+
internalType: "struct IClanker.TokenConfig",
|
|
288
|
+
name: "tokenConfig",
|
|
289
|
+
type: "tuple"
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
components: [
|
|
293
|
+
{ internalType: "uint8", name: "vaultPercentage", type: "uint8" },
|
|
294
|
+
{ internalType: "uint256", name: "vaultDuration", type: "uint256" }
|
|
295
|
+
],
|
|
296
|
+
internalType: "struct IClanker.VaultConfig",
|
|
297
|
+
name: "vaultConfig",
|
|
298
|
+
type: "tuple"
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
components: [
|
|
302
|
+
{ internalType: "address", name: "pairedToken", type: "address" },
|
|
303
|
+
{ internalType: "int24", name: "tickIfToken0IsNewToken", type: "int24" }
|
|
304
|
+
],
|
|
305
|
+
internalType: "struct IClanker.PoolConfig",
|
|
306
|
+
name: "poolConfig",
|
|
307
|
+
type: "tuple"
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
components: [
|
|
311
|
+
{ internalType: "uint24", name: "pairedTokenPoolFee", type: "uint24" },
|
|
312
|
+
{ internalType: "uint256", name: "pairedTokenSwapAmountOutMinimum", type: "uint256" }
|
|
313
|
+
],
|
|
314
|
+
internalType: "struct IClanker.InitialBuyConfig",
|
|
315
|
+
name: "initialBuyConfig",
|
|
316
|
+
type: "tuple"
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
components: [
|
|
320
|
+
{ internalType: "uint256", name: "creatorReward", type: "uint256" },
|
|
321
|
+
{ internalType: "address", name: "creatorAdmin", type: "address" },
|
|
322
|
+
{ internalType: "address", name: "creatorRewardRecipient", type: "address" },
|
|
323
|
+
{ internalType: "address", name: "interfaceAdmin", type: "address" },
|
|
324
|
+
{ internalType: "address", name: "interfaceRewardRecipient", type: "address" }
|
|
325
|
+
],
|
|
326
|
+
internalType: "struct IClanker.RewardsConfig",
|
|
327
|
+
name: "rewardsConfig",
|
|
328
|
+
type: "tuple"
|
|
329
|
+
}
|
|
330
|
+
],
|
|
331
|
+
internalType: "struct IClanker.DeploymentConfig",
|
|
332
|
+
name: "deploymentConfig",
|
|
333
|
+
type: "tuple"
|
|
334
|
+
},
|
|
335
|
+
{ internalType: "address", name: "teamRewardRecipient", type: "address" }
|
|
336
|
+
],
|
|
337
|
+
name: "deployTokenWithCustomTeamRewardRecipient",
|
|
338
|
+
outputs: [
|
|
339
|
+
{ internalType: "address", name: "tokenAddress", type: "address" },
|
|
340
|
+
{ internalType: "uint256", name: "positionId", type: "uint256" }
|
|
341
|
+
],
|
|
342
|
+
stateMutability: "payable",
|
|
343
|
+
type: "function"
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
inputs: [
|
|
347
|
+
{
|
|
348
|
+
components: [
|
|
349
|
+
{ internalType: "string", name: "name", type: "string" },
|
|
350
|
+
{ internalType: "string", name: "symbol", type: "string" },
|
|
351
|
+
{ internalType: "bytes32", name: "salt", type: "bytes32" },
|
|
352
|
+
{ internalType: "string", name: "image", type: "string" },
|
|
353
|
+
{ internalType: "string", name: "metadata", type: "string" },
|
|
354
|
+
{ internalType: "string", name: "context", type: "string" },
|
|
355
|
+
{ internalType: "uint256", name: "originatingChainId", type: "uint256" }
|
|
356
|
+
],
|
|
357
|
+
internalType: "struct IClanker.TokenConfig",
|
|
358
|
+
name: "tokenConfig",
|
|
359
|
+
type: "tuple"
|
|
360
|
+
},
|
|
361
|
+
{ internalType: "address", name: "tokenAdmin", type: "address" }
|
|
362
|
+
],
|
|
363
|
+
name: "deployTokenZeroSupply",
|
|
364
|
+
outputs: [{ internalType: "address", name: "tokenAddress", type: "address" }],
|
|
365
|
+
stateMutability: "nonpayable",
|
|
366
|
+
type: "function"
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
inputs: [{ internalType: "address", name: "", type: "address" }],
|
|
370
|
+
name: "deploymentInfoForToken",
|
|
371
|
+
outputs: [
|
|
372
|
+
{ internalType: "address", name: "token", type: "address" },
|
|
373
|
+
{ internalType: "uint256", name: "positionId", type: "uint256" },
|
|
374
|
+
{ internalType: "address", name: "locker", type: "address" }
|
|
375
|
+
],
|
|
376
|
+
stateMutability: "view",
|
|
377
|
+
type: "function"
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
inputs: [],
|
|
381
|
+
name: "deprecated",
|
|
382
|
+
outputs: [{ internalType: "bool", name: "", type: "bool" }],
|
|
383
|
+
stateMutability: "view",
|
|
384
|
+
type: "function"
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
inputs: [{ internalType: "address", name: "user", type: "address" }],
|
|
388
|
+
name: "getTokensDeployedByUser",
|
|
389
|
+
outputs: [
|
|
390
|
+
{
|
|
391
|
+
components: [
|
|
392
|
+
{ internalType: "address", name: "token", type: "address" },
|
|
393
|
+
{ internalType: "uint256", name: "positionId", type: "uint256" },
|
|
394
|
+
{ internalType: "address", name: "locker", type: "address" }
|
|
395
|
+
],
|
|
396
|
+
internalType: "struct IClanker.DeploymentInfo[]",
|
|
397
|
+
name: "",
|
|
398
|
+
type: "tuple[]"
|
|
399
|
+
}
|
|
400
|
+
],
|
|
401
|
+
stateMutability: "view",
|
|
402
|
+
type: "function"
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
inputs: [
|
|
406
|
+
{ internalType: "address", name: "uniswapV3Factory_", type: "address" },
|
|
407
|
+
{ internalType: "address", name: "positionManager_", type: "address" },
|
|
408
|
+
{ internalType: "address", name: "swapRouter_", type: "address" },
|
|
409
|
+
{ internalType: "address", name: "weth_", type: "address" },
|
|
410
|
+
{ internalType: "address", name: "liquidityLocker_", type: "address" },
|
|
411
|
+
{ internalType: "address", name: "vault_", type: "address" }
|
|
412
|
+
],
|
|
413
|
+
name: "initialize",
|
|
414
|
+
outputs: [],
|
|
415
|
+
stateMutability: "nonpayable",
|
|
416
|
+
type: "function"
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
inputs: [],
|
|
420
|
+
name: "liquidityLocker",
|
|
421
|
+
outputs: [{ internalType: "contract ILpLockerv2", name: "", type: "address" }],
|
|
422
|
+
stateMutability: "view",
|
|
423
|
+
type: "function"
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
inputs: [],
|
|
427
|
+
name: "owner",
|
|
428
|
+
outputs: [{ internalType: "address", name: "", type: "address" }],
|
|
429
|
+
stateMutability: "view",
|
|
430
|
+
type: "function"
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
inputs: [],
|
|
434
|
+
name: "positionManager",
|
|
435
|
+
outputs: [{ internalType: "contract INonfungiblePositionManager", name: "", type: "address" }],
|
|
436
|
+
stateMutability: "view",
|
|
437
|
+
type: "function"
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
inputs: [],
|
|
441
|
+
name: "renounceOwnership",
|
|
442
|
+
outputs: [],
|
|
443
|
+
stateMutability: "nonpayable",
|
|
444
|
+
type: "function"
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
inputs: [
|
|
448
|
+
{ internalType: "address", name: "admin", type: "address" },
|
|
449
|
+
{ internalType: "bool", name: "isAdmin", type: "bool" }
|
|
450
|
+
],
|
|
451
|
+
name: "setAdmin",
|
|
452
|
+
outputs: [],
|
|
453
|
+
stateMutability: "nonpayable",
|
|
454
|
+
type: "function"
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
inputs: [{ internalType: "bool", name: "deprecated_", type: "bool" }],
|
|
458
|
+
name: "setDeprecated",
|
|
459
|
+
outputs: [],
|
|
460
|
+
stateMutability: "nonpayable",
|
|
461
|
+
type: "function"
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
inputs: [],
|
|
465
|
+
name: "swapRouter",
|
|
466
|
+
outputs: [{ internalType: "contract ISwapRouter", name: "", type: "address" }],
|
|
467
|
+
stateMutability: "view",
|
|
468
|
+
type: "function"
|
|
469
|
+
},
|
|
470
|
+
{
|
|
471
|
+
inputs: [
|
|
472
|
+
{ internalType: "address", name: "", type: "address" },
|
|
473
|
+
{ internalType: "uint256", name: "", type: "uint256" }
|
|
474
|
+
],
|
|
475
|
+
name: "tokensDeployedByUsers",
|
|
476
|
+
outputs: [
|
|
477
|
+
{ internalType: "address", name: "token", type: "address" },
|
|
478
|
+
{ internalType: "uint256", name: "positionId", type: "uint256" },
|
|
479
|
+
{ internalType: "address", name: "locker", type: "address" }
|
|
480
|
+
],
|
|
481
|
+
stateMutability: "view",
|
|
482
|
+
type: "function"
|
|
483
|
+
},
|
|
484
|
+
{
|
|
485
|
+
inputs: [{ internalType: "address", name: "newOwner", type: "address" }],
|
|
486
|
+
name: "transferOwnership",
|
|
487
|
+
outputs: [],
|
|
488
|
+
stateMutability: "nonpayable",
|
|
489
|
+
type: "function"
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
inputs: [],
|
|
493
|
+
name: "uniswapV3Factory",
|
|
494
|
+
outputs: [{ internalType: "contract IUniswapV3Factory", name: "", type: "address" }],
|
|
495
|
+
stateMutability: "view",
|
|
496
|
+
type: "function"
|
|
497
|
+
},
|
|
498
|
+
{
|
|
499
|
+
inputs: [{ internalType: "address", name: "newLocker", type: "address" }],
|
|
500
|
+
name: "updateLiquidityLocker",
|
|
501
|
+
outputs: [],
|
|
502
|
+
stateMutability: "nonpayable",
|
|
503
|
+
type: "function"
|
|
504
|
+
},
|
|
505
|
+
{
|
|
506
|
+
inputs: [{ internalType: "address", name: "newVault", type: "address" }],
|
|
507
|
+
name: "updateVault",
|
|
508
|
+
outputs: [],
|
|
509
|
+
stateMutability: "nonpayable",
|
|
510
|
+
type: "function"
|
|
511
|
+
},
|
|
512
|
+
{
|
|
513
|
+
inputs: [],
|
|
514
|
+
name: "vault",
|
|
515
|
+
outputs: [{ internalType: "contract IClankerVault", name: "", type: "address" }],
|
|
516
|
+
stateMutability: "view",
|
|
517
|
+
type: "function"
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
inputs: [],
|
|
521
|
+
name: "weth",
|
|
522
|
+
outputs: [{ internalType: "address", name: "", type: "address" }],
|
|
523
|
+
stateMutability: "view",
|
|
524
|
+
type: "function"
|
|
525
|
+
}
|
|
526
|
+
];
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
// src/types.ts
|
|
531
|
+
var init_types = __esm({
|
|
532
|
+
"src/types.ts"() {
|
|
533
|
+
"use strict";
|
|
534
|
+
init_esm_shims();
|
|
535
|
+
}
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
// src/index.ts
|
|
539
|
+
import {
|
|
540
|
+
parseEther,
|
|
541
|
+
parseUnits,
|
|
542
|
+
stringify,
|
|
543
|
+
parseEventLogs,
|
|
544
|
+
encodeFunctionData
|
|
545
|
+
} from "viem";
|
|
546
|
+
import { simulateContract, writeContract, readContract } from "viem/actions";
|
|
547
|
+
var ERC20_DECIMALS_ABI, UNIV3_FACTORY_ABI, UNIV3_POOL_ABI, UNIV3_FACTORY, FEE_TIERS, Clanker;
|
|
548
|
+
var init_index = __esm({
|
|
549
|
+
"src/index.ts"() {
|
|
550
|
+
"use strict";
|
|
551
|
+
init_esm_shims();
|
|
552
|
+
init_constants();
|
|
553
|
+
init_Clanker_V3_1();
|
|
554
|
+
init_types();
|
|
555
|
+
ERC20_DECIMALS_ABI = [
|
|
556
|
+
{
|
|
557
|
+
inputs: [],
|
|
558
|
+
name: "decimals",
|
|
559
|
+
outputs: [{ type: "uint8", name: "" }],
|
|
560
|
+
stateMutability: "view",
|
|
561
|
+
type: "function"
|
|
562
|
+
}
|
|
563
|
+
];
|
|
564
|
+
UNIV3_FACTORY_ABI = [
|
|
565
|
+
{
|
|
566
|
+
inputs: [
|
|
567
|
+
{ internalType: "address", name: "tokenA", type: "address" },
|
|
568
|
+
{ internalType: "address", name: "tokenB", type: "address" },
|
|
569
|
+
{ internalType: "uint24", name: "fee", type: "uint24" }
|
|
570
|
+
],
|
|
571
|
+
name: "getPool",
|
|
572
|
+
outputs: [{ internalType: "address", name: "", type: "address" }],
|
|
573
|
+
stateMutability: "view",
|
|
574
|
+
type: "function"
|
|
575
|
+
}
|
|
576
|
+
];
|
|
577
|
+
UNIV3_POOL_ABI = [
|
|
578
|
+
{
|
|
579
|
+
inputs: [],
|
|
580
|
+
name: "liquidity",
|
|
581
|
+
outputs: [{ internalType: "uint128", name: "", type: "uint128" }],
|
|
582
|
+
stateMutability: "view",
|
|
583
|
+
type: "function"
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
inputs: [],
|
|
587
|
+
name: "slot0",
|
|
588
|
+
outputs: [
|
|
589
|
+
{ internalType: "uint160", name: "sqrtPriceX96", type: "uint160" },
|
|
590
|
+
{ internalType: "int24", name: "tick", type: "int24" },
|
|
591
|
+
{ internalType: "uint16", name: "observationIndex", type: "uint16" },
|
|
592
|
+
{ internalType: "uint16", name: "observationCardinality", type: "uint16" },
|
|
593
|
+
{ internalType: "uint16", name: "observationCardinalityNext", type: "uint16" },
|
|
594
|
+
{ internalType: "uint8", name: "feeProtocol", type: "uint8" },
|
|
595
|
+
{ internalType: "bool", name: "unlocked", type: "bool" }
|
|
596
|
+
],
|
|
597
|
+
stateMutability: "view",
|
|
598
|
+
type: "function"
|
|
599
|
+
}
|
|
600
|
+
];
|
|
601
|
+
UNIV3_FACTORY = "0x33128a8fC17869897dcE68Ed026d694621f6FDfD";
|
|
602
|
+
FEE_TIERS = [100, 500, 3e3, 1e4];
|
|
603
|
+
Clanker = class {
|
|
604
|
+
wallet;
|
|
605
|
+
factoryAddress;
|
|
606
|
+
publicClient;
|
|
607
|
+
constructor(config2) {
|
|
608
|
+
this.wallet = config2.wallet;
|
|
609
|
+
this.publicClient = config2.publicClient;
|
|
610
|
+
this.factoryAddress = config2.factoryAddress ?? CLANKER_FACTORY_V3_1;
|
|
611
|
+
}
|
|
612
|
+
// Get quote token decimals
|
|
613
|
+
async getQuoteTokenDecimals(quoteToken) {
|
|
614
|
+
try {
|
|
615
|
+
const decimals = await readContract(this.publicClient, {
|
|
616
|
+
address: quoteToken,
|
|
617
|
+
abi: ERC20_DECIMALS_ABI,
|
|
618
|
+
functionName: "decimals"
|
|
619
|
+
});
|
|
620
|
+
return decimals;
|
|
621
|
+
} catch (error) {
|
|
622
|
+
console.warn(`Failed to fetch decimals for quote token ${quoteToken}, defaulting to 18:`, error);
|
|
623
|
+
return 18;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
// Find the most liquid pool between WETH and quote token
|
|
627
|
+
async findMostLiquidPool(quoteToken) {
|
|
628
|
+
const pools = await Promise.all(
|
|
629
|
+
FEE_TIERS.map(async (fee) => {
|
|
630
|
+
try {
|
|
631
|
+
const poolAddress = await readContract(this.publicClient, {
|
|
632
|
+
address: UNIV3_FACTORY,
|
|
633
|
+
abi: UNIV3_FACTORY_ABI,
|
|
634
|
+
functionName: "getPool",
|
|
635
|
+
args: [WETH_ADDRESS, quoteToken, fee]
|
|
636
|
+
});
|
|
637
|
+
if (poolAddress === "0x0000000000000000000000000000000000000000") {
|
|
638
|
+
return { fee, liquidity: 0n, sqrtPriceX96: 0n };
|
|
639
|
+
}
|
|
640
|
+
const [liquidity, slot0] = await Promise.all([
|
|
641
|
+
readContract(this.publicClient, {
|
|
642
|
+
address: poolAddress,
|
|
643
|
+
abi: UNIV3_POOL_ABI,
|
|
644
|
+
functionName: "liquidity"
|
|
645
|
+
}),
|
|
646
|
+
readContract(this.publicClient, {
|
|
647
|
+
address: poolAddress,
|
|
648
|
+
abi: UNIV3_POOL_ABI,
|
|
649
|
+
functionName: "slot0"
|
|
650
|
+
})
|
|
651
|
+
]);
|
|
652
|
+
return { fee, liquidity, sqrtPriceX96: slot0[0] };
|
|
653
|
+
} catch (error) {
|
|
654
|
+
console.warn(`Failed to get pool info for fee tier ${fee}:`, error);
|
|
655
|
+
return { fee, liquidity: 0n, sqrtPriceX96: 0n };
|
|
656
|
+
}
|
|
657
|
+
})
|
|
658
|
+
);
|
|
659
|
+
const mostLiquidPool = pools.reduce(
|
|
660
|
+
(max, current) => current.liquidity > max.liquidity ? current : max
|
|
661
|
+
);
|
|
662
|
+
if (mostLiquidPool.liquidity === 0n) {
|
|
663
|
+
console.warn("No liquid pool found, defaulting to 1% fee tier");
|
|
664
|
+
return { fee: 1e4, sqrtPriceX96: 0n };
|
|
665
|
+
}
|
|
666
|
+
return { fee: mostLiquidPool.fee, sqrtPriceX96: mostLiquidPool.sqrtPriceX96 };
|
|
667
|
+
}
|
|
668
|
+
// Calculate minimum output amount for WETH -> quote token swap
|
|
669
|
+
calculateMinimumOutput(ethAmount, sqrtPriceX96, quoteDecimals, slippagePercent) {
|
|
670
|
+
if (sqrtPriceX96 === 0n) {
|
|
671
|
+
return 0n;
|
|
672
|
+
}
|
|
673
|
+
const Q96 = BigInt("79228162514264337593543950336");
|
|
674
|
+
const price = (Number(sqrtPriceX96) / Number(Q96)) ** 2;
|
|
675
|
+
const ethDecimals = 18;
|
|
676
|
+
const ethAmountInEth = Number(ethAmount) / 10 ** ethDecimals;
|
|
677
|
+
const expectedOutput = ethAmountInEth * price;
|
|
678
|
+
const minimumOutput = expectedOutput * (1 - slippagePercent / 100);
|
|
679
|
+
return BigInt(Math.floor(minimumOutput * 10 ** quoteDecimals));
|
|
680
|
+
}
|
|
681
|
+
// Calculate tick based on quote token and token ordering
|
|
682
|
+
async calculateTickForQuoteToken(quoteToken, marketCap) {
|
|
683
|
+
const quoteDecimals = await this.getQuoteTokenDecimals(quoteToken);
|
|
684
|
+
console.log("Quote token decimals:", quoteDecimals);
|
|
685
|
+
const tokenDecimals = 18;
|
|
686
|
+
const totalSupply = BigInt(1e11) * BigInt(10) ** BigInt(tokenDecimals);
|
|
687
|
+
const priceInQuoteToken = Number(marketCap) / Number(totalSupply);
|
|
688
|
+
console.log("Price in quote token:", priceInQuoteToken);
|
|
689
|
+
console.log("Market cap in quote token units:", Number(marketCap) / 10 ** quoteDecimals);
|
|
690
|
+
const logBase = 1.0001;
|
|
691
|
+
const tickSpacing = 200;
|
|
692
|
+
const dummyTokenAddress = "0xffffffffffffffffffffffffffffffffffffffff";
|
|
693
|
+
const isToken0 = dummyTokenAddress.toLowerCase() < quoteToken.toLowerCase();
|
|
694
|
+
console.log("Is new token token0?", isToken0);
|
|
695
|
+
const priceForTick = isToken0 ? priceInQuoteToken : 1 / priceInQuoteToken;
|
|
696
|
+
let rawTick = Math.floor(Math.log(priceForTick) / Math.log(logBase));
|
|
697
|
+
if (!isToken0) {
|
|
698
|
+
rawTick = -rawTick;
|
|
699
|
+
}
|
|
700
|
+
console.log("Raw tick (before spacing):", rawTick);
|
|
701
|
+
const initialTick = Math.floor(rawTick / tickSpacing) * tickSpacing;
|
|
702
|
+
console.log("Final tick (rounded to spacing):", initialTick);
|
|
703
|
+
const actualPrice = Math.pow(logBase, isToken0 ? initialTick : -initialTick);
|
|
704
|
+
console.log("Actual price from tick:", actualPrice);
|
|
705
|
+
const finalPrice = isToken0 ? actualPrice : 1 / actualPrice;
|
|
706
|
+
const actualMarketCap = finalPrice * Number(totalSupply) / Math.pow(10, tokenDecimals);
|
|
707
|
+
console.log("Actual market cap in quote token:", actualMarketCap);
|
|
708
|
+
return initialTick;
|
|
709
|
+
}
|
|
710
|
+
handleError(error) {
|
|
711
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
712
|
+
throw new Error(`Deployment failed: ${message}`);
|
|
713
|
+
}
|
|
714
|
+
async deploy(config2) {
|
|
715
|
+
if (!this.wallet?.account) {
|
|
716
|
+
throw new Error("Wallet account not configured");
|
|
717
|
+
}
|
|
718
|
+
try {
|
|
719
|
+
const rewardsConfig = config2.rewardsConfig;
|
|
720
|
+
const tick = await this.calculateTickForQuoteToken(
|
|
721
|
+
config2.poolConfig.pairedToken,
|
|
722
|
+
config2.poolConfig.initialMarketCapInPairedToken
|
|
723
|
+
);
|
|
724
|
+
const deploymentData = {
|
|
725
|
+
tokenConfig: {
|
|
726
|
+
name: config2.tokenConfig.name,
|
|
727
|
+
symbol: config2.tokenConfig.symbol,
|
|
728
|
+
salt: config2.tokenConfig.salt,
|
|
729
|
+
image: config2.tokenConfig.image,
|
|
730
|
+
metadata: stringify(config2.tokenConfig.metadata),
|
|
731
|
+
context: stringify(config2.tokenConfig.context),
|
|
732
|
+
originatingChainId: config2.tokenConfig.originatingChainId
|
|
733
|
+
},
|
|
734
|
+
vaultConfig: {
|
|
735
|
+
vaultPercentage: config2.vaultConfig?.vaultPercentage ?? 0,
|
|
736
|
+
vaultDuration: config2.vaultConfig?.vaultDuration ?? BigInt(0)
|
|
737
|
+
},
|
|
738
|
+
poolConfig: {
|
|
739
|
+
pairedToken: config2.poolConfig.pairedToken,
|
|
740
|
+
tickIfToken0IsNewToken: tick
|
|
741
|
+
},
|
|
742
|
+
initialBuyConfig: {
|
|
743
|
+
pairedTokenPoolFee: config2.initialBuyConfig?.pairedTokenPoolFee ?? 1e4,
|
|
744
|
+
pairedTokenSwapAmountOutMinimum: config2.initialBuyConfig?.pairedTokenSwapAmountOutMinimum ?? BigInt(0)
|
|
745
|
+
},
|
|
746
|
+
rewardsConfig: {
|
|
747
|
+
creatorReward: rewardsConfig.creatorReward,
|
|
748
|
+
creatorAdmin: rewardsConfig.creatorAdmin,
|
|
749
|
+
creatorRewardRecipient: rewardsConfig.creatorRewardRecipient,
|
|
750
|
+
interfaceAdmin: rewardsConfig.interfaceAdmin,
|
|
751
|
+
interfaceRewardRecipient: rewardsConfig.interfaceRewardRecipient
|
|
752
|
+
}
|
|
753
|
+
};
|
|
754
|
+
const { request } = await simulateContract(this.publicClient, {
|
|
755
|
+
address: this.factoryAddress,
|
|
756
|
+
abi: Clanker_v3_1_abi,
|
|
757
|
+
functionName: "deployToken",
|
|
758
|
+
args: [deploymentData],
|
|
759
|
+
value: config2.initialBuyConfig?.ethAmount ?? BigInt(0),
|
|
760
|
+
chain: this.publicClient.chain,
|
|
761
|
+
account: this.wallet.account
|
|
762
|
+
});
|
|
763
|
+
const hash = await writeContract(this.wallet, request);
|
|
764
|
+
const receipt = await this.publicClient.waitForTransactionReceipt({
|
|
765
|
+
hash
|
|
766
|
+
});
|
|
767
|
+
const [log] = parseEventLogs({
|
|
768
|
+
abi: Clanker_v3_1_abi,
|
|
769
|
+
eventName: "TokenCreated",
|
|
770
|
+
logs: receipt.logs
|
|
771
|
+
});
|
|
772
|
+
if (!log) {
|
|
773
|
+
throw new Error("No deployment event found");
|
|
774
|
+
}
|
|
775
|
+
return log.args.tokenAddress;
|
|
776
|
+
} catch (error) {
|
|
777
|
+
this.handleError(error);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
async buildDeploymentConfig(cfg) {
|
|
781
|
+
const quoteToken = cfg.pool?.quoteToken ?? WETH_ADDRESS;
|
|
782
|
+
const quoteDecimals = await this.getQuoteTokenDecimals(quoteToken);
|
|
783
|
+
console.log("Quote token decimals:", quoteDecimals);
|
|
784
|
+
const marketCap = parseUnits(
|
|
785
|
+
cfg.pool?.initialMarketCap ?? "100",
|
|
786
|
+
quoteDecimals
|
|
787
|
+
);
|
|
788
|
+
const tick = await this.calculateTickForQuoteToken(
|
|
789
|
+
quoteToken,
|
|
790
|
+
marketCap
|
|
791
|
+
);
|
|
792
|
+
let initialBuyConfig = {
|
|
793
|
+
pairedTokenPoolFee: 1e4,
|
|
794
|
+
// Default to 1%
|
|
795
|
+
pairedTokenSwapAmountOutMinimum: BigInt(0),
|
|
796
|
+
ethAmount: void 0
|
|
797
|
+
};
|
|
798
|
+
if (cfg.devBuy) {
|
|
799
|
+
const ethAmount = parseEther(cfg.devBuy.ethAmount);
|
|
800
|
+
const { fee, sqrtPriceX96 } = await this.findMostLiquidPool(quoteToken);
|
|
801
|
+
const minOutput = this.calculateMinimumOutput(
|
|
802
|
+
ethAmount,
|
|
803
|
+
sqrtPriceX96,
|
|
804
|
+
quoteDecimals,
|
|
805
|
+
cfg.devBuy.maxSlippage ?? 5
|
|
806
|
+
);
|
|
807
|
+
initialBuyConfig = {
|
|
808
|
+
pairedTokenPoolFee: fee,
|
|
809
|
+
pairedTokenSwapAmountOutMinimum: minOutput,
|
|
810
|
+
ethAmount
|
|
811
|
+
};
|
|
812
|
+
console.log("Dev buy configuration:", {
|
|
813
|
+
ethAmount: cfg.devBuy.ethAmount,
|
|
814
|
+
fee,
|
|
815
|
+
minOutput: minOutput.toString()
|
|
816
|
+
});
|
|
817
|
+
}
|
|
818
|
+
const deployerAddress = this.wallet?.account?.address ?? "0x0000000000000000000000000000000000000000";
|
|
819
|
+
return {
|
|
820
|
+
tokenConfig: {
|
|
821
|
+
name: cfg.name,
|
|
822
|
+
symbol: cfg.symbol,
|
|
823
|
+
salt: cfg.salt || "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
824
|
+
image: cfg.image || "https://ipfs.io/ipfs/QmcjfTeK3tpK3MVCQuvEaXvSscrqbL3MwsEo8LdBTWabY4",
|
|
825
|
+
metadata: JSON.stringify(cfg.metadata || {
|
|
826
|
+
description: "Clanker Token",
|
|
827
|
+
socialMediaUrls: [],
|
|
828
|
+
auditUrls: []
|
|
829
|
+
}),
|
|
830
|
+
context: JSON.stringify(cfg.context || {
|
|
831
|
+
interface: "Clanker SDK",
|
|
832
|
+
platform: "Clanker",
|
|
833
|
+
messageId: "Clanker SDK",
|
|
834
|
+
id: "Clanker SDK"
|
|
835
|
+
}),
|
|
836
|
+
originatingChainId: BigInt(this.publicClient.chain.id)
|
|
837
|
+
},
|
|
838
|
+
poolConfig: {
|
|
839
|
+
pairedToken: quoteToken,
|
|
840
|
+
tickIfToken0IsNewToken: tick,
|
|
841
|
+
initialMarketCapInPairedToken: marketCap
|
|
842
|
+
},
|
|
843
|
+
vaultConfig: cfg.vault ? {
|
|
844
|
+
vaultPercentage: cfg.vault.percentage,
|
|
845
|
+
vaultDuration: BigInt(cfg.vault.durationInDays * 24 * 60 * 60)
|
|
846
|
+
} : {
|
|
847
|
+
vaultPercentage: 0,
|
|
848
|
+
vaultDuration: 0n
|
|
849
|
+
},
|
|
850
|
+
initialBuyConfig,
|
|
851
|
+
rewardsConfig: {
|
|
852
|
+
creatorReward: BigInt(40),
|
|
853
|
+
// Default to 40% creator reward
|
|
854
|
+
creatorAdmin: deployerAddress,
|
|
855
|
+
creatorRewardRecipient: deployerAddress,
|
|
856
|
+
interfaceAdmin: deployerAddress,
|
|
857
|
+
interfaceRewardRecipient: deployerAddress
|
|
858
|
+
}
|
|
859
|
+
};
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* Creates calldata (+ msg.value) **without** sending a transaction.
|
|
863
|
+
* This version no longer relies on viem's `simulateContract`, which
|
|
864
|
+
* was returning an object without `.data`. We now ABI-encode the
|
|
865
|
+
* call manually so `data` is always defined.
|
|
866
|
+
*/
|
|
867
|
+
async prepareDeployToken(cfg) {
|
|
868
|
+
const deploymentConfig = await this.buildDeploymentConfig(cfg);
|
|
869
|
+
const data = encodeFunctionData({
|
|
870
|
+
abi: Clanker_v3_1_abi,
|
|
871
|
+
functionName: "deployToken",
|
|
872
|
+
args: [deploymentConfig]
|
|
873
|
+
});
|
|
874
|
+
const value = deploymentConfig.initialBuyConfig?.ethAmount ?? 0n;
|
|
875
|
+
return {
|
|
876
|
+
to: this.factoryAddress,
|
|
877
|
+
data,
|
|
878
|
+
// 0x-prefixed hex string (non-empty)
|
|
879
|
+
value
|
|
880
|
+
};
|
|
881
|
+
}
|
|
882
|
+
async deployToken(cfg) {
|
|
883
|
+
if (!this.wallet) throw new Error("Wallet client required for deployToken");
|
|
884
|
+
if (!this.wallet.account) throw new Error("Wallet account required for deployToken");
|
|
885
|
+
const tx = await this.prepareDeployToken(cfg);
|
|
886
|
+
const hash = await this.wallet.sendTransaction({
|
|
887
|
+
...tx,
|
|
888
|
+
account: this.wallet.account,
|
|
889
|
+
chain: this.publicClient.chain
|
|
890
|
+
});
|
|
891
|
+
const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
|
|
892
|
+
const [log] = parseEventLogs({
|
|
893
|
+
abi: Clanker_v3_1_abi,
|
|
894
|
+
eventName: "TokenCreated",
|
|
895
|
+
logs: receipt.logs
|
|
896
|
+
});
|
|
897
|
+
if (!log) throw new Error("No deployment event found");
|
|
898
|
+
return log.args.tokenAddress;
|
|
899
|
+
}
|
|
900
|
+
};
|
|
901
|
+
}
|
|
902
|
+
});
|
|
903
|
+
|
|
904
|
+
// src/cli/create-clanker.ts
|
|
905
|
+
var create_clanker_exports = {};
|
|
906
|
+
__export(create_clanker_exports, {
|
|
907
|
+
default: () => createClanker
|
|
908
|
+
});
|
|
909
|
+
import inquirer from "inquirer";
|
|
910
|
+
import { createPublicClient, createWalletClient, http } from "viem";
|
|
911
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
912
|
+
import { base } from "viem/chains";
|
|
913
|
+
import * as dotenv from "dotenv";
|
|
914
|
+
async function createClanker() {
|
|
915
|
+
const args = process.argv.slice(2);
|
|
916
|
+
if (args.length === 0 || args[0] !== "--create" && args[0] !== "create") {
|
|
917
|
+
console.log("\n\u{1F680} Clanker SDK CLI\n");
|
|
918
|
+
console.log("Available commands:");
|
|
919
|
+
console.log(" --create Create a new token");
|
|
920
|
+
console.log("\nExample:");
|
|
921
|
+
console.log(" npx clanker-sdk --create\n");
|
|
922
|
+
process.exit(0);
|
|
923
|
+
}
|
|
924
|
+
const PRIVATE_KEY = process.env.PRIVATE_KEY;
|
|
925
|
+
const FACTORY_ADDRESS = process.env.FACTORY_ADDRESS;
|
|
926
|
+
const RPC_URL = process.env.RPC_URL;
|
|
927
|
+
const WETH_ADDRESS2 = "0x4200000000000000000000000000000000000006";
|
|
928
|
+
const USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
929
|
+
function checkEnvironment() {
|
|
930
|
+
const missingVars = [];
|
|
931
|
+
if (!PRIVATE_KEY) missingVars.push("PRIVATE_KEY");
|
|
932
|
+
if (!FACTORY_ADDRESS) missingVars.push("FACTORY_ADDRESS");
|
|
933
|
+
if (missingVars.length > 0) {
|
|
934
|
+
console.log("\n\u274C Missing required environment variables:");
|
|
935
|
+
console.log(missingVars.join(", "));
|
|
936
|
+
console.log("\n\u{1F4DD} Please create a .env file in your current directory with the following variables:");
|
|
937
|
+
console.log(`
|
|
938
|
+
Required:
|
|
939
|
+
PRIVATE_KEY=your_private_key_here
|
|
940
|
+
FACTORY_ADDRESS=factory_contract_address_here
|
|
941
|
+
|
|
942
|
+
Optional:
|
|
943
|
+
RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
944
|
+
`);
|
|
945
|
+
console.log("\nMake sure to include the 0x prefix for addresses and private keys.");
|
|
946
|
+
console.log("Never share or commit your private key!\n");
|
|
947
|
+
return false;
|
|
948
|
+
}
|
|
949
|
+
if (!PRIVATE_KEY.startsWith("0x") || PRIVATE_KEY.length !== 66) {
|
|
950
|
+
console.log("\n\u274C Invalid PRIVATE_KEY format. It should:");
|
|
951
|
+
console.log("- Start with 0x");
|
|
952
|
+
console.log("- Be 64 characters long (plus 0x prefix)");
|
|
953
|
+
return false;
|
|
954
|
+
}
|
|
955
|
+
if (!FACTORY_ADDRESS.startsWith("0x") || FACTORY_ADDRESS.length !== 42) {
|
|
956
|
+
console.log("\n\u274C Invalid FACTORY_ADDRESS format. It should:");
|
|
957
|
+
console.log("- Start with 0x");
|
|
958
|
+
console.log("- Be 40 characters long (plus 0x prefix)");
|
|
959
|
+
return false;
|
|
960
|
+
}
|
|
961
|
+
return true;
|
|
962
|
+
}
|
|
963
|
+
const validateAddress = (input) => {
|
|
964
|
+
if (!input) return "Address cannot be empty";
|
|
965
|
+
if (!/^0x[a-fA-F0-9]{40}$/.test(input)) return "Invalid Ethereum address";
|
|
966
|
+
return true;
|
|
967
|
+
};
|
|
968
|
+
const validatePercentage = (input) => {
|
|
969
|
+
const num = Number(input);
|
|
970
|
+
if (isNaN(num)) return "Must be a number";
|
|
971
|
+
if (num < 0 || num > 100) return "Percentage must be between 0 and 100";
|
|
972
|
+
return true;
|
|
973
|
+
};
|
|
974
|
+
const validateSymbol = (input) => {
|
|
975
|
+
if (!input) return "Symbol cannot be empty";
|
|
976
|
+
if (!/^[A-Z0-9]+$/.test(input)) return "Symbol must contain only uppercase letters and numbers";
|
|
977
|
+
if (input.length > 10) return "Symbol must be 10 characters or less";
|
|
978
|
+
return true;
|
|
979
|
+
};
|
|
980
|
+
const validateIpfsUri = (input) => {
|
|
981
|
+
if (!input) return "Image URI cannot be empty";
|
|
982
|
+
if (!input.startsWith("ipfs://")) return "Image URI must start with ipfs://";
|
|
983
|
+
return true;
|
|
984
|
+
};
|
|
985
|
+
const validateAmount = (input) => {
|
|
986
|
+
if (!input) return "Amount cannot be empty";
|
|
987
|
+
if (!/^\d*\.?\d+$/.test(input)) return "Must be a valid number";
|
|
988
|
+
return true;
|
|
989
|
+
};
|
|
990
|
+
const validateHexString = (input) => {
|
|
991
|
+
if (!input) return true;
|
|
992
|
+
if (!/^0x[a-fA-F0-9]+$/.test(input)) return "Must be a valid hex string starting with 0x";
|
|
993
|
+
return true;
|
|
994
|
+
};
|
|
995
|
+
const validateSlippage = (input) => {
|
|
996
|
+
const num = Number(input);
|
|
997
|
+
if (isNaN(num)) return "Must be a number";
|
|
998
|
+
if (num < 0 || num > 100) return "Slippage must be between 0 and 100";
|
|
999
|
+
return true;
|
|
1000
|
+
};
|
|
1001
|
+
const validateVaultPercentage = (input) => {
|
|
1002
|
+
const num = Number(input);
|
|
1003
|
+
if (isNaN(num)) return "Must be a number";
|
|
1004
|
+
if (num < 0 || num > 30) return "Vault percentage must be between 0 and 30%";
|
|
1005
|
+
return true;
|
|
1006
|
+
};
|
|
1007
|
+
const validateVaultDuration = (input) => {
|
|
1008
|
+
const num = Number(input);
|
|
1009
|
+
if (isNaN(num)) return "Must be a number";
|
|
1010
|
+
if (num < 30) return "Vault duration must be at least 30 days";
|
|
1011
|
+
return true;
|
|
1012
|
+
};
|
|
1013
|
+
const validateCreatorReward = (input) => {
|
|
1014
|
+
const num = Number(input);
|
|
1015
|
+
if (isNaN(num)) return "Must be a number";
|
|
1016
|
+
if (num < 0 || num > 80) return "Creator reward must be between 0 and 80%";
|
|
1017
|
+
return true;
|
|
1018
|
+
};
|
|
1019
|
+
const validateUrl = (input) => {
|
|
1020
|
+
if (!input) return true;
|
|
1021
|
+
try {
|
|
1022
|
+
new URL(input);
|
|
1023
|
+
return true;
|
|
1024
|
+
} catch (e) {
|
|
1025
|
+
return "Please enter a valid URL";
|
|
1026
|
+
}
|
|
1027
|
+
};
|
|
1028
|
+
async function promptUser() {
|
|
1029
|
+
const questions = [
|
|
1030
|
+
{
|
|
1031
|
+
type: "input",
|
|
1032
|
+
name: "name",
|
|
1033
|
+
message: "Token name:",
|
|
1034
|
+
validate: (input) => input.length > 0 || "Name cannot be empty"
|
|
1035
|
+
},
|
|
1036
|
+
{
|
|
1037
|
+
type: "input",
|
|
1038
|
+
name: "symbol",
|
|
1039
|
+
message: "Token symbol:",
|
|
1040
|
+
validate: validateSymbol
|
|
1041
|
+
},
|
|
1042
|
+
{
|
|
1043
|
+
type: "list",
|
|
1044
|
+
name: "pairedTokenChoice",
|
|
1045
|
+
message: "Select quote token:",
|
|
1046
|
+
choices: [
|
|
1047
|
+
{ name: "WETH", value: "WETH" },
|
|
1048
|
+
{ name: "USDC", value: "USDC" },
|
|
1049
|
+
{ name: "Custom Address", value: "CUSTOM" }
|
|
1050
|
+
],
|
|
1051
|
+
default: "WETH"
|
|
1052
|
+
},
|
|
1053
|
+
{
|
|
1054
|
+
type: "input",
|
|
1055
|
+
name: "customPairedToken",
|
|
1056
|
+
message: "Enter custom token address:",
|
|
1057
|
+
validate: validateAddress,
|
|
1058
|
+
when: (answers2) => answers2.pairedTokenChoice === "CUSTOM"
|
|
1059
|
+
},
|
|
1060
|
+
{
|
|
1061
|
+
type: "input",
|
|
1062
|
+
name: "initialMarketCapUsd",
|
|
1063
|
+
message: (answers2) => `Enter initial market cap in ${answers2.pairedTokenChoice === "CUSTOM" ? "quote token" : answers2.pairedTokenChoice}:`,
|
|
1064
|
+
validate: validateAmount,
|
|
1065
|
+
default: (answers2) => answers2.pairedTokenChoice === "WETH" ? "1" : answers2.pairedTokenChoice === "USDC" ? "1000" : "1"
|
|
1066
|
+
},
|
|
1067
|
+
{
|
|
1068
|
+
type: "input",
|
|
1069
|
+
name: "customMarketCap",
|
|
1070
|
+
message: "Enter custom market cap in quote token:",
|
|
1071
|
+
validate: validateAmount,
|
|
1072
|
+
when: (answers2) => answers2.initialMarketCapUsd === "CUSTOM"
|
|
1073
|
+
},
|
|
1074
|
+
{
|
|
1075
|
+
type: "input",
|
|
1076
|
+
name: "image",
|
|
1077
|
+
message: "Enter the IPFS URI for the token image:",
|
|
1078
|
+
validate: validateIpfsUri
|
|
1079
|
+
},
|
|
1080
|
+
{
|
|
1081
|
+
type: "list",
|
|
1082
|
+
name: "devBuy.ethAmount",
|
|
1083
|
+
message: "Creator buy amount (optional):",
|
|
1084
|
+
choices: [
|
|
1085
|
+
{ name: "None", value: "0" },
|
|
1086
|
+
{ name: "0.00005 ETH", value: "0.00005" },
|
|
1087
|
+
{ name: "0.1 ETH", value: "0.1" },
|
|
1088
|
+
{ name: "0.5 ETH", value: "0.5" },
|
|
1089
|
+
{ name: "1.0 ETH", value: "1.0" },
|
|
1090
|
+
{ name: "Custom", value: "CUSTOM" }
|
|
1091
|
+
],
|
|
1092
|
+
default: "0"
|
|
1093
|
+
},
|
|
1094
|
+
{
|
|
1095
|
+
type: "input",
|
|
1096
|
+
name: "customDevBuy",
|
|
1097
|
+
message: "Enter custom dev buy amount in ETH:",
|
|
1098
|
+
validate: validateAmount,
|
|
1099
|
+
when: (answers2) => answers2.devBuy.ethAmount === "CUSTOM"
|
|
1100
|
+
},
|
|
1101
|
+
{
|
|
1102
|
+
type: "input",
|
|
1103
|
+
name: "devBuy.maxSlippage",
|
|
1104
|
+
message: "Maximum slippage percentage (0-100):",
|
|
1105
|
+
validate: validateSlippage,
|
|
1106
|
+
default: "5",
|
|
1107
|
+
when: (answers2) => answers2.devBuy.ethAmount !== "0"
|
|
1108
|
+
},
|
|
1109
|
+
{
|
|
1110
|
+
type: "list",
|
|
1111
|
+
name: "vaultConfig.vaultPercentage",
|
|
1112
|
+
message: "Vault percentage (optional):",
|
|
1113
|
+
choices: [
|
|
1114
|
+
{ name: "None", value: "0" },
|
|
1115
|
+
{ name: "5%", value: "5" },
|
|
1116
|
+
{ name: "15%", value: "15" },
|
|
1117
|
+
{ name: "30%", value: "30" },
|
|
1118
|
+
{ name: "Custom", value: "CUSTOM" }
|
|
1119
|
+
],
|
|
1120
|
+
default: "0"
|
|
1121
|
+
},
|
|
1122
|
+
{
|
|
1123
|
+
type: "input",
|
|
1124
|
+
name: "customVaultPercentage",
|
|
1125
|
+
message: "Enter custom vault percentage (0-30):",
|
|
1126
|
+
validate: validateVaultPercentage,
|
|
1127
|
+
when: (answers2) => answers2.vaultConfig.vaultPercentage === "CUSTOM"
|
|
1128
|
+
},
|
|
1129
|
+
{
|
|
1130
|
+
type: "list",
|
|
1131
|
+
name: "vaultConfig.durationInDays",
|
|
1132
|
+
message: "Vault duration:",
|
|
1133
|
+
choices: [
|
|
1134
|
+
{ name: "31 days", value: "31" },
|
|
1135
|
+
{ name: "90 days", value: "90" },
|
|
1136
|
+
{ name: "180 days", value: "180" },
|
|
1137
|
+
{ name: "Custom", value: "CUSTOM" }
|
|
1138
|
+
],
|
|
1139
|
+
default: "31",
|
|
1140
|
+
when: (answers2) => answers2.vaultConfig.vaultPercentage !== "0"
|
|
1141
|
+
},
|
|
1142
|
+
{
|
|
1143
|
+
type: "input",
|
|
1144
|
+
name: "customVaultDuration",
|
|
1145
|
+
message: "Enter custom vault duration in days (minimum 30):",
|
|
1146
|
+
validate: validateVaultDuration,
|
|
1147
|
+
when: (answers2) => answers2.vaultConfig.durationInDays === "CUSTOM"
|
|
1148
|
+
},
|
|
1149
|
+
{
|
|
1150
|
+
type: "input",
|
|
1151
|
+
name: "metadata.description",
|
|
1152
|
+
message: "Token description:",
|
|
1153
|
+
default: (answers2) => `${answers2.name} token deployed via Clanker CLI`,
|
|
1154
|
+
validate: (input) => input.length > 0 || "Description cannot be empty"
|
|
1155
|
+
},
|
|
1156
|
+
{
|
|
1157
|
+
type: "input",
|
|
1158
|
+
name: "metadata.telegram",
|
|
1159
|
+
message: "Telegram URL (optional):",
|
|
1160
|
+
validate: validateUrl
|
|
1161
|
+
},
|
|
1162
|
+
{
|
|
1163
|
+
type: "input",
|
|
1164
|
+
name: "metadata.website",
|
|
1165
|
+
message: "Website URL (optional):",
|
|
1166
|
+
validate: validateUrl
|
|
1167
|
+
},
|
|
1168
|
+
{
|
|
1169
|
+
type: "input",
|
|
1170
|
+
name: "metadata.twitter",
|
|
1171
|
+
message: "X/Twitter URL (optional):",
|
|
1172
|
+
validate: validateUrl
|
|
1173
|
+
},
|
|
1174
|
+
{
|
|
1175
|
+
type: "input",
|
|
1176
|
+
name: "metadata.farcaster",
|
|
1177
|
+
message: "Farcaster URL (optional):",
|
|
1178
|
+
validate: validateUrl
|
|
1179
|
+
}
|
|
1180
|
+
];
|
|
1181
|
+
const answers = await inquirer.prompt(questions);
|
|
1182
|
+
if (answers.initialMarketCapUsd === "CUSTOM") {
|
|
1183
|
+
answers.initialMarketCapUsd = answers.customMarketCap || "0";
|
|
1184
|
+
}
|
|
1185
|
+
if (answers.devBuy.ethAmount === "CUSTOM") {
|
|
1186
|
+
answers.devBuy.ethAmount = answers.customDevBuy || "0";
|
|
1187
|
+
}
|
|
1188
|
+
const vaultPercentage = answers.vaultConfig.vaultPercentage === "CUSTOM" ? parseInt(answers.customVaultPercentage || "0", 10) : parseInt(answers.vaultConfig.vaultPercentage, 10);
|
|
1189
|
+
const vaultDuration = answers.vaultConfig.durationInDays === "CUSTOM" ? parseInt(answers.customVaultDuration || "31", 10) : parseInt(answers.vaultConfig.durationInDays, 10);
|
|
1190
|
+
const socialMediaUrls = [];
|
|
1191
|
+
if (answers.metadata.telegram) socialMediaUrls.push(answers.metadata.telegram);
|
|
1192
|
+
if (answers.metadata.website) socialMediaUrls.push(answers.metadata.website);
|
|
1193
|
+
if (answers.metadata.twitter) socialMediaUrls.push(answers.metadata.twitter);
|
|
1194
|
+
if (answers.metadata.farcaster) socialMediaUrls.push(answers.metadata.farcaster);
|
|
1195
|
+
const metadata = {
|
|
1196
|
+
description: answers.metadata.description,
|
|
1197
|
+
socialMediaUrls,
|
|
1198
|
+
auditUrls: []
|
|
1199
|
+
};
|
|
1200
|
+
return {
|
|
1201
|
+
...answers,
|
|
1202
|
+
metadata,
|
|
1203
|
+
vaultConfig: {
|
|
1204
|
+
vaultPercentage: vaultPercentage.toString(),
|
|
1205
|
+
durationInDays: vaultDuration.toString()
|
|
1206
|
+
}
|
|
1207
|
+
};
|
|
1208
|
+
}
|
|
1209
|
+
async function deployToken(answers) {
|
|
1210
|
+
if (!PRIVATE_KEY || !FACTORY_ADDRESS) {
|
|
1211
|
+
throw new Error("Missing required environment variables (PRIVATE_KEY, FACTORY_ADDRESS)");
|
|
1212
|
+
}
|
|
1213
|
+
const account = privateKeyToAccount(PRIVATE_KEY);
|
|
1214
|
+
const transport = RPC_URL ? http(RPC_URL) : http();
|
|
1215
|
+
const publicClient = createPublicClient({
|
|
1216
|
+
chain: base,
|
|
1217
|
+
transport
|
|
1218
|
+
});
|
|
1219
|
+
const walletClient = createWalletClient({
|
|
1220
|
+
account,
|
|
1221
|
+
chain: base,
|
|
1222
|
+
transport
|
|
1223
|
+
});
|
|
1224
|
+
const clanker = new Clanker({
|
|
1225
|
+
wallet: walletClient,
|
|
1226
|
+
publicClient,
|
|
1227
|
+
factoryAddress: FACTORY_ADDRESS
|
|
1228
|
+
});
|
|
1229
|
+
console.log("\n\u{1F504} Preparing deployment configuration...");
|
|
1230
|
+
let quoteToken;
|
|
1231
|
+
let decimals;
|
|
1232
|
+
switch (answers.pairedTokenChoice) {
|
|
1233
|
+
case "WETH":
|
|
1234
|
+
quoteToken = WETH_ADDRESS2;
|
|
1235
|
+
decimals = 18;
|
|
1236
|
+
break;
|
|
1237
|
+
case "USDC":
|
|
1238
|
+
quoteToken = USDC_ADDRESS;
|
|
1239
|
+
decimals = 6;
|
|
1240
|
+
break;
|
|
1241
|
+
case "CUSTOM":
|
|
1242
|
+
quoteToken = answers.customPairedToken;
|
|
1243
|
+
decimals = 18;
|
|
1244
|
+
break;
|
|
1245
|
+
default:
|
|
1246
|
+
quoteToken = WETH_ADDRESS2;
|
|
1247
|
+
decimals = 18;
|
|
1248
|
+
}
|
|
1249
|
+
const tokenAddress = await clanker.deployToken({
|
|
1250
|
+
name: answers.name,
|
|
1251
|
+
symbol: answers.symbol,
|
|
1252
|
+
salt: answers.salt || "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
1253
|
+
image: answers.image,
|
|
1254
|
+
metadata: {
|
|
1255
|
+
description: `${answers.name} token deployed via Clanker CLI`,
|
|
1256
|
+
socialMediaUrls: [],
|
|
1257
|
+
auditUrls: []
|
|
1258
|
+
},
|
|
1259
|
+
context: {
|
|
1260
|
+
interface: "Clanker CLI",
|
|
1261
|
+
platform: "Clanker",
|
|
1262
|
+
messageId: `CLI-${Date.now()}`,
|
|
1263
|
+
id: `${answers.symbol}-${Date.now()}`
|
|
1264
|
+
},
|
|
1265
|
+
vault: answers.vaultConfig.vaultPercentage !== "0" ? {
|
|
1266
|
+
percentage: parseInt(answers.vaultConfig.vaultPercentage, 10),
|
|
1267
|
+
durationInDays: parseInt(answers.vaultConfig.durationInDays, 10)
|
|
1268
|
+
} : void 0,
|
|
1269
|
+
pool: {
|
|
1270
|
+
quoteToken,
|
|
1271
|
+
initialMarketCap: answers.initialMarketCapUsd
|
|
1272
|
+
// Pass raw value, SDK will handle decimals
|
|
1273
|
+
},
|
|
1274
|
+
devBuy: answers.devBuy.ethAmount !== "0" ? {
|
|
1275
|
+
ethAmount: answers.devBuy.ethAmount,
|
|
1276
|
+
maxSlippage: answers.devBuy.maxSlippage
|
|
1277
|
+
} : void 0
|
|
1278
|
+
});
|
|
1279
|
+
return tokenAddress;
|
|
1280
|
+
}
|
|
1281
|
+
async function main2() {
|
|
1282
|
+
console.log("\n\u{1F680} Welcome to the Clanker Token Creator! \u{1F680}\n");
|
|
1283
|
+
if (!checkEnvironment()) {
|
|
1284
|
+
process.exit(1);
|
|
1285
|
+
}
|
|
1286
|
+
try {
|
|
1287
|
+
const answers = await promptUser();
|
|
1288
|
+
console.log("\n\u{1F4DD} Review your token configuration:\n");
|
|
1289
|
+
console.log(JSON.stringify(answers, null, 2));
|
|
1290
|
+
const { confirm } = await inquirer.prompt([
|
|
1291
|
+
{
|
|
1292
|
+
type: "confirm",
|
|
1293
|
+
name: "confirm",
|
|
1294
|
+
message: "Would you like to proceed with deployment?",
|
|
1295
|
+
default: false
|
|
1296
|
+
}
|
|
1297
|
+
]);
|
|
1298
|
+
if (confirm) {
|
|
1299
|
+
console.log("\n\u{1F504} Deploying your token...");
|
|
1300
|
+
try {
|
|
1301
|
+
const tokenAddress = await deployToken(answers);
|
|
1302
|
+
console.log("\n\u2728 Token deployed successfully!");
|
|
1303
|
+
console.log("\u{1F4CD} Token address:", tokenAddress);
|
|
1304
|
+
console.log("\n\u{1F310} View on Basescan:");
|
|
1305
|
+
console.log(`https://basescan.org/token/${tokenAddress}`);
|
|
1306
|
+
} catch (error) {
|
|
1307
|
+
console.error("\n\u274C Deployment failed:", error instanceof Error ? error.message : "Unknown error");
|
|
1308
|
+
process.exit(1);
|
|
1309
|
+
}
|
|
1310
|
+
} else {
|
|
1311
|
+
console.log("\n\u274C Deployment cancelled");
|
|
1312
|
+
}
|
|
1313
|
+
} catch (error) {
|
|
1314
|
+
console.error("\n\u274C Error:", error);
|
|
1315
|
+
process.exit(1);
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
await main2();
|
|
1319
|
+
}
|
|
1320
|
+
var init_create_clanker = __esm({
|
|
1321
|
+
"src/cli/create-clanker.ts"() {
|
|
1322
|
+
"use strict";
|
|
1323
|
+
init_esm_shims();
|
|
1324
|
+
init_index();
|
|
1325
|
+
dotenv.config();
|
|
1326
|
+
createClanker();
|
|
1327
|
+
}
|
|
1328
|
+
});
|
|
1329
|
+
|
|
1330
|
+
// src/cli/cli.ts
|
|
1331
|
+
init_esm_shims();
|
|
1332
|
+
import { fileURLToPath } from "url";
|
|
1333
|
+
import { dirname } from "path";
|
|
1334
|
+
var __filename2 = fileURLToPath(import.meta.url);
|
|
1335
|
+
var __dirname2 = dirname(__filename2);
|
|
1336
|
+
async function main() {
|
|
1337
|
+
const args = process.argv.slice(2);
|
|
1338
|
+
if (args.includes("--create")) {
|
|
1339
|
+
const createClanker2 = await Promise.resolve().then(() => (init_create_clanker(), create_clanker_exports));
|
|
1340
|
+
await createClanker2.default();
|
|
1341
|
+
} else {
|
|
1342
|
+
console.log("\n\u{1F680} Clanker SDK CLI\n");
|
|
1343
|
+
console.log("Available commands:");
|
|
1344
|
+
console.log(" --create Create a new token");
|
|
1345
|
+
console.log("\nExample:");
|
|
1346
|
+
console.log(" npx clanker-sdk --create\n");
|
|
1347
|
+
process.exit(0);
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
main().catch((error) => {
|
|
1351
|
+
console.error("Error:", error);
|
|
1352
|
+
process.exit(1);
|
|
1353
|
+
});
|