clanker-sdk 3.9.8 → 3.9.9
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 +6 -1
- package/dist/cli/ascii.txt +20 -0
- package/dist/cli/cli.d.ts +1 -0
- package/dist/cli/cli.js +166 -35
- package/dist/cli/create-clanker.d.ts +4 -0
- package/dist/cli/create-clanker.js +164 -33
- package/dist/index.d.ts +125 -0
- package/dist/index.js +19 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -146,7 +146,8 @@ async function prepareTokenDeployment() {
|
|
|
146
146
|
### Basic Token Configuration
|
|
147
147
|
- `name`: Token name
|
|
148
148
|
- `symbol`: Token symbol
|
|
149
|
-
- `salt`:
|
|
149
|
+
- `salt`: Optional bytes32 value (must be "0x" + 64 hex characters), defaults to all zeros
|
|
150
|
+
- `creatorReward`: Optional percentage (0-80) controlling reward distribution between creator and interface, defaults to 80%
|
|
150
151
|
- `image`: IPFS hash for token image
|
|
151
152
|
- `metadata`: IPFS hash for token metadata
|
|
152
153
|
- `context`: Deployment context string
|
|
@@ -162,6 +163,10 @@ const tokenAddress = await clanker.deployToken({
|
|
|
162
163
|
name: "Test Token",
|
|
163
164
|
symbol: "TEST",
|
|
164
165
|
|
|
166
|
+
// Optional configuration with validation
|
|
167
|
+
salt: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", // Must be 0x + 64 hex chars
|
|
168
|
+
creatorReward: 60, // Must be between 0-80, defaults to 80
|
|
169
|
+
|
|
165
170
|
// Metadata configuration
|
|
166
171
|
metadata: {
|
|
167
172
|
description: "Test token deployment",
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
.--..--..--..--..--..--..--..--..--..--..--..--..--..--..--..--..--..--..--..--..--..--..--..--.
|
|
2
|
+
/ .. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \
|
|
3
|
+
\ \/\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ \/ /
|
|
4
|
+
\/ /`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'\/ /
|
|
5
|
+
/ /\ ```````````````````````````````````````````````````````````````````````````````````` / /\
|
|
6
|
+
/ /\ \ ```````````````````````````````````````````````````````````````````````````````````` / /\ \
|
|
7
|
+
\ \/ / ```````::::::::``:::````````````:::`````::::````:::`:::````:::`::::::::::`:::::::::` \ \/ /
|
|
8
|
+
\/ / `````:+:````:+:`:+:``````````:+:`:+:```:+:+:```:+:`:+:```:+:``:+:````````:+:````:+:` \/ /
|
|
9
|
+
/ /\ ````+:+````````+:+`````````+:+```+:+``:+:+:+``+:+`+:+``+:+```+:+````````+:+````+:+`` / /\
|
|
10
|
+
/ /\ \ ```+#+````````+#+````````+#++:++#++:`+#+`+:+`+#+`+#++:++````+#++:++#```+#++:++#:```` / /\ \
|
|
11
|
+
\ \/ / ``+#+````````+#+````````+#+`````+#+`+#+``+#+#+#`+#+``+#+```+#+````````+#+````+#+```` \ \/ /
|
|
12
|
+
\/ / `#+#````#+#`#+#````````#+#`````#+#`#+#```#+#+#`#+#```#+#``#+#````````#+#````#+#````` \/ /
|
|
13
|
+
/ /\ `########``##########`###`````###`###````####`###````###`##########`###````###`````` / /\
|
|
14
|
+
/ /\ \ ```````````````````````````````````````````````````````````````````````````````````` / /\ \
|
|
15
|
+
\ \/ / ```````````````````````````````````````````````````````````````````````````````````` \ \/ /
|
|
16
|
+
\/ / ```````````````````````````````````````````````````````````````````````````````````` \/ /
|
|
17
|
+
/ /\.--..--..--..--..--..--..--..--..--..--..--..--..--..--..--..--..--..--..--..--..--..--./ /\
|
|
18
|
+
/ /\ \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \.. \/\ \
|
|
19
|
+
\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `'\ `' /
|
|
20
|
+
`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'`--'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/cli/cli.js
CHANGED
|
@@ -10,9 +10,15 @@ var __export = (target, all) => {
|
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
// node_modules/tsup/assets/esm_shims.js
|
|
13
|
+
import { fileURLToPath } from "url";
|
|
14
|
+
import path from "path";
|
|
15
|
+
var getFilename, getDirname, __dirname;
|
|
13
16
|
var init_esm_shims = __esm({
|
|
14
17
|
"node_modules/tsup/assets/esm_shims.js"() {
|
|
15
18
|
"use strict";
|
|
19
|
+
getFilename = () => fileURLToPath(import.meta.url);
|
|
20
|
+
getDirname = () => path.dirname(getFilename());
|
|
21
|
+
__dirname = /* @__PURE__ */ getDirname();
|
|
16
22
|
}
|
|
17
23
|
});
|
|
18
24
|
|
|
@@ -820,7 +826,14 @@ var init_index = __esm({
|
|
|
820
826
|
tokenConfig: {
|
|
821
827
|
name: cfg.name,
|
|
822
828
|
symbol: cfg.symbol,
|
|
823
|
-
salt:
|
|
829
|
+
salt: (() => {
|
|
830
|
+
const defaultSalt = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
831
|
+
const salt = cfg.salt ?? defaultSalt;
|
|
832
|
+
if (!/^0x[a-fA-F0-9]{64}$/.test(salt)) {
|
|
833
|
+
throw new Error("Salt must be a valid bytes32 value (0x + 64 hex characters)");
|
|
834
|
+
}
|
|
835
|
+
return salt;
|
|
836
|
+
})(),
|
|
824
837
|
image: cfg.image || "https://ipfs.io/ipfs/QmcjfTeK3tpK3MVCQuvEaXvSscrqbL3MwsEo8LdBTWabY4",
|
|
825
838
|
metadata: JSON.stringify(cfg.metadata || {
|
|
826
839
|
description: "Clanker Token",
|
|
@@ -849,12 +862,17 @@ var init_index = __esm({
|
|
|
849
862
|
},
|
|
850
863
|
initialBuyConfig,
|
|
851
864
|
rewardsConfig: {
|
|
852
|
-
creatorReward:
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
865
|
+
creatorReward: (() => {
|
|
866
|
+
const reward = cfg.rewardsConfig?.creatorReward ?? 80;
|
|
867
|
+
if (reward < 0 || reward > 80) {
|
|
868
|
+
throw new Error("Creator reward must be between 0 and 80");
|
|
869
|
+
}
|
|
870
|
+
return BigInt(reward);
|
|
871
|
+
})(),
|
|
872
|
+
creatorAdmin: cfg.rewardsConfig?.creatorAdmin ?? deployerAddress,
|
|
873
|
+
creatorRewardRecipient: cfg.rewardsConfig?.creatorRewardRecipient ?? deployerAddress,
|
|
874
|
+
interfaceAdmin: cfg.rewardsConfig?.interfaceAdmin ?? deployerAddress,
|
|
875
|
+
interfaceRewardRecipient: cfg.rewardsConfig?.interfaceRewardRecipient ?? deployerAddress
|
|
858
876
|
}
|
|
859
877
|
};
|
|
860
878
|
}
|
|
@@ -904,28 +922,25 @@ var init_index = __esm({
|
|
|
904
922
|
// src/cli/create-clanker.ts
|
|
905
923
|
var create_clanker_exports = {};
|
|
906
924
|
__export(create_clanker_exports, {
|
|
907
|
-
default: () =>
|
|
925
|
+
default: () => create_clanker_default
|
|
908
926
|
});
|
|
909
927
|
import inquirer from "inquirer";
|
|
910
928
|
import { createPublicClient, createWalletClient, http } from "viem";
|
|
911
929
|
import { privateKeyToAccount } from "viem/accounts";
|
|
912
930
|
import { base } from "viem/chains";
|
|
913
931
|
import * as dotenv from "dotenv";
|
|
932
|
+
import * as fs from "fs";
|
|
933
|
+
import * as path2 from "path";
|
|
914
934
|
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
935
|
const PRIVATE_KEY = process.env.PRIVATE_KEY;
|
|
925
936
|
const FACTORY_ADDRESS = process.env.FACTORY_ADDRESS;
|
|
926
937
|
const RPC_URL = process.env.RPC_URL;
|
|
927
938
|
const WETH_ADDRESS2 = "0x4200000000000000000000000000000000000006";
|
|
928
939
|
const USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
940
|
+
function toHexAddress(address) {
|
|
941
|
+
if (!address) return void 0;
|
|
942
|
+
return address.toLowerCase();
|
|
943
|
+
}
|
|
929
944
|
function checkEnvironment() {
|
|
930
945
|
const missingVars = [];
|
|
931
946
|
if (!PRIVATE_KEY) missingVars.push("PRIVATE_KEY");
|
|
@@ -973,8 +988,8 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
973
988
|
};
|
|
974
989
|
const validateSymbol = (input) => {
|
|
975
990
|
if (!input) return "Symbol cannot be empty";
|
|
976
|
-
if (!/^[
|
|
977
|
-
if (input.length >
|
|
991
|
+
if (!/^[a-zA-Z0-9]+$/.test(input)) return "Symbol must contain only letters and numbers";
|
|
992
|
+
if (input.length > 20) return "Symbol must be 20 characters or less";
|
|
978
993
|
return true;
|
|
979
994
|
};
|
|
980
995
|
const validateIpfsUri = (input) => {
|
|
@@ -1031,18 +1046,21 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1031
1046
|
type: "input",
|
|
1032
1047
|
name: "name",
|
|
1033
1048
|
message: "Token name:",
|
|
1049
|
+
prefix: "",
|
|
1034
1050
|
validate: (input) => input.length > 0 || "Name cannot be empty"
|
|
1035
1051
|
},
|
|
1036
1052
|
{
|
|
1037
1053
|
type: "input",
|
|
1038
1054
|
name: "symbol",
|
|
1039
1055
|
message: "Token symbol:",
|
|
1056
|
+
prefix: "",
|
|
1040
1057
|
validate: validateSymbol
|
|
1041
1058
|
},
|
|
1042
1059
|
{
|
|
1043
1060
|
type: "list",
|
|
1044
1061
|
name: "pairedTokenChoice",
|
|
1045
1062
|
message: "Select quote token:",
|
|
1063
|
+
prefix: "",
|
|
1046
1064
|
choices: [
|
|
1047
1065
|
{ name: "WETH", value: "WETH" },
|
|
1048
1066
|
{ name: "USDC", value: "USDC" },
|
|
@@ -1054,6 +1072,7 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1054
1072
|
type: "input",
|
|
1055
1073
|
name: "customPairedToken",
|
|
1056
1074
|
message: "Enter custom token address:",
|
|
1075
|
+
prefix: "",
|
|
1057
1076
|
validate: validateAddress,
|
|
1058
1077
|
when: (answers2) => answers2.pairedTokenChoice === "CUSTOM"
|
|
1059
1078
|
},
|
|
@@ -1061,6 +1080,7 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1061
1080
|
type: "input",
|
|
1062
1081
|
name: "initialMarketCapUsd",
|
|
1063
1082
|
message: (answers2) => `Enter initial market cap in ${answers2.pairedTokenChoice === "CUSTOM" ? "quote token" : answers2.pairedTokenChoice}:`,
|
|
1083
|
+
prefix: "",
|
|
1064
1084
|
validate: validateAmount,
|
|
1065
1085
|
default: (answers2) => answers2.pairedTokenChoice === "WETH" ? "1" : answers2.pairedTokenChoice === "USDC" ? "1000" : "1"
|
|
1066
1086
|
},
|
|
@@ -1068,6 +1088,7 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1068
1088
|
type: "input",
|
|
1069
1089
|
name: "customMarketCap",
|
|
1070
1090
|
message: "Enter custom market cap in quote token:",
|
|
1091
|
+
prefix: "",
|
|
1071
1092
|
validate: validateAmount,
|
|
1072
1093
|
when: (answers2) => answers2.initialMarketCapUsd === "CUSTOM"
|
|
1073
1094
|
},
|
|
@@ -1075,12 +1096,14 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1075
1096
|
type: "input",
|
|
1076
1097
|
name: "image",
|
|
1077
1098
|
message: "Enter the IPFS URI for the token image:",
|
|
1099
|
+
prefix: "",
|
|
1078
1100
|
validate: validateIpfsUri
|
|
1079
1101
|
},
|
|
1080
1102
|
{
|
|
1081
1103
|
type: "list",
|
|
1082
1104
|
name: "devBuy.ethAmount",
|
|
1083
1105
|
message: "Creator buy amount (optional):",
|
|
1106
|
+
prefix: "",
|
|
1084
1107
|
choices: [
|
|
1085
1108
|
{ name: "None", value: "0" },
|
|
1086
1109
|
{ name: "0.00005 ETH", value: "0.00005" },
|
|
@@ -1095,6 +1118,7 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1095
1118
|
type: "input",
|
|
1096
1119
|
name: "customDevBuy",
|
|
1097
1120
|
message: "Enter custom dev buy amount in ETH:",
|
|
1121
|
+
prefix: "",
|
|
1098
1122
|
validate: validateAmount,
|
|
1099
1123
|
when: (answers2) => answers2.devBuy.ethAmount === "CUSTOM"
|
|
1100
1124
|
},
|
|
@@ -1102,6 +1126,7 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1102
1126
|
type: "input",
|
|
1103
1127
|
name: "devBuy.maxSlippage",
|
|
1104
1128
|
message: "Maximum slippage percentage (0-100):",
|
|
1129
|
+
prefix: "",
|
|
1105
1130
|
validate: validateSlippage,
|
|
1106
1131
|
default: "5",
|
|
1107
1132
|
when: (answers2) => answers2.devBuy.ethAmount !== "0"
|
|
@@ -1110,6 +1135,7 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1110
1135
|
type: "list",
|
|
1111
1136
|
name: "vaultConfig.vaultPercentage",
|
|
1112
1137
|
message: "Vault percentage (optional):",
|
|
1138
|
+
prefix: "",
|
|
1113
1139
|
choices: [
|
|
1114
1140
|
{ name: "None", value: "0" },
|
|
1115
1141
|
{ name: "5%", value: "5" },
|
|
@@ -1123,6 +1149,7 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1123
1149
|
type: "input",
|
|
1124
1150
|
name: "customVaultPercentage",
|
|
1125
1151
|
message: "Enter custom vault percentage (0-30):",
|
|
1152
|
+
prefix: "",
|
|
1126
1153
|
validate: validateVaultPercentage,
|
|
1127
1154
|
when: (answers2) => answers2.vaultConfig.vaultPercentage === "CUSTOM"
|
|
1128
1155
|
},
|
|
@@ -1130,6 +1157,7 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1130
1157
|
type: "list",
|
|
1131
1158
|
name: "vaultConfig.durationInDays",
|
|
1132
1159
|
message: "Vault duration:",
|
|
1160
|
+
prefix: "",
|
|
1133
1161
|
choices: [
|
|
1134
1162
|
{ name: "31 days", value: "31" },
|
|
1135
1163
|
{ name: "90 days", value: "90" },
|
|
@@ -1143,6 +1171,7 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1143
1171
|
type: "input",
|
|
1144
1172
|
name: "customVaultDuration",
|
|
1145
1173
|
message: "Enter custom vault duration in days (minimum 30):",
|
|
1174
|
+
prefix: "",
|
|
1146
1175
|
validate: validateVaultDuration,
|
|
1147
1176
|
when: (answers2) => answers2.vaultConfig.durationInDays === "CUSTOM"
|
|
1148
1177
|
},
|
|
@@ -1150,6 +1179,7 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1150
1179
|
type: "input",
|
|
1151
1180
|
name: "metadata.description",
|
|
1152
1181
|
message: "Token description:",
|
|
1182
|
+
prefix: "",
|
|
1153
1183
|
default: (answers2) => `${answers2.name} token deployed via Clanker CLI`,
|
|
1154
1184
|
validate: (input) => input.length > 0 || "Description cannot be empty"
|
|
1155
1185
|
},
|
|
@@ -1157,28 +1187,96 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1157
1187
|
type: "input",
|
|
1158
1188
|
name: "metadata.telegram",
|
|
1159
1189
|
message: "Telegram URL (optional):",
|
|
1190
|
+
prefix: "",
|
|
1160
1191
|
validate: validateUrl
|
|
1161
1192
|
},
|
|
1162
1193
|
{
|
|
1163
1194
|
type: "input",
|
|
1164
1195
|
name: "metadata.website",
|
|
1165
1196
|
message: "Website URL (optional):",
|
|
1197
|
+
prefix: "",
|
|
1166
1198
|
validate: validateUrl
|
|
1167
1199
|
},
|
|
1168
1200
|
{
|
|
1169
1201
|
type: "input",
|
|
1170
1202
|
name: "metadata.twitter",
|
|
1171
1203
|
message: "X/Twitter URL (optional):",
|
|
1204
|
+
prefix: "",
|
|
1172
1205
|
validate: validateUrl
|
|
1173
1206
|
},
|
|
1174
1207
|
{
|
|
1175
1208
|
type: "input",
|
|
1176
1209
|
name: "metadata.farcaster",
|
|
1177
1210
|
message: "Farcaster URL (optional):",
|
|
1211
|
+
prefix: "",
|
|
1178
1212
|
validate: validateUrl
|
|
1213
|
+
},
|
|
1214
|
+
{
|
|
1215
|
+
type: "input",
|
|
1216
|
+
name: "salt",
|
|
1217
|
+
message: "Enter custom salt (optional, press enter for default 0x0000...):",
|
|
1218
|
+
prefix: "",
|
|
1219
|
+
validate: (input) => {
|
|
1220
|
+
if (!input) return true;
|
|
1221
|
+
if (!/^0x[a-fA-F0-9]{64}$/.test(input)) {
|
|
1222
|
+
return "Salt must be a valid bytes32 value (0x + 64 hex characters)";
|
|
1223
|
+
}
|
|
1224
|
+
return true;
|
|
1225
|
+
}
|
|
1226
|
+
},
|
|
1227
|
+
{
|
|
1228
|
+
type: "list",
|
|
1229
|
+
name: "rewardsConfig.creatorReward",
|
|
1230
|
+
message: "Creator reward percentage, balance remaining goes to interface:",
|
|
1231
|
+
prefix: "",
|
|
1232
|
+
choices: [
|
|
1233
|
+
{ name: "80% (maximum)", value: 80 },
|
|
1234
|
+
{ name: "60%", value: 60 },
|
|
1235
|
+
{ name: "40%", value: 40 },
|
|
1236
|
+
{ name: "20%", value: 20 },
|
|
1237
|
+
{ name: "0% (all to interface)", value: 0 },
|
|
1238
|
+
{ name: "Custom", value: "CUSTOM" }
|
|
1239
|
+
],
|
|
1240
|
+
default: 80
|
|
1241
|
+
},
|
|
1242
|
+
{
|
|
1243
|
+
type: "input",
|
|
1244
|
+
name: "rewardsConfig.customCreatorReward",
|
|
1245
|
+
message: "Enter custom creator reward percentage (0-80):",
|
|
1246
|
+
prefix: "",
|
|
1247
|
+
validate: validateCreatorReward,
|
|
1248
|
+
when: (answers2) => answers2.rewardsConfig.creatorReward === "CUSTOM"
|
|
1249
|
+
},
|
|
1250
|
+
{
|
|
1251
|
+
type: "input",
|
|
1252
|
+
name: "rewardsConfig.creatorAdmin",
|
|
1253
|
+
message: "Enter custom creator admin address (optional):",
|
|
1254
|
+
prefix: "",
|
|
1255
|
+
validate: validateAddress
|
|
1256
|
+
},
|
|
1257
|
+
{
|
|
1258
|
+
type: "input",
|
|
1259
|
+
name: "rewardsConfig.creatorRewardRecipient",
|
|
1260
|
+
message: "Enter custom creator reward recipient address (optional):",
|
|
1261
|
+
prefix: "",
|
|
1262
|
+
validate: validateAddress
|
|
1263
|
+
},
|
|
1264
|
+
{
|
|
1265
|
+
type: "input",
|
|
1266
|
+
name: "rewardsConfig.interfaceAdmin",
|
|
1267
|
+
message: "Enter custom interface admin address (optional):",
|
|
1268
|
+
prefix: "",
|
|
1269
|
+
validate: validateAddress
|
|
1270
|
+
},
|
|
1271
|
+
{
|
|
1272
|
+
type: "input",
|
|
1273
|
+
name: "rewardsConfig.interfaceRewardRecipient",
|
|
1274
|
+
message: "Enter custom interface reward recipient address (optional):",
|
|
1275
|
+
prefix: "",
|
|
1276
|
+
validate: validateAddress
|
|
1179
1277
|
}
|
|
1180
1278
|
];
|
|
1181
|
-
const answers = await inquirer.prompt(questions);
|
|
1279
|
+
const answers = await inquirer.prompt(questions, {});
|
|
1182
1280
|
if (answers.initialMarketCapUsd === "CUSTOM") {
|
|
1183
1281
|
answers.initialMarketCapUsd = answers.customMarketCap || "0";
|
|
1184
1282
|
}
|
|
@@ -1203,6 +1301,21 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1203
1301
|
vaultConfig: {
|
|
1204
1302
|
vaultPercentage: vaultPercentage.toString(),
|
|
1205
1303
|
durationInDays: vaultDuration.toString()
|
|
1304
|
+
},
|
|
1305
|
+
rewardsConfig: {
|
|
1306
|
+
creatorReward: answers.rewardsConfig.creatorReward === "CUSTOM" ? Number(answers.rewardsConfig.customCreatorReward) : Number(answers.rewardsConfig.creatorReward),
|
|
1307
|
+
...answers.rewardsConfig.creatorAdmin ? {
|
|
1308
|
+
creatorAdmin: toHexAddress(answers.rewardsConfig.creatorAdmin)
|
|
1309
|
+
} : {},
|
|
1310
|
+
...answers.rewardsConfig.creatorRewardRecipient ? {
|
|
1311
|
+
creatorRewardRecipient: toHexAddress(answers.rewardsConfig.creatorRewardRecipient)
|
|
1312
|
+
} : {},
|
|
1313
|
+
...answers.rewardsConfig.interfaceAdmin ? {
|
|
1314
|
+
interfaceAdmin: toHexAddress(answers.rewardsConfig.interfaceAdmin)
|
|
1315
|
+
} : {},
|
|
1316
|
+
...answers.rewardsConfig.interfaceRewardRecipient ? {
|
|
1317
|
+
interfaceRewardRecipient: toHexAddress(answers.rewardsConfig.interfaceRewardRecipient)
|
|
1318
|
+
} : {}
|
|
1206
1319
|
}
|
|
1207
1320
|
};
|
|
1208
1321
|
}
|
|
@@ -1251,11 +1364,7 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1251
1364
|
symbol: answers.symbol,
|
|
1252
1365
|
salt: answers.salt || "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
1253
1366
|
image: answers.image,
|
|
1254
|
-
metadata:
|
|
1255
|
-
description: `${answers.name} token deployed via Clanker CLI`,
|
|
1256
|
-
socialMediaUrls: [],
|
|
1257
|
-
auditUrls: []
|
|
1258
|
-
},
|
|
1367
|
+
metadata: answers.metadata,
|
|
1259
1368
|
context: {
|
|
1260
1369
|
interface: "Clanker CLI",
|
|
1261
1370
|
platform: "Clanker",
|
|
@@ -1269,16 +1378,37 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1269
1378
|
pool: {
|
|
1270
1379
|
quoteToken,
|
|
1271
1380
|
initialMarketCap: answers.initialMarketCapUsd
|
|
1272
|
-
// Pass raw value, SDK will handle decimals
|
|
1273
1381
|
},
|
|
1274
1382
|
devBuy: answers.devBuy.ethAmount !== "0" ? {
|
|
1275
1383
|
ethAmount: answers.devBuy.ethAmount,
|
|
1276
1384
|
maxSlippage: answers.devBuy.maxSlippage
|
|
1277
|
-
} : void 0
|
|
1385
|
+
} : void 0,
|
|
1386
|
+
rewardsConfig: {
|
|
1387
|
+
creatorReward: answers.rewardsConfig.creatorReward === "CUSTOM" ? Number(answers.rewardsConfig.customCreatorReward) : Number(answers.rewardsConfig.creatorReward),
|
|
1388
|
+
...answers.rewardsConfig.creatorAdmin ? {
|
|
1389
|
+
creatorAdmin: toHexAddress(answers.rewardsConfig.creatorAdmin)
|
|
1390
|
+
} : {},
|
|
1391
|
+
...answers.rewardsConfig.creatorRewardRecipient ? {
|
|
1392
|
+
creatorRewardRecipient: toHexAddress(answers.rewardsConfig.creatorRewardRecipient)
|
|
1393
|
+
} : {},
|
|
1394
|
+
...answers.rewardsConfig.interfaceAdmin ? {
|
|
1395
|
+
interfaceAdmin: toHexAddress(answers.rewardsConfig.interfaceAdmin)
|
|
1396
|
+
} : {},
|
|
1397
|
+
...answers.rewardsConfig.interfaceRewardRecipient ? {
|
|
1398
|
+
interfaceRewardRecipient: toHexAddress(answers.rewardsConfig.interfaceRewardRecipient)
|
|
1399
|
+
} : {}
|
|
1400
|
+
}
|
|
1278
1401
|
});
|
|
1402
|
+
console.log("\n\u2728 Deployment successful!");
|
|
1403
|
+
console.log(`\u{1F4CD} Token address: ${tokenAddress}`);
|
|
1404
|
+
console.log("\n\u{1F310} View on:");
|
|
1405
|
+
console.log(`Basescan: https://basescan.org/token/${tokenAddress}`);
|
|
1406
|
+
console.log(`Clanker World: https://clanker.world/clanker/${tokenAddress}`);
|
|
1279
1407
|
return tokenAddress;
|
|
1280
1408
|
}
|
|
1281
1409
|
async function main2() {
|
|
1410
|
+
console.clear();
|
|
1411
|
+
console.log(ASCII_ART);
|
|
1282
1412
|
console.log("\n\u{1F680} Welcome to the Clanker Token Creator! \u{1F680}\n");
|
|
1283
1413
|
if (!checkEnvironment()) {
|
|
1284
1414
|
process.exit(1);
|
|
@@ -1292,23 +1422,22 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1292
1422
|
type: "confirm",
|
|
1293
1423
|
name: "confirm",
|
|
1294
1424
|
message: "Would you like to proceed with deployment?",
|
|
1295
|
-
default: false
|
|
1425
|
+
default: false,
|
|
1426
|
+
prefix: ""
|
|
1296
1427
|
}
|
|
1297
1428
|
]);
|
|
1298
1429
|
if (confirm) {
|
|
1299
1430
|
console.log("\n\u{1F504} Deploying your token...");
|
|
1300
1431
|
try {
|
|
1301
1432
|
const tokenAddress = await deployToken(answers);
|
|
1302
|
-
|
|
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}`);
|
|
1433
|
+
process.exit(0);
|
|
1306
1434
|
} catch (error) {
|
|
1307
1435
|
console.error("\n\u274C Deployment failed:", error instanceof Error ? error.message : "Unknown error");
|
|
1308
1436
|
process.exit(1);
|
|
1309
1437
|
}
|
|
1310
1438
|
} else {
|
|
1311
1439
|
console.log("\n\u274C Deployment cancelled");
|
|
1440
|
+
process.exit(0);
|
|
1312
1441
|
}
|
|
1313
1442
|
} catch (error) {
|
|
1314
1443
|
console.error("\n\u274C Error:", error);
|
|
@@ -1317,21 +1446,23 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1317
1446
|
}
|
|
1318
1447
|
await main2();
|
|
1319
1448
|
}
|
|
1449
|
+
var ASCII_ART, create_clanker_default;
|
|
1320
1450
|
var init_create_clanker = __esm({
|
|
1321
1451
|
"src/cli/create-clanker.ts"() {
|
|
1322
1452
|
"use strict";
|
|
1323
1453
|
init_esm_shims();
|
|
1324
1454
|
init_index();
|
|
1325
1455
|
dotenv.config();
|
|
1326
|
-
|
|
1456
|
+
ASCII_ART = fs.readFileSync(path2.join(__dirname, "ascii.txt"), "utf8");
|
|
1457
|
+
create_clanker_default = createClanker;
|
|
1327
1458
|
}
|
|
1328
1459
|
});
|
|
1329
1460
|
|
|
1330
1461
|
// src/cli/cli.ts
|
|
1331
1462
|
init_esm_shims();
|
|
1332
|
-
import { fileURLToPath } from "url";
|
|
1463
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1333
1464
|
import { dirname } from "path";
|
|
1334
|
-
var __filename2 =
|
|
1465
|
+
var __filename2 = fileURLToPath2(import.meta.url);
|
|
1335
1466
|
var __dirname2 = dirname(__filename2);
|
|
1336
1467
|
async function main() {
|
|
1337
1468
|
const args = process.argv.slice(2);
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
// node_modules/tsup/assets/esm_shims.js
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
import path from "path";
|
|
6
|
+
var getFilename = () => fileURLToPath(import.meta.url);
|
|
7
|
+
var getDirname = () => path.dirname(getFilename());
|
|
8
|
+
var __dirname = /* @__PURE__ */ getDirname();
|
|
9
|
+
|
|
3
10
|
// src/cli/create-clanker.ts
|
|
4
11
|
import inquirer from "inquirer";
|
|
5
12
|
|
|
@@ -779,7 +786,14 @@ var Clanker = class {
|
|
|
779
786
|
tokenConfig: {
|
|
780
787
|
name: cfg.name,
|
|
781
788
|
symbol: cfg.symbol,
|
|
782
|
-
salt:
|
|
789
|
+
salt: (() => {
|
|
790
|
+
const defaultSalt = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
791
|
+
const salt = cfg.salt ?? defaultSalt;
|
|
792
|
+
if (!/^0x[a-fA-F0-9]{64}$/.test(salt)) {
|
|
793
|
+
throw new Error("Salt must be a valid bytes32 value (0x + 64 hex characters)");
|
|
794
|
+
}
|
|
795
|
+
return salt;
|
|
796
|
+
})(),
|
|
783
797
|
image: cfg.image || "https://ipfs.io/ipfs/QmcjfTeK3tpK3MVCQuvEaXvSscrqbL3MwsEo8LdBTWabY4",
|
|
784
798
|
metadata: JSON.stringify(cfg.metadata || {
|
|
785
799
|
description: "Clanker Token",
|
|
@@ -808,12 +822,17 @@ var Clanker = class {
|
|
|
808
822
|
},
|
|
809
823
|
initialBuyConfig,
|
|
810
824
|
rewardsConfig: {
|
|
811
|
-
creatorReward:
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
825
|
+
creatorReward: (() => {
|
|
826
|
+
const reward = cfg.rewardsConfig?.creatorReward ?? 80;
|
|
827
|
+
if (reward < 0 || reward > 80) {
|
|
828
|
+
throw new Error("Creator reward must be between 0 and 80");
|
|
829
|
+
}
|
|
830
|
+
return BigInt(reward);
|
|
831
|
+
})(),
|
|
832
|
+
creatorAdmin: cfg.rewardsConfig?.creatorAdmin ?? deployerAddress,
|
|
833
|
+
creatorRewardRecipient: cfg.rewardsConfig?.creatorRewardRecipient ?? deployerAddress,
|
|
834
|
+
interfaceAdmin: cfg.rewardsConfig?.interfaceAdmin ?? deployerAddress,
|
|
835
|
+
interfaceRewardRecipient: cfg.rewardsConfig?.interfaceRewardRecipient ?? deployerAddress
|
|
817
836
|
}
|
|
818
837
|
};
|
|
819
838
|
}
|
|
@@ -863,22 +882,20 @@ import { createPublicClient, createWalletClient, http } from "viem";
|
|
|
863
882
|
import { privateKeyToAccount } from "viem/accounts";
|
|
864
883
|
import { base } from "viem/chains";
|
|
865
884
|
import * as dotenv from "dotenv";
|
|
885
|
+
import * as fs from "fs";
|
|
886
|
+
import * as path2 from "path";
|
|
866
887
|
dotenv.config();
|
|
888
|
+
var ASCII_ART = fs.readFileSync(path2.join(__dirname, "ascii.txt"), "utf8");
|
|
867
889
|
async function createClanker() {
|
|
868
|
-
const args = process.argv.slice(2);
|
|
869
|
-
if (args.length === 0 || args[0] !== "--create" && args[0] !== "create") {
|
|
870
|
-
console.log("\n\u{1F680} Clanker SDK CLI\n");
|
|
871
|
-
console.log("Available commands:");
|
|
872
|
-
console.log(" --create Create a new token");
|
|
873
|
-
console.log("\nExample:");
|
|
874
|
-
console.log(" npx clanker-sdk --create\n");
|
|
875
|
-
process.exit(0);
|
|
876
|
-
}
|
|
877
890
|
const PRIVATE_KEY = process.env.PRIVATE_KEY;
|
|
878
891
|
const FACTORY_ADDRESS = process.env.FACTORY_ADDRESS;
|
|
879
892
|
const RPC_URL = process.env.RPC_URL;
|
|
880
893
|
const WETH_ADDRESS2 = "0x4200000000000000000000000000000000000006";
|
|
881
894
|
const USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
895
|
+
function toHexAddress(address) {
|
|
896
|
+
if (!address) return void 0;
|
|
897
|
+
return address.toLowerCase();
|
|
898
|
+
}
|
|
882
899
|
function checkEnvironment() {
|
|
883
900
|
const missingVars = [];
|
|
884
901
|
if (!PRIVATE_KEY) missingVars.push("PRIVATE_KEY");
|
|
@@ -926,8 +943,8 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
926
943
|
};
|
|
927
944
|
const validateSymbol = (input) => {
|
|
928
945
|
if (!input) return "Symbol cannot be empty";
|
|
929
|
-
if (!/^[
|
|
930
|
-
if (input.length >
|
|
946
|
+
if (!/^[a-zA-Z0-9]+$/.test(input)) return "Symbol must contain only letters and numbers";
|
|
947
|
+
if (input.length > 20) return "Symbol must be 20 characters or less";
|
|
931
948
|
return true;
|
|
932
949
|
};
|
|
933
950
|
const validateIpfsUri = (input) => {
|
|
@@ -984,18 +1001,21 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
984
1001
|
type: "input",
|
|
985
1002
|
name: "name",
|
|
986
1003
|
message: "Token name:",
|
|
1004
|
+
prefix: "",
|
|
987
1005
|
validate: (input) => input.length > 0 || "Name cannot be empty"
|
|
988
1006
|
},
|
|
989
1007
|
{
|
|
990
1008
|
type: "input",
|
|
991
1009
|
name: "symbol",
|
|
992
1010
|
message: "Token symbol:",
|
|
1011
|
+
prefix: "",
|
|
993
1012
|
validate: validateSymbol
|
|
994
1013
|
},
|
|
995
1014
|
{
|
|
996
1015
|
type: "list",
|
|
997
1016
|
name: "pairedTokenChoice",
|
|
998
1017
|
message: "Select quote token:",
|
|
1018
|
+
prefix: "",
|
|
999
1019
|
choices: [
|
|
1000
1020
|
{ name: "WETH", value: "WETH" },
|
|
1001
1021
|
{ name: "USDC", value: "USDC" },
|
|
@@ -1007,6 +1027,7 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1007
1027
|
type: "input",
|
|
1008
1028
|
name: "customPairedToken",
|
|
1009
1029
|
message: "Enter custom token address:",
|
|
1030
|
+
prefix: "",
|
|
1010
1031
|
validate: validateAddress,
|
|
1011
1032
|
when: (answers2) => answers2.pairedTokenChoice === "CUSTOM"
|
|
1012
1033
|
},
|
|
@@ -1014,6 +1035,7 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1014
1035
|
type: "input",
|
|
1015
1036
|
name: "initialMarketCapUsd",
|
|
1016
1037
|
message: (answers2) => `Enter initial market cap in ${answers2.pairedTokenChoice === "CUSTOM" ? "quote token" : answers2.pairedTokenChoice}:`,
|
|
1038
|
+
prefix: "",
|
|
1017
1039
|
validate: validateAmount,
|
|
1018
1040
|
default: (answers2) => answers2.pairedTokenChoice === "WETH" ? "1" : answers2.pairedTokenChoice === "USDC" ? "1000" : "1"
|
|
1019
1041
|
},
|
|
@@ -1021,6 +1043,7 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1021
1043
|
type: "input",
|
|
1022
1044
|
name: "customMarketCap",
|
|
1023
1045
|
message: "Enter custom market cap in quote token:",
|
|
1046
|
+
prefix: "",
|
|
1024
1047
|
validate: validateAmount,
|
|
1025
1048
|
when: (answers2) => answers2.initialMarketCapUsd === "CUSTOM"
|
|
1026
1049
|
},
|
|
@@ -1028,12 +1051,14 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1028
1051
|
type: "input",
|
|
1029
1052
|
name: "image",
|
|
1030
1053
|
message: "Enter the IPFS URI for the token image:",
|
|
1054
|
+
prefix: "",
|
|
1031
1055
|
validate: validateIpfsUri
|
|
1032
1056
|
},
|
|
1033
1057
|
{
|
|
1034
1058
|
type: "list",
|
|
1035
1059
|
name: "devBuy.ethAmount",
|
|
1036
1060
|
message: "Creator buy amount (optional):",
|
|
1061
|
+
prefix: "",
|
|
1037
1062
|
choices: [
|
|
1038
1063
|
{ name: "None", value: "0" },
|
|
1039
1064
|
{ name: "0.00005 ETH", value: "0.00005" },
|
|
@@ -1048,6 +1073,7 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1048
1073
|
type: "input",
|
|
1049
1074
|
name: "customDevBuy",
|
|
1050
1075
|
message: "Enter custom dev buy amount in ETH:",
|
|
1076
|
+
prefix: "",
|
|
1051
1077
|
validate: validateAmount,
|
|
1052
1078
|
when: (answers2) => answers2.devBuy.ethAmount === "CUSTOM"
|
|
1053
1079
|
},
|
|
@@ -1055,6 +1081,7 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1055
1081
|
type: "input",
|
|
1056
1082
|
name: "devBuy.maxSlippage",
|
|
1057
1083
|
message: "Maximum slippage percentage (0-100):",
|
|
1084
|
+
prefix: "",
|
|
1058
1085
|
validate: validateSlippage,
|
|
1059
1086
|
default: "5",
|
|
1060
1087
|
when: (answers2) => answers2.devBuy.ethAmount !== "0"
|
|
@@ -1063,6 +1090,7 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1063
1090
|
type: "list",
|
|
1064
1091
|
name: "vaultConfig.vaultPercentage",
|
|
1065
1092
|
message: "Vault percentage (optional):",
|
|
1093
|
+
prefix: "",
|
|
1066
1094
|
choices: [
|
|
1067
1095
|
{ name: "None", value: "0" },
|
|
1068
1096
|
{ name: "5%", value: "5" },
|
|
@@ -1076,6 +1104,7 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1076
1104
|
type: "input",
|
|
1077
1105
|
name: "customVaultPercentage",
|
|
1078
1106
|
message: "Enter custom vault percentage (0-30):",
|
|
1107
|
+
prefix: "",
|
|
1079
1108
|
validate: validateVaultPercentage,
|
|
1080
1109
|
when: (answers2) => answers2.vaultConfig.vaultPercentage === "CUSTOM"
|
|
1081
1110
|
},
|
|
@@ -1083,6 +1112,7 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1083
1112
|
type: "list",
|
|
1084
1113
|
name: "vaultConfig.durationInDays",
|
|
1085
1114
|
message: "Vault duration:",
|
|
1115
|
+
prefix: "",
|
|
1086
1116
|
choices: [
|
|
1087
1117
|
{ name: "31 days", value: "31" },
|
|
1088
1118
|
{ name: "90 days", value: "90" },
|
|
@@ -1096,6 +1126,7 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1096
1126
|
type: "input",
|
|
1097
1127
|
name: "customVaultDuration",
|
|
1098
1128
|
message: "Enter custom vault duration in days (minimum 30):",
|
|
1129
|
+
prefix: "",
|
|
1099
1130
|
validate: validateVaultDuration,
|
|
1100
1131
|
when: (answers2) => answers2.vaultConfig.durationInDays === "CUSTOM"
|
|
1101
1132
|
},
|
|
@@ -1103,6 +1134,7 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1103
1134
|
type: "input",
|
|
1104
1135
|
name: "metadata.description",
|
|
1105
1136
|
message: "Token description:",
|
|
1137
|
+
prefix: "",
|
|
1106
1138
|
default: (answers2) => `${answers2.name} token deployed via Clanker CLI`,
|
|
1107
1139
|
validate: (input) => input.length > 0 || "Description cannot be empty"
|
|
1108
1140
|
},
|
|
@@ -1110,28 +1142,96 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1110
1142
|
type: "input",
|
|
1111
1143
|
name: "metadata.telegram",
|
|
1112
1144
|
message: "Telegram URL (optional):",
|
|
1145
|
+
prefix: "",
|
|
1113
1146
|
validate: validateUrl
|
|
1114
1147
|
},
|
|
1115
1148
|
{
|
|
1116
1149
|
type: "input",
|
|
1117
1150
|
name: "metadata.website",
|
|
1118
1151
|
message: "Website URL (optional):",
|
|
1152
|
+
prefix: "",
|
|
1119
1153
|
validate: validateUrl
|
|
1120
1154
|
},
|
|
1121
1155
|
{
|
|
1122
1156
|
type: "input",
|
|
1123
1157
|
name: "metadata.twitter",
|
|
1124
1158
|
message: "X/Twitter URL (optional):",
|
|
1159
|
+
prefix: "",
|
|
1125
1160
|
validate: validateUrl
|
|
1126
1161
|
},
|
|
1127
1162
|
{
|
|
1128
1163
|
type: "input",
|
|
1129
1164
|
name: "metadata.farcaster",
|
|
1130
1165
|
message: "Farcaster URL (optional):",
|
|
1166
|
+
prefix: "",
|
|
1131
1167
|
validate: validateUrl
|
|
1168
|
+
},
|
|
1169
|
+
{
|
|
1170
|
+
type: "input",
|
|
1171
|
+
name: "salt",
|
|
1172
|
+
message: "Enter custom salt (optional, press enter for default 0x0000...):",
|
|
1173
|
+
prefix: "",
|
|
1174
|
+
validate: (input) => {
|
|
1175
|
+
if (!input) return true;
|
|
1176
|
+
if (!/^0x[a-fA-F0-9]{64}$/.test(input)) {
|
|
1177
|
+
return "Salt must be a valid bytes32 value (0x + 64 hex characters)";
|
|
1178
|
+
}
|
|
1179
|
+
return true;
|
|
1180
|
+
}
|
|
1181
|
+
},
|
|
1182
|
+
{
|
|
1183
|
+
type: "list",
|
|
1184
|
+
name: "rewardsConfig.creatorReward",
|
|
1185
|
+
message: "Creator reward percentage, balance remaining goes to interface:",
|
|
1186
|
+
prefix: "",
|
|
1187
|
+
choices: [
|
|
1188
|
+
{ name: "80% (maximum)", value: 80 },
|
|
1189
|
+
{ name: "60%", value: 60 },
|
|
1190
|
+
{ name: "40%", value: 40 },
|
|
1191
|
+
{ name: "20%", value: 20 },
|
|
1192
|
+
{ name: "0% (all to interface)", value: 0 },
|
|
1193
|
+
{ name: "Custom", value: "CUSTOM" }
|
|
1194
|
+
],
|
|
1195
|
+
default: 80
|
|
1196
|
+
},
|
|
1197
|
+
{
|
|
1198
|
+
type: "input",
|
|
1199
|
+
name: "rewardsConfig.customCreatorReward",
|
|
1200
|
+
message: "Enter custom creator reward percentage (0-80):",
|
|
1201
|
+
prefix: "",
|
|
1202
|
+
validate: validateCreatorReward,
|
|
1203
|
+
when: (answers2) => answers2.rewardsConfig.creatorReward === "CUSTOM"
|
|
1204
|
+
},
|
|
1205
|
+
{
|
|
1206
|
+
type: "input",
|
|
1207
|
+
name: "rewardsConfig.creatorAdmin",
|
|
1208
|
+
message: "Enter custom creator admin address (optional):",
|
|
1209
|
+
prefix: "",
|
|
1210
|
+
validate: validateAddress
|
|
1211
|
+
},
|
|
1212
|
+
{
|
|
1213
|
+
type: "input",
|
|
1214
|
+
name: "rewardsConfig.creatorRewardRecipient",
|
|
1215
|
+
message: "Enter custom creator reward recipient address (optional):",
|
|
1216
|
+
prefix: "",
|
|
1217
|
+
validate: validateAddress
|
|
1218
|
+
},
|
|
1219
|
+
{
|
|
1220
|
+
type: "input",
|
|
1221
|
+
name: "rewardsConfig.interfaceAdmin",
|
|
1222
|
+
message: "Enter custom interface admin address (optional):",
|
|
1223
|
+
prefix: "",
|
|
1224
|
+
validate: validateAddress
|
|
1225
|
+
},
|
|
1226
|
+
{
|
|
1227
|
+
type: "input",
|
|
1228
|
+
name: "rewardsConfig.interfaceRewardRecipient",
|
|
1229
|
+
message: "Enter custom interface reward recipient address (optional):",
|
|
1230
|
+
prefix: "",
|
|
1231
|
+
validate: validateAddress
|
|
1132
1232
|
}
|
|
1133
1233
|
];
|
|
1134
|
-
const answers = await inquirer.prompt(questions);
|
|
1234
|
+
const answers = await inquirer.prompt(questions, {});
|
|
1135
1235
|
if (answers.initialMarketCapUsd === "CUSTOM") {
|
|
1136
1236
|
answers.initialMarketCapUsd = answers.customMarketCap || "0";
|
|
1137
1237
|
}
|
|
@@ -1156,6 +1256,21 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1156
1256
|
vaultConfig: {
|
|
1157
1257
|
vaultPercentage: vaultPercentage.toString(),
|
|
1158
1258
|
durationInDays: vaultDuration.toString()
|
|
1259
|
+
},
|
|
1260
|
+
rewardsConfig: {
|
|
1261
|
+
creatorReward: answers.rewardsConfig.creatorReward === "CUSTOM" ? Number(answers.rewardsConfig.customCreatorReward) : Number(answers.rewardsConfig.creatorReward),
|
|
1262
|
+
...answers.rewardsConfig.creatorAdmin ? {
|
|
1263
|
+
creatorAdmin: toHexAddress(answers.rewardsConfig.creatorAdmin)
|
|
1264
|
+
} : {},
|
|
1265
|
+
...answers.rewardsConfig.creatorRewardRecipient ? {
|
|
1266
|
+
creatorRewardRecipient: toHexAddress(answers.rewardsConfig.creatorRewardRecipient)
|
|
1267
|
+
} : {},
|
|
1268
|
+
...answers.rewardsConfig.interfaceAdmin ? {
|
|
1269
|
+
interfaceAdmin: toHexAddress(answers.rewardsConfig.interfaceAdmin)
|
|
1270
|
+
} : {},
|
|
1271
|
+
...answers.rewardsConfig.interfaceRewardRecipient ? {
|
|
1272
|
+
interfaceRewardRecipient: toHexAddress(answers.rewardsConfig.interfaceRewardRecipient)
|
|
1273
|
+
} : {}
|
|
1159
1274
|
}
|
|
1160
1275
|
};
|
|
1161
1276
|
}
|
|
@@ -1204,11 +1319,7 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1204
1319
|
symbol: answers.symbol,
|
|
1205
1320
|
salt: answers.salt || "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
1206
1321
|
image: answers.image,
|
|
1207
|
-
metadata:
|
|
1208
|
-
description: `${answers.name} token deployed via Clanker CLI`,
|
|
1209
|
-
socialMediaUrls: [],
|
|
1210
|
-
auditUrls: []
|
|
1211
|
-
},
|
|
1322
|
+
metadata: answers.metadata,
|
|
1212
1323
|
context: {
|
|
1213
1324
|
interface: "Clanker CLI",
|
|
1214
1325
|
platform: "Clanker",
|
|
@@ -1222,16 +1333,37 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1222
1333
|
pool: {
|
|
1223
1334
|
quoteToken,
|
|
1224
1335
|
initialMarketCap: answers.initialMarketCapUsd
|
|
1225
|
-
// Pass raw value, SDK will handle decimals
|
|
1226
1336
|
},
|
|
1227
1337
|
devBuy: answers.devBuy.ethAmount !== "0" ? {
|
|
1228
1338
|
ethAmount: answers.devBuy.ethAmount,
|
|
1229
1339
|
maxSlippage: answers.devBuy.maxSlippage
|
|
1230
|
-
} : void 0
|
|
1340
|
+
} : void 0,
|
|
1341
|
+
rewardsConfig: {
|
|
1342
|
+
creatorReward: answers.rewardsConfig.creatorReward === "CUSTOM" ? Number(answers.rewardsConfig.customCreatorReward) : Number(answers.rewardsConfig.creatorReward),
|
|
1343
|
+
...answers.rewardsConfig.creatorAdmin ? {
|
|
1344
|
+
creatorAdmin: toHexAddress(answers.rewardsConfig.creatorAdmin)
|
|
1345
|
+
} : {},
|
|
1346
|
+
...answers.rewardsConfig.creatorRewardRecipient ? {
|
|
1347
|
+
creatorRewardRecipient: toHexAddress(answers.rewardsConfig.creatorRewardRecipient)
|
|
1348
|
+
} : {},
|
|
1349
|
+
...answers.rewardsConfig.interfaceAdmin ? {
|
|
1350
|
+
interfaceAdmin: toHexAddress(answers.rewardsConfig.interfaceAdmin)
|
|
1351
|
+
} : {},
|
|
1352
|
+
...answers.rewardsConfig.interfaceRewardRecipient ? {
|
|
1353
|
+
interfaceRewardRecipient: toHexAddress(answers.rewardsConfig.interfaceRewardRecipient)
|
|
1354
|
+
} : {}
|
|
1355
|
+
}
|
|
1231
1356
|
});
|
|
1357
|
+
console.log("\n\u2728 Deployment successful!");
|
|
1358
|
+
console.log(`\u{1F4CD} Token address: ${tokenAddress}`);
|
|
1359
|
+
console.log("\n\u{1F310} View on:");
|
|
1360
|
+
console.log(`Basescan: https://basescan.org/token/${tokenAddress}`);
|
|
1361
|
+
console.log(`Clanker World: https://clanker.world/clanker/${tokenAddress}`);
|
|
1232
1362
|
return tokenAddress;
|
|
1233
1363
|
}
|
|
1234
1364
|
async function main() {
|
|
1365
|
+
console.clear();
|
|
1366
|
+
console.log(ASCII_ART);
|
|
1235
1367
|
console.log("\n\u{1F680} Welcome to the Clanker Token Creator! \u{1F680}\n");
|
|
1236
1368
|
if (!checkEnvironment()) {
|
|
1237
1369
|
process.exit(1);
|
|
@@ -1245,23 +1377,22 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1245
1377
|
type: "confirm",
|
|
1246
1378
|
name: "confirm",
|
|
1247
1379
|
message: "Would you like to proceed with deployment?",
|
|
1248
|
-
default: false
|
|
1380
|
+
default: false,
|
|
1381
|
+
prefix: ""
|
|
1249
1382
|
}
|
|
1250
1383
|
]);
|
|
1251
1384
|
if (confirm) {
|
|
1252
1385
|
console.log("\n\u{1F504} Deploying your token...");
|
|
1253
1386
|
try {
|
|
1254
1387
|
const tokenAddress = await deployToken(answers);
|
|
1255
|
-
|
|
1256
|
-
console.log("\u{1F4CD} Token address:", tokenAddress);
|
|
1257
|
-
console.log("\n\u{1F310} View on Basescan:");
|
|
1258
|
-
console.log(`https://basescan.org/token/${tokenAddress}`);
|
|
1388
|
+
process.exit(0);
|
|
1259
1389
|
} catch (error) {
|
|
1260
1390
|
console.error("\n\u274C Deployment failed:", error instanceof Error ? error.message : "Unknown error");
|
|
1261
1391
|
process.exit(1);
|
|
1262
1392
|
}
|
|
1263
1393
|
} else {
|
|
1264
1394
|
console.log("\n\u274C Deployment cancelled");
|
|
1395
|
+
process.exit(0);
|
|
1265
1396
|
}
|
|
1266
1397
|
} catch (error) {
|
|
1267
1398
|
console.error("\n\u274C Error:", error);
|
|
@@ -1270,7 +1401,7 @@ RPC_URL=your_custom_rpc_url (if not provided, will use default Base RPC)
|
|
|
1270
1401
|
}
|
|
1271
1402
|
await main();
|
|
1272
1403
|
}
|
|
1273
|
-
createClanker
|
|
1404
|
+
var create_clanker_default = createClanker;
|
|
1274
1405
|
export {
|
|
1275
|
-
|
|
1406
|
+
create_clanker_default as default
|
|
1276
1407
|
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { PublicClient, WalletClient, Address } from 'viem';
|
|
2
|
+
|
|
3
|
+
interface TokenConfig {
|
|
4
|
+
name: string;
|
|
5
|
+
symbol: string;
|
|
6
|
+
salt: `0x${string}`;
|
|
7
|
+
image: string;
|
|
8
|
+
metadata: IClankerMetadata;
|
|
9
|
+
context: IClankerSocialContext;
|
|
10
|
+
originatingChainId: bigint;
|
|
11
|
+
}
|
|
12
|
+
interface VaultConfig {
|
|
13
|
+
vaultPercentage: number;
|
|
14
|
+
vaultDuration: bigint;
|
|
15
|
+
}
|
|
16
|
+
interface PoolConfig {
|
|
17
|
+
pairedToken: Address;
|
|
18
|
+
initialMarketCapInPairedToken: bigint;
|
|
19
|
+
initialMarketCap?: string;
|
|
20
|
+
tickIfToken0IsNewToken?: number;
|
|
21
|
+
}
|
|
22
|
+
interface InitialBuyConfig {
|
|
23
|
+
pairedTokenPoolFee: number;
|
|
24
|
+
pairedTokenSwapAmountOutMinimum: bigint;
|
|
25
|
+
ethAmount?: bigint;
|
|
26
|
+
}
|
|
27
|
+
interface RewardsConfig {
|
|
28
|
+
creatorReward: bigint;
|
|
29
|
+
creatorAdmin: Address;
|
|
30
|
+
creatorRewardRecipient: Address;
|
|
31
|
+
interfaceAdmin: Address;
|
|
32
|
+
interfaceRewardRecipient: Address;
|
|
33
|
+
}
|
|
34
|
+
interface DeploymentConfig {
|
|
35
|
+
tokenConfig: TokenConfig;
|
|
36
|
+
vaultConfig?: VaultConfig;
|
|
37
|
+
poolConfig: PoolConfig;
|
|
38
|
+
initialBuyConfig?: InitialBuyConfig;
|
|
39
|
+
rewardsConfig: RewardsConfig;
|
|
40
|
+
}
|
|
41
|
+
type ClankerConfig = {
|
|
42
|
+
publicClient: PublicClient;
|
|
43
|
+
wallet?: WalletClient;
|
|
44
|
+
factoryAddress?: Address;
|
|
45
|
+
};
|
|
46
|
+
interface SimpleTokenConfig {
|
|
47
|
+
name: string;
|
|
48
|
+
symbol: string;
|
|
49
|
+
salt?: `0x${string}`;
|
|
50
|
+
image?: string;
|
|
51
|
+
metadata?: {
|
|
52
|
+
description: string;
|
|
53
|
+
socialMediaUrls: string[];
|
|
54
|
+
auditUrls: string[];
|
|
55
|
+
};
|
|
56
|
+
context?: {
|
|
57
|
+
interface: string;
|
|
58
|
+
platform: string;
|
|
59
|
+
messageId: string;
|
|
60
|
+
id: string;
|
|
61
|
+
};
|
|
62
|
+
pool?: {
|
|
63
|
+
quoteToken?: `0x${string}`;
|
|
64
|
+
initialMarketCap?: string;
|
|
65
|
+
};
|
|
66
|
+
vault?: {
|
|
67
|
+
percentage: number;
|
|
68
|
+
durationInDays: number;
|
|
69
|
+
};
|
|
70
|
+
devBuy?: {
|
|
71
|
+
ethAmount: string;
|
|
72
|
+
maxSlippage?: number;
|
|
73
|
+
};
|
|
74
|
+
rewardsConfig?: {
|
|
75
|
+
creatorReward?: number;
|
|
76
|
+
creatorAdmin?: `0x${string}`;
|
|
77
|
+
creatorRewardRecipient?: `0x${string}`;
|
|
78
|
+
interfaceAdmin?: `0x${string}`;
|
|
79
|
+
interfaceRewardRecipient?: `0x${string}`;
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
interface IClankerMetadata {
|
|
83
|
+
description?: string;
|
|
84
|
+
socialMediaUrls?: {
|
|
85
|
+
platform: string;
|
|
86
|
+
url: string;
|
|
87
|
+
}[];
|
|
88
|
+
auditUrls?: string[];
|
|
89
|
+
}
|
|
90
|
+
interface IClankerSocialContext {
|
|
91
|
+
interface: string;
|
|
92
|
+
platform?: string;
|
|
93
|
+
messageId?: string;
|
|
94
|
+
id?: string;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Lightweight container for a pre-built deploy transaction */
|
|
98
|
+
type PreparedDeployTx = {
|
|
99
|
+
to: Address;
|
|
100
|
+
data: `0x${string}`;
|
|
101
|
+
value: bigint;
|
|
102
|
+
};
|
|
103
|
+
declare class Clanker {
|
|
104
|
+
private readonly wallet?;
|
|
105
|
+
private readonly factoryAddress;
|
|
106
|
+
private readonly publicClient;
|
|
107
|
+
constructor(config: ClankerConfig);
|
|
108
|
+
private getQuoteTokenDecimals;
|
|
109
|
+
private findMostLiquidPool;
|
|
110
|
+
private calculateMinimumOutput;
|
|
111
|
+
private calculateTickForQuoteToken;
|
|
112
|
+
private handleError;
|
|
113
|
+
deploy(config: DeploymentConfig): Promise<Address>;
|
|
114
|
+
private buildDeploymentConfig;
|
|
115
|
+
/**
|
|
116
|
+
* Creates calldata (+ msg.value) **without** sending a transaction.
|
|
117
|
+
* This version no longer relies on viem's `simulateContract`, which
|
|
118
|
+
* was returning an object without `.data`. We now ABI-encode the
|
|
119
|
+
* call manually so `data` is always defined.
|
|
120
|
+
*/
|
|
121
|
+
prepareDeployToken(cfg: SimpleTokenConfig): Promise<PreparedDeployTx>;
|
|
122
|
+
deployToken(cfg: SimpleTokenConfig): Promise<Address>;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export { Clanker, type ClankerConfig, type DeploymentConfig, type IClankerMetadata, type IClankerSocialContext, type InitialBuyConfig, type PoolConfig, type PreparedDeployTx, type RewardsConfig, type SimpleTokenConfig, type TokenConfig, type VaultConfig };
|
package/dist/index.js
CHANGED
|
@@ -774,7 +774,14 @@ var Clanker = class {
|
|
|
774
774
|
tokenConfig: {
|
|
775
775
|
name: cfg.name,
|
|
776
776
|
symbol: cfg.symbol,
|
|
777
|
-
salt:
|
|
777
|
+
salt: (() => {
|
|
778
|
+
const defaultSalt = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
779
|
+
const salt = cfg.salt ?? defaultSalt;
|
|
780
|
+
if (!/^0x[a-fA-F0-9]{64}$/.test(salt)) {
|
|
781
|
+
throw new Error("Salt must be a valid bytes32 value (0x + 64 hex characters)");
|
|
782
|
+
}
|
|
783
|
+
return salt;
|
|
784
|
+
})(),
|
|
778
785
|
image: cfg.image || "https://ipfs.io/ipfs/QmcjfTeK3tpK3MVCQuvEaXvSscrqbL3MwsEo8LdBTWabY4",
|
|
779
786
|
metadata: JSON.stringify(cfg.metadata || {
|
|
780
787
|
description: "Clanker Token",
|
|
@@ -803,12 +810,17 @@ var Clanker = class {
|
|
|
803
810
|
},
|
|
804
811
|
initialBuyConfig,
|
|
805
812
|
rewardsConfig: {
|
|
806
|
-
creatorReward:
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
813
|
+
creatorReward: (() => {
|
|
814
|
+
const reward = cfg.rewardsConfig?.creatorReward ?? 80;
|
|
815
|
+
if (reward < 0 || reward > 80) {
|
|
816
|
+
throw new Error("Creator reward must be between 0 and 80");
|
|
817
|
+
}
|
|
818
|
+
return BigInt(reward);
|
|
819
|
+
})(),
|
|
820
|
+
creatorAdmin: cfg.rewardsConfig?.creatorAdmin ?? deployerAddress,
|
|
821
|
+
creatorRewardRecipient: cfg.rewardsConfig?.creatorRewardRecipient ?? deployerAddress,
|
|
822
|
+
interfaceAdmin: cfg.rewardsConfig?.interfaceAdmin ?? deployerAddress,
|
|
823
|
+
interfaceRewardRecipient: cfg.rewardsConfig?.interfaceRewardRecipient ?? deployerAddress
|
|
812
824
|
}
|
|
813
825
|
};
|
|
814
826
|
}
|