create-polymarket-strategy 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -7,6 +7,173 @@ import path from "path";
7
7
  import { execSync } from "child_process";
8
8
  import pc from "picocolors";
9
9
  import { fileURLToPath } from "url";
10
+
11
+ // src/wallet/index.ts
12
+ import { ethers } from "ethers";
13
+
14
+ // src/wallet/constants.ts
15
+ var CHAIN_ID = 137;
16
+ var RPC_URL = "https://1rpc.io/matic";
17
+ var CLOB_API = "https://clob.polymarket.com";
18
+ var USDC_NATIVE = "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359";
19
+ var USDC_E = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174";
20
+ var CTF_ADDRESS = "0x4D97DCd97eC945f40cF65F87097ACe5EA0476045";
21
+ var EXCHANGE_CONTRACTS = [
22
+ { address: "0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E", name: "CTF Exchange" },
23
+ { address: "0xC5d563A36AE78145C45a50134d48A1215220f80a", name: "Neg Risk CTF Exchange" },
24
+ { address: "0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296", name: "Neg Risk Adapter" }
25
+ ];
26
+ var CLOB_AUTH_DOMAIN = {
27
+ name: "ClobAuthDomain",
28
+ version: "1",
29
+ chainId: CHAIN_ID
30
+ };
31
+ var CLOB_AUTH_MESSAGE = "This message attests that I control the given wallet";
32
+ var ERC20_ABI = [
33
+ "function balanceOf(address owner) view returns (uint256)",
34
+ "function approve(address spender, uint256 amount) returns (bool)",
35
+ "function allowance(address owner, address spender) view returns (uint256)"
36
+ ];
37
+ var ERC1155_ABI = [
38
+ "function setApprovalForAll(address operator, bool approved)",
39
+ "function isApprovedForAll(address account, address operator) view returns (bool)"
40
+ ];
41
+
42
+ // src/wallet/index.ts
43
+ function generateWallet() {
44
+ const wallet = ethers.Wallet.createRandom();
45
+ return {
46
+ address: wallet.address,
47
+ privateKey: wallet.privateKey
48
+ };
49
+ }
50
+ async function signClobAuthMessage(wallet, timestamp, nonce) {
51
+ const types = {
52
+ ClobAuth: [
53
+ { name: "address", type: "address" },
54
+ { name: "timestamp", type: "string" },
55
+ { name: "nonce", type: "uint256" },
56
+ { name: "message", type: "string" }
57
+ ]
58
+ };
59
+ const value = {
60
+ address: wallet.address,
61
+ timestamp: timestamp.toString(),
62
+ nonce,
63
+ message: CLOB_AUTH_MESSAGE
64
+ };
65
+ return wallet.signTypedData(CLOB_AUTH_DOMAIN, types, value);
66
+ }
67
+ async function deriveApiCredentials(privateKey, nonce = 0) {
68
+ const wallet = new ethers.Wallet(privateKey);
69
+ const timestamp = Math.floor(Date.now() / 1e3);
70
+ const signature = await signClobAuthMessage(wallet, timestamp, nonce);
71
+ const headers = {
72
+ "POLY_ADDRESS": wallet.address,
73
+ "POLY_SIGNATURE": signature,
74
+ "POLY_TIMESTAMP": timestamp.toString(),
75
+ "POLY_NONCE": nonce.toString()
76
+ };
77
+ let response = await fetch(`${CLOB_API}/auth/derive-api-key`, {
78
+ method: "GET",
79
+ headers
80
+ });
81
+ if (!response.ok) {
82
+ response = await fetch(`${CLOB_API}/auth/api-key`, {
83
+ method: "POST",
84
+ headers
85
+ });
86
+ }
87
+ if (!response.ok) {
88
+ const text = await response.text();
89
+ throw new Error(`Failed to derive API credentials: ${response.status} ${text}`);
90
+ }
91
+ const data = await response.json();
92
+ return {
93
+ apiKey: data.apiKey,
94
+ apiSecret: data.secret,
95
+ apiPassphrase: data.passphrase
96
+ };
97
+ }
98
+ function getProvider() {
99
+ return new ethers.JsonRpcProvider(RPC_URL, CHAIN_ID);
100
+ }
101
+ async function getBalances(address) {
102
+ const provider = getProvider();
103
+ const polBalance = await provider.getBalance(address);
104
+ const pol = Number(ethers.formatEther(polBalance));
105
+ const usdcNativeContract = new ethers.Contract(USDC_NATIVE, ERC20_ABI, provider);
106
+ const usdcNativeBalance = await usdcNativeContract.balanceOf(address);
107
+ const usdcNative = Number(ethers.formatUnits(usdcNativeBalance, 6));
108
+ const usdcEContract = new ethers.Contract(USDC_E, ERC20_ABI, provider);
109
+ const usdcEBalance = await usdcEContract.balanceOf(address);
110
+ const usdcE = Number(ethers.formatUnits(usdcEBalance, 6));
111
+ return {
112
+ address,
113
+ pol,
114
+ usdcNative,
115
+ usdcE,
116
+ totalUsdc: usdcNative + usdcE
117
+ };
118
+ }
119
+ async function approveExchangeContracts(privateKey, onProgress) {
120
+ const provider = getProvider();
121
+ const wallet = new ethers.Wallet(privateKey, provider);
122
+ const results = [];
123
+ const usdcE = new ethers.Contract(USDC_E, ERC20_ABI, wallet);
124
+ const ctf = new ethers.Contract(CTF_ADDRESS, ERC1155_ABI, wallet);
125
+ const maxApproval = ethers.MaxUint256;
126
+ for (const exchange of EXCHANGE_CONTRACTS) {
127
+ const result = {
128
+ contract: exchange.name,
129
+ usdcApproved: false,
130
+ ctfApproved: false
131
+ };
132
+ const currentAllowance = await usdcE.allowance(wallet.address, exchange.address);
133
+ if (currentAllowance < ethers.parseUnits("1000000000", 6)) {
134
+ onProgress?.(`Approving USDC.e for ${exchange.name}...`);
135
+ const tx = await usdcE.approve(exchange.address, maxApproval);
136
+ const receipt = await tx.wait();
137
+ result.usdcTxHash = receipt.hash;
138
+ result.usdcApproved = true;
139
+ } else {
140
+ onProgress?.(`USDC.e already approved for ${exchange.name}`);
141
+ result.usdcApproved = true;
142
+ }
143
+ const isApproved = await ctf.isApprovedForAll(wallet.address, exchange.address);
144
+ if (!isApproved) {
145
+ onProgress?.(`Approving CTF for ${exchange.name}...`);
146
+ const tx = await ctf.setApprovalForAll(exchange.address, true);
147
+ const receipt = await tx.wait();
148
+ result.ctfTxHash = receipt.hash;
149
+ result.ctfApproved = true;
150
+ } else {
151
+ onProgress?.(`CTF already approved for ${exchange.name}`);
152
+ result.ctfApproved = true;
153
+ }
154
+ results.push(result);
155
+ }
156
+ return results;
157
+ }
158
+ async function checkApprovals(address) {
159
+ const provider = getProvider();
160
+ const usdcE = new ethers.Contract(USDC_E, ERC20_ABI, provider);
161
+ const ctf = new ethers.Contract(CTF_ADDRESS, ERC1155_ABI, provider);
162
+ const details = [];
163
+ for (const exchange of EXCHANGE_CONTRACTS) {
164
+ const allowance = await usdcE.allowance(address, exchange.address);
165
+ const isCtfApproved = await ctf.isApprovedForAll(address, exchange.address);
166
+ details.push({
167
+ contract: exchange.name,
168
+ usdcApproved: allowance > 0n,
169
+ ctfApproved: isCtfApproved
170
+ });
171
+ }
172
+ const allApproved = details.every((d) => d.usdcApproved && d.ctfApproved);
173
+ return { allApproved, details };
174
+ }
175
+
176
+ // src/index.ts
10
177
  var __dirname = path.dirname(fileURLToPath(import.meta.url));
11
178
  var TEMPLATE_DIR = path.resolve(__dirname, "..", "templates", "worker");
12
179
  function toKebabCase(str) {
@@ -22,7 +189,10 @@ function toCamelCase(str) {
22
189
  async function replaceInFile(filePath, replacements) {
23
190
  let content = await fs.readFile(filePath, "utf-8");
24
191
  for (const [key, value] of Object.entries(replacements)) {
25
- content = content.replace(new RegExp(key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), value);
192
+ content = content.replace(
193
+ new RegExp(key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"),
194
+ value
195
+ );
26
196
  }
27
197
  await fs.writeFile(filePath, content);
28
198
  }
@@ -59,7 +229,7 @@ async function renameFiles(dir, replacements) {
59
229
  }
60
230
  }
61
231
  }
62
- async function create(name, options) {
232
+ async function createStrategy(name, options) {
63
233
  const targetDir = path.resolve(process.cwd(), name);
64
234
  const strategyName = toKebabCase(name);
65
235
  const strategyClassName = toPascalCase(name);
@@ -96,9 +266,13 @@ async function create(name, options) {
96
266
  } catch {
97
267
  try {
98
268
  execSync("npm install", { cwd: targetDir, stdio: "pipe" });
99
- } catch (e) {
100
- console.log(pc.yellow(" Could not install dependencies automatically."));
101
- console.log(pc.yellow(" Run 'npm install' or 'pnpm install' manually."));
269
+ } catch {
270
+ console.log(
271
+ pc.yellow(" Could not install dependencies automatically.")
272
+ );
273
+ console.log(
274
+ pc.yellow(" Run 'npm install' or 'pnpm install' manually.")
275
+ );
102
276
  }
103
277
  }
104
278
  }
@@ -122,6 +296,185 @@ async function create(name, options) {
122
296
  console.log(pc.cyan(" wrangler deploy"));
123
297
  console.log();
124
298
  }
125
- program.name("create-polymarket-strategy").description("Create a new Polymarket trading strategy project").version("0.1.0").argument("<name>", "Project name").option("--no-git", "Skip git initialization").option("--no-install", "Skip dependency installation").action(create);
299
+ async function walletCreate() {
300
+ console.log();
301
+ console.log(pc.cyan("Creating new Polymarket wallet..."));
302
+ console.log();
303
+ console.log(` ${pc.yellow("\u2192")} Generating Ethereum wallet...`);
304
+ const wallet = generateWallet();
305
+ console.log(` ${pc.green("\u2713")} Address: ${pc.bold(wallet.address)}`);
306
+ console.log(` ${pc.yellow("\u2192")} Deriving Polymarket API credentials...`);
307
+ try {
308
+ const apiCreds = await deriveApiCredentials(wallet.privateKey);
309
+ console.log(` ${pc.green("\u2713")} API credentials derived`);
310
+ console.log();
311
+ console.log(pc.cyan("\u2550".repeat(60)));
312
+ console.log(pc.bold("SAVE THESE CREDENTIALS SECURELY"));
313
+ console.log(pc.cyan("\u2550".repeat(60)));
314
+ console.log();
315
+ console.log(`${pc.bold("Address:")} ${wallet.address}`);
316
+ console.log(`${pc.bold("Private Key:")} ${wallet.privateKey}`);
317
+ console.log(`${pc.bold("API Key:")} ${apiCreds.apiKey}`);
318
+ console.log(`${pc.bold("API Secret:")} ${apiCreds.apiSecret}`);
319
+ console.log(`${pc.bold("API Passphrase:")} ${apiCreds.apiPassphrase}`);
320
+ console.log();
321
+ console.log(pc.cyan("\u2550".repeat(60)));
322
+ console.log();
323
+ console.log(pc.bold("Next steps:"));
324
+ console.log();
325
+ console.log(
326
+ ` 1. ${pc.yellow("Fund this wallet on Polygon network:")}`
327
+ );
328
+ console.log(` - Send USDC to: ${wallet.address}`);
329
+ console.log(` - Send ~1 POL for gas fees`);
330
+ console.log();
331
+ console.log(` 2. ${pc.yellow("Run on-chain setup:")}`);
332
+ console.log(
333
+ ` npx create-polymarket-strategy wallet setup --private-key ${wallet.privateKey}`
334
+ );
335
+ console.log();
336
+ console.log(` 3. ${pc.yellow("Add secrets to your worker:")}`);
337
+ console.log(` wrangler secret put EXECUTOR_API_KEY`);
338
+ console.log();
339
+ } catch (error) {
340
+ console.log(` ${pc.red("\u2717")} Failed to derive API credentials`);
341
+ console.log(
342
+ pc.yellow(
343
+ " This may be a network issue. You can derive credentials later."
344
+ )
345
+ );
346
+ console.log();
347
+ console.log(pc.cyan("\u2550".repeat(60)));
348
+ console.log(pc.bold("WALLET CREATED (API credentials pending)"));
349
+ console.log(pc.cyan("\u2550".repeat(60)));
350
+ console.log();
351
+ console.log(`${pc.bold("Address:")} ${wallet.address}`);
352
+ console.log(`${pc.bold("Private Key:")} ${wallet.privateKey}`);
353
+ console.log();
354
+ console.log(
355
+ pc.yellow(
356
+ "Fund the wallet and re-run to derive API credentials."
357
+ )
358
+ );
359
+ console.log();
360
+ }
361
+ }
362
+ async function walletBalance(address) {
363
+ console.log();
364
+ console.log(pc.cyan(`Checking balances for ${address}...`));
365
+ console.log();
366
+ try {
367
+ const balances = await getBalances(address);
368
+ console.log(pc.cyan("\u2550".repeat(50)));
369
+ console.log(pc.bold("Polymarket Wallet Balance"));
370
+ console.log(pc.cyan("\u2550".repeat(50)));
371
+ console.log();
372
+ console.log(
373
+ ` ${pc.bold("POL:")} ${balances.pol.toFixed(4)} (~$${(balances.pol * 0.4).toFixed(2)})`
374
+ );
375
+ console.log(` ${pc.bold("USDC:")} $${balances.usdcNative.toFixed(2)}`);
376
+ console.log(
377
+ ` ${pc.bold("USDC.e:")} $${balances.usdcE.toFixed(2)} ${pc.dim("(Polymarket uses this)")}`
378
+ );
379
+ console.log();
380
+ console.log(` ${pc.bold("Total USDC:")} $${balances.totalUsdc.toFixed(2)}`);
381
+ console.log();
382
+ console.log(pc.cyan("\u2550".repeat(50)));
383
+ console.log(`View: https://polygonscan.com/address/${address}`);
384
+ console.log();
385
+ const approvals = await checkApprovals(address);
386
+ if (approvals.allApproved) {
387
+ console.log(pc.green("\u2713 All exchange contracts approved"));
388
+ } else {
389
+ console.log(pc.yellow("\u26A0 Some contracts not approved:"));
390
+ for (const detail of approvals.details) {
391
+ const status = detail.usdcApproved && detail.ctfApproved ? pc.green("\u2713") : pc.red("\u2717");
392
+ console.log(` ${status} ${detail.contract}`);
393
+ }
394
+ console.log();
395
+ console.log(
396
+ pc.dim("Run 'npx create-polymarket-strategy wallet setup' to approve")
397
+ );
398
+ }
399
+ console.log();
400
+ } catch (error) {
401
+ console.error(pc.red(`Error: ${error}`));
402
+ process.exit(1);
403
+ }
404
+ }
405
+ async function walletSetup(privateKey) {
406
+ console.log();
407
+ console.log(pc.cyan("Setting up wallet for Polymarket trading..."));
408
+ console.log();
409
+ try {
410
+ const { ethers: ethers2 } = await import("ethers");
411
+ const wallet = new ethers2.Wallet(privateKey);
412
+ const address = wallet.address;
413
+ console.log(` ${pc.bold("Address:")} ${address}`);
414
+ console.log();
415
+ console.log(pc.yellow("Checking balances..."));
416
+ const balances = await getBalances(address);
417
+ console.log(` POL: ${balances.pol.toFixed(4)}`);
418
+ console.log(` USDC: $${balances.usdcNative.toFixed(2)}`);
419
+ console.log(` USDC.e: $${balances.usdcE.toFixed(2)}`);
420
+ console.log();
421
+ if (balances.pol < 0.01) {
422
+ console.error(pc.red("Error: Need at least 0.01 POL for gas fees"));
423
+ console.log(`Send POL to: ${address}`);
424
+ process.exit(1);
425
+ }
426
+ if (balances.usdcNative > 1 && balances.usdcE < 1) {
427
+ console.log(
428
+ pc.yellow(
429
+ "Note: You have native USDC but Polymarket requires USDC.e"
430
+ )
431
+ );
432
+ console.log(
433
+ pc.yellow("Use a DEX like Uniswap to swap USDC \u2192 USDC.e first")
434
+ );
435
+ console.log();
436
+ }
437
+ console.log(pc.yellow("Approving Polymarket exchange contracts..."));
438
+ console.log(
439
+ pc.dim("(3 contracts x 2 approvals each = up to 6 transactions)")
440
+ );
441
+ console.log();
442
+ const results = await approveExchangeContracts(privateKey, (msg) => {
443
+ console.log(` ${pc.yellow("\u2192")} ${msg}`);
444
+ });
445
+ console.log();
446
+ let txCount = 0;
447
+ for (const result of results) {
448
+ if (result.usdcTxHash) txCount++;
449
+ if (result.ctfTxHash) txCount++;
450
+ }
451
+ console.log(pc.cyan("\u2550".repeat(50)));
452
+ console.log(pc.bold("Setup Complete"));
453
+ console.log(pc.cyan("\u2550".repeat(50)));
454
+ console.log();
455
+ console.log(` ${pc.green("\u2713")} All contracts approved`);
456
+ console.log(` ${pc.dim(`${txCount} transaction(s) submitted`)}`);
457
+ console.log();
458
+ console.log(` USDC.e balance: $${balances.usdcE.toFixed(2)}`);
459
+ console.log();
460
+ console.log(pc.bold("Your wallet is ready for live trading!"));
461
+ console.log();
462
+ } catch (error) {
463
+ console.error(pc.red(`Error: ${error}`));
464
+ process.exit(1);
465
+ }
466
+ }
467
+ program.name("create-polymarket-strategy").description("Create and manage Polymarket trading strategies").version("0.2.0");
468
+ program.argument("[name]", "Project name").option("--no-git", "Skip git initialization").option("--no-install", "Skip dependency installation").action(async (name, options) => {
469
+ if (name) {
470
+ await createStrategy(name, options);
471
+ } else {
472
+ program.help();
473
+ }
474
+ });
475
+ var walletCmd = program.command("wallet").description("Wallet management commands");
476
+ walletCmd.command("create").description("Create a new wallet and derive API credentials").action(walletCreate);
477
+ walletCmd.command("balance").description("Check wallet balances").argument("<address>", "Wallet address").action(walletBalance);
478
+ walletCmd.command("setup").description("Approve exchange contracts for trading").requiredOption("--private-key <key>", "Wallet private key").action((options) => walletSetup(options.privateKey));
126
479
  program.parse();
127
480
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { program } from \"commander\";\nimport fs from \"fs-extra\";\nimport path from \"path\";\nimport { execSync } from \"child_process\";\nimport pc from \"picocolors\";\nimport { fileURLToPath } from \"url\";\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n// Template directory is at the package root, not in dist\nconst TEMPLATE_DIR = path.resolve(__dirname, \"..\", \"templates\", \"worker\");\n\ninterface Options {\n git: boolean;\n install: boolean;\n}\n\nfunction toKebabCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, \"$1-$2\")\n .replace(/[\\s_]+/g, \"-\")\n .toLowerCase();\n}\n\nfunction toPascalCase(str: string): string {\n return str\n .split(/[-_\\s]+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(\"\");\n}\n\nfunction toCamelCase(str: string): string {\n const pascal = toPascalCase(str);\n return pascal.charAt(0).toLowerCase() + pascal.slice(1);\n}\n\nasync function replaceInFile(\n filePath: string,\n replacements: Record<string, string>\n): Promise<void> {\n let content = await fs.readFile(filePath, \"utf-8\");\n for (const [key, value] of Object.entries(replacements)) {\n content = content.replace(new RegExp(key.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"), \"g\"), value);\n }\n await fs.writeFile(filePath, content);\n}\n\nasync function replaceInFiles(\n dir: string,\n replacements: Record<string, string>\n): Promise<void> {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n await replaceInFiles(fullPath, replacements);\n } else if (entry.isFile()) {\n // Only process text files\n const ext = path.extname(entry.name);\n if ([\".ts\", \".js\", \".json\", \".jsonc\", \".md\", \".txt\", \"\"].includes(ext)) {\n await replaceInFile(fullPath, replacements);\n }\n }\n }\n}\n\nasync function renameFiles(\n dir: string,\n replacements: Record<string, string>\n): Promise<void> {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n await renameFiles(fullPath, replacements);\n }\n\n // Check if filename needs renaming\n let newName = entry.name;\n for (const [key, value] of Object.entries(replacements)) {\n if (newName.includes(key)) {\n newName = newName.replace(key, value);\n }\n }\n\n if (newName !== entry.name) {\n const newPath = path.join(dir, newName);\n await fs.rename(fullPath, newPath);\n }\n }\n}\n\nasync function create(name: string, options: Options): Promise<void> {\n const targetDir = path.resolve(process.cwd(), name);\n const strategyName = toKebabCase(name);\n const strategyClassName = toPascalCase(name);\n const strategyVarName = toCamelCase(name);\n\n // Check if target exists\n if (await fs.pathExists(targetDir)) {\n console.error(pc.red(`Error: Directory \"${name}\" already exists.`));\n process.exit(1);\n }\n\n // Check if template exists\n if (!(await fs.pathExists(TEMPLATE_DIR))) {\n console.error(pc.red(`Error: Template not found at ${TEMPLATE_DIR}`));\n console.error(pc.yellow(\"This may be a development installation issue.\"));\n process.exit(1);\n }\n\n console.log();\n console.log(pc.cyan(`Creating Polymarket strategy: ${pc.bold(name)}`));\n console.log();\n\n // Copy template\n console.log(` ${pc.green(\"✓\")} Copying template...`);\n await fs.copy(TEMPLATE_DIR, targetDir);\n\n // Replace placeholders\n console.log(` ${pc.green(\"✓\")} Configuring project...`);\n const replacements = {\n \"{{name}}\": name,\n \"{{strategy-name}}\": strategyName,\n \"{{StrategyName}}\": strategyClassName,\n \"{{strategyName}}\": strategyVarName,\n };\n await replaceInFiles(targetDir, replacements);\n await renameFiles(targetDir, {\n \"{{strategy-name}}\": strategyName,\n });\n\n // Install dependencies\n if (options.install) {\n console.log(` ${pc.green(\"✓\")} Installing dependencies...`);\n try {\n execSync(\"pnpm install\", { cwd: targetDir, stdio: \"pipe\" });\n } catch {\n try {\n execSync(\"npm install\", { cwd: targetDir, stdio: \"pipe\" });\n } catch (e) {\n console.log(pc.yellow(\" Could not install dependencies automatically.\"));\n console.log(pc.yellow(\" Run 'npm install' or 'pnpm install' manually.\"));\n }\n }\n }\n\n // Initialize git\n if (options.git) {\n console.log(` ${pc.green(\"✓\")} Initializing git repository...`);\n try {\n execSync(\"git init\", { cwd: targetDir, stdio: \"pipe\" });\n execSync(\"git add -A\", { cwd: targetDir, stdio: \"pipe\" });\n } catch {\n console.log(pc.yellow(\" Could not initialize git repository.\"));\n }\n }\n\n // Success message\n console.log();\n console.log(pc.green(\"Done! \") + pc.bold(`Created ${name}`));\n console.log();\n console.log(\"Next steps:\");\n console.log();\n console.log(pc.cyan(` cd ${name}`));\n console.log(pc.cyan(` # Edit src/strategies/${strategyName}.ts`));\n console.log(pc.cyan(\" # Configure wrangler.jsonc\"));\n console.log(pc.cyan(\" wrangler deploy\"));\n console.log();\n}\n\nprogram\n .name(\"create-polymarket-strategy\")\n .description(\"Create a new Polymarket trading strategy project\")\n .version(\"0.1.0\")\n .argument(\"<name>\", \"Project name\")\n .option(\"--no-git\", \"Skip git initialization\")\n .option(\"--no-install\", \"Skip dependency installation\")\n .action(create);\n\nprogram.parse();\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/wallet/index.ts","../src/wallet/constants.ts"],"sourcesContent":["import { program } from \"commander\";\nimport fs from \"fs-extra\";\nimport path from \"path\";\nimport { execSync } from \"child_process\";\nimport pc from \"picocolors\";\nimport { fileURLToPath } from \"url\";\nimport {\n generateWallet,\n deriveApiCredentials,\n getBalances,\n approveExchangeContracts,\n checkApprovals,\n} from \"./wallet/index.js\";\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n// Template directory is at the package root, not in dist\nconst TEMPLATE_DIR = path.resolve(__dirname, \"..\", \"templates\", \"worker\");\n\n// =============================================================================\n// Utility Functions\n// =============================================================================\n\nfunction toKebabCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, \"$1-$2\")\n .replace(/[\\s_]+/g, \"-\")\n .toLowerCase();\n}\n\nfunction toPascalCase(str: string): string {\n return str\n .split(/[-_\\s]+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(\"\");\n}\n\nfunction toCamelCase(str: string): string {\n const pascal = toPascalCase(str);\n return pascal.charAt(0).toLowerCase() + pascal.slice(1);\n}\n\nasync function replaceInFile(\n filePath: string,\n replacements: Record<string, string>\n): Promise<void> {\n let content = await fs.readFile(filePath, \"utf-8\");\n for (const [key, value] of Object.entries(replacements)) {\n content = content.replace(\n new RegExp(key.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"), \"g\"),\n value\n );\n }\n await fs.writeFile(filePath, content);\n}\n\nasync function replaceInFiles(\n dir: string,\n replacements: Record<string, string>\n): Promise<void> {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n await replaceInFiles(fullPath, replacements);\n } else if (entry.isFile()) {\n const ext = path.extname(entry.name);\n if ([\".ts\", \".js\", \".json\", \".jsonc\", \".md\", \".txt\", \"\"].includes(ext)) {\n await replaceInFile(fullPath, replacements);\n }\n }\n }\n}\n\nasync function renameFiles(\n dir: string,\n replacements: Record<string, string>\n): Promise<void> {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n await renameFiles(fullPath, replacements);\n }\n\n let newName = entry.name;\n for (const [key, value] of Object.entries(replacements)) {\n if (newName.includes(key)) {\n newName = newName.replace(key, value);\n }\n }\n\n if (newName !== entry.name) {\n const newPath = path.join(dir, newName);\n await fs.rename(fullPath, newPath);\n }\n }\n}\n\n// =============================================================================\n// Create Command\n// =============================================================================\n\ninterface CreateOptions {\n git: boolean;\n install: boolean;\n}\n\nasync function createStrategy(\n name: string,\n options: CreateOptions\n): Promise<void> {\n const targetDir = path.resolve(process.cwd(), name);\n const strategyName = toKebabCase(name);\n const strategyClassName = toPascalCase(name);\n const strategyVarName = toCamelCase(name);\n\n if (await fs.pathExists(targetDir)) {\n console.error(pc.red(`Error: Directory \"${name}\" already exists.`));\n process.exit(1);\n }\n\n if (!(await fs.pathExists(TEMPLATE_DIR))) {\n console.error(pc.red(`Error: Template not found at ${TEMPLATE_DIR}`));\n console.error(pc.yellow(\"This may be a development installation issue.\"));\n process.exit(1);\n }\n\n console.log();\n console.log(pc.cyan(`Creating Polymarket strategy: ${pc.bold(name)}`));\n console.log();\n\n console.log(` ${pc.green(\"✓\")} Copying template...`);\n await fs.copy(TEMPLATE_DIR, targetDir);\n\n console.log(` ${pc.green(\"✓\")} Configuring project...`);\n const replacements = {\n \"{{name}}\": name,\n \"{{strategy-name}}\": strategyName,\n \"{{StrategyName}}\": strategyClassName,\n \"{{strategyName}}\": strategyVarName,\n };\n await replaceInFiles(targetDir, replacements);\n await renameFiles(targetDir, {\n \"{{strategy-name}}\": strategyName,\n });\n\n if (options.install) {\n console.log(` ${pc.green(\"✓\")} Installing dependencies...`);\n try {\n execSync(\"pnpm install\", { cwd: targetDir, stdio: \"pipe\" });\n } catch {\n try {\n execSync(\"npm install\", { cwd: targetDir, stdio: \"pipe\" });\n } catch {\n console.log(\n pc.yellow(\" Could not install dependencies automatically.\")\n );\n console.log(\n pc.yellow(\" Run 'npm install' or 'pnpm install' manually.\")\n );\n }\n }\n }\n\n if (options.git) {\n console.log(` ${pc.green(\"✓\")} Initializing git repository...`);\n try {\n execSync(\"git init\", { cwd: targetDir, stdio: \"pipe\" });\n execSync(\"git add -A\", { cwd: targetDir, stdio: \"pipe\" });\n } catch {\n console.log(pc.yellow(\" Could not initialize git repository.\"));\n }\n }\n\n console.log();\n console.log(pc.green(\"Done! \") + pc.bold(`Created ${name}`));\n console.log();\n console.log(\"Next steps:\");\n console.log();\n console.log(pc.cyan(` cd ${name}`));\n console.log(pc.cyan(` # Edit src/strategies/${strategyName}.ts`));\n console.log(pc.cyan(\" # Configure wrangler.jsonc\"));\n console.log(pc.cyan(\" wrangler deploy\"));\n console.log();\n}\n\n// =============================================================================\n// Wallet Commands\n// =============================================================================\n\nasync function walletCreate(): Promise<void> {\n console.log();\n console.log(pc.cyan(\"Creating new Polymarket wallet...\"));\n console.log();\n\n // Generate wallet\n console.log(` ${pc.yellow(\"→\")} Generating Ethereum wallet...`);\n const wallet = generateWallet();\n console.log(` ${pc.green(\"✓\")} Address: ${pc.bold(wallet.address)}`);\n\n // Derive API credentials\n console.log(` ${pc.yellow(\"→\")} Deriving Polymarket API credentials...`);\n try {\n const apiCreds = await deriveApiCredentials(wallet.privateKey);\n console.log(` ${pc.green(\"✓\")} API credentials derived`);\n\n // Output credentials\n console.log();\n console.log(pc.cyan(\"═\".repeat(60)));\n console.log(pc.bold(\"SAVE THESE CREDENTIALS SECURELY\"));\n console.log(pc.cyan(\"═\".repeat(60)));\n console.log();\n console.log(`${pc.bold(\"Address:\")} ${wallet.address}`);\n console.log(`${pc.bold(\"Private Key:\")} ${wallet.privateKey}`);\n console.log(`${pc.bold(\"API Key:\")} ${apiCreds.apiKey}`);\n console.log(`${pc.bold(\"API Secret:\")} ${apiCreds.apiSecret}`);\n console.log(`${pc.bold(\"API Passphrase:\")} ${apiCreds.apiPassphrase}`);\n console.log();\n console.log(pc.cyan(\"═\".repeat(60)));\n console.log();\n console.log(pc.bold(\"Next steps:\"));\n console.log();\n console.log(\n ` 1. ${pc.yellow(\"Fund this wallet on Polygon network:\")}`\n );\n console.log(` - Send USDC to: ${wallet.address}`);\n console.log(` - Send ~1 POL for gas fees`);\n console.log();\n console.log(` 2. ${pc.yellow(\"Run on-chain setup:\")}`);\n console.log(\n ` npx create-polymarket-strategy wallet setup --private-key ${wallet.privateKey}`\n );\n console.log();\n console.log(` 3. ${pc.yellow(\"Add secrets to your worker:\")}`);\n console.log(` wrangler secret put EXECUTOR_API_KEY`);\n console.log();\n } catch (error) {\n console.log(` ${pc.red(\"✗\")} Failed to derive API credentials`);\n console.log(\n pc.yellow(\n \" This may be a network issue. You can derive credentials later.\"\n )\n );\n console.log();\n console.log(pc.cyan(\"═\".repeat(60)));\n console.log(pc.bold(\"WALLET CREATED (API credentials pending)\"));\n console.log(pc.cyan(\"═\".repeat(60)));\n console.log();\n console.log(`${pc.bold(\"Address:\")} ${wallet.address}`);\n console.log(`${pc.bold(\"Private Key:\")} ${wallet.privateKey}`);\n console.log();\n console.log(\n pc.yellow(\n \"Fund the wallet and re-run to derive API credentials.\"\n )\n );\n console.log();\n }\n}\n\nasync function walletBalance(address: string): Promise<void> {\n console.log();\n console.log(pc.cyan(`Checking balances for ${address}...`));\n console.log();\n\n try {\n const balances = await getBalances(address);\n\n console.log(pc.cyan(\"═\".repeat(50)));\n console.log(pc.bold(\"Polymarket Wallet Balance\"));\n console.log(pc.cyan(\"═\".repeat(50)));\n console.log();\n console.log(\n ` ${pc.bold(\"POL:\")} ${balances.pol.toFixed(4)} (~$${(balances.pol * 0.4).toFixed(2)})`\n );\n console.log(` ${pc.bold(\"USDC:\")} $${balances.usdcNative.toFixed(2)}`);\n console.log(\n ` ${pc.bold(\"USDC.e:\")} $${balances.usdcE.toFixed(2)} ${pc.dim(\"(Polymarket uses this)\")}`\n );\n console.log();\n console.log(` ${pc.bold(\"Total USDC:\")} $${balances.totalUsdc.toFixed(2)}`);\n console.log();\n console.log(pc.cyan(\"═\".repeat(50)));\n console.log(`View: https://polygonscan.com/address/${address}`);\n console.log();\n\n // Check approvals\n const approvals = await checkApprovals(address);\n if (approvals.allApproved) {\n console.log(pc.green(\"✓ All exchange contracts approved\"));\n } else {\n console.log(pc.yellow(\"⚠ Some contracts not approved:\"));\n for (const detail of approvals.details) {\n const status =\n detail.usdcApproved && detail.ctfApproved\n ? pc.green(\"✓\")\n : pc.red(\"✗\");\n console.log(` ${status} ${detail.contract}`);\n }\n console.log();\n console.log(\n pc.dim(\"Run 'npx create-polymarket-strategy wallet setup' to approve\")\n );\n }\n console.log();\n } catch (error) {\n console.error(pc.red(`Error: ${error}`));\n process.exit(1);\n }\n}\n\nasync function walletSetup(privateKey: string): Promise<void> {\n console.log();\n console.log(pc.cyan(\"Setting up wallet for Polymarket trading...\"));\n console.log();\n\n try {\n // Get wallet address from private key\n const { ethers } = await import(\"ethers\");\n const wallet = new ethers.Wallet(privateKey);\n const address = wallet.address;\n\n console.log(` ${pc.bold(\"Address:\")} ${address}`);\n console.log();\n\n // Check balances first\n console.log(pc.yellow(\"Checking balances...\"));\n const balances = await getBalances(address);\n\n console.log(` POL: ${balances.pol.toFixed(4)}`);\n console.log(` USDC: $${balances.usdcNative.toFixed(2)}`);\n console.log(` USDC.e: $${balances.usdcE.toFixed(2)}`);\n console.log();\n\n if (balances.pol < 0.01) {\n console.error(pc.red(\"Error: Need at least 0.01 POL for gas fees\"));\n console.log(`Send POL to: ${address}`);\n process.exit(1);\n }\n\n if (balances.usdcNative > 1 && balances.usdcE < 1) {\n console.log(\n pc.yellow(\n \"Note: You have native USDC but Polymarket requires USDC.e\"\n )\n );\n console.log(\n pc.yellow(\"Use a DEX like Uniswap to swap USDC → USDC.e first\")\n );\n console.log();\n }\n\n // Approve contracts\n console.log(pc.yellow(\"Approving Polymarket exchange contracts...\"));\n console.log(\n pc.dim(\"(3 contracts x 2 approvals each = up to 6 transactions)\")\n );\n console.log();\n\n const results = await approveExchangeContracts(privateKey, (msg) => {\n console.log(` ${pc.yellow(\"→\")} ${msg}`);\n });\n\n console.log();\n\n // Summary\n let txCount = 0;\n for (const result of results) {\n if (result.usdcTxHash) txCount++;\n if (result.ctfTxHash) txCount++;\n }\n\n console.log(pc.cyan(\"═\".repeat(50)));\n console.log(pc.bold(\"Setup Complete\"));\n console.log(pc.cyan(\"═\".repeat(50)));\n console.log();\n console.log(` ${pc.green(\"✓\")} All contracts approved`);\n console.log(` ${pc.dim(`${txCount} transaction(s) submitted`)}`);\n console.log();\n console.log(` USDC.e balance: $${balances.usdcE.toFixed(2)}`);\n console.log();\n console.log(pc.bold(\"Your wallet is ready for live trading!\"));\n console.log();\n } catch (error) {\n console.error(pc.red(`Error: ${error}`));\n process.exit(1);\n }\n}\n\n// =============================================================================\n// CLI Setup\n// =============================================================================\n\nprogram\n .name(\"create-polymarket-strategy\")\n .description(\"Create and manage Polymarket trading strategies\")\n .version(\"0.2.0\");\n\n// Default command: create a new strategy\nprogram\n .argument(\"[name]\", \"Project name\")\n .option(\"--no-git\", \"Skip git initialization\")\n .option(\"--no-install\", \"Skip dependency installation\")\n .action(async (name, options) => {\n if (name) {\n await createStrategy(name, options);\n } else {\n program.help();\n }\n });\n\n// Wallet subcommands\nconst walletCmd = program\n .command(\"wallet\")\n .description(\"Wallet management commands\");\n\nwalletCmd\n .command(\"create\")\n .description(\"Create a new wallet and derive API credentials\")\n .action(walletCreate);\n\nwalletCmd\n .command(\"balance\")\n .description(\"Check wallet balances\")\n .argument(\"<address>\", \"Wallet address\")\n .action(walletBalance);\n\nwalletCmd\n .command(\"setup\")\n .description(\"Approve exchange contracts for trading\")\n .requiredOption(\"--private-key <key>\", \"Wallet private key\")\n .action((options) => walletSetup(options.privateKey));\n\nprogram.parse();\n","import { ethers } from \"ethers\";\nimport {\n CHAIN_ID,\n RPC_URL,\n CLOB_API,\n USDC_NATIVE,\n USDC_E,\n CTF_ADDRESS,\n EXCHANGE_CONTRACTS,\n CLOB_AUTH_DOMAIN,\n CLOB_AUTH_MESSAGE,\n ERC20_ABI,\n ERC1155_ABI,\n} from \"./constants.js\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface WalletCredentials {\n address: string;\n privateKey: string;\n}\n\nexport interface ApiCredentials {\n apiKey: string;\n apiSecret: string;\n apiPassphrase: string;\n}\n\nexport interface FullCredentials extends WalletCredentials, ApiCredentials {}\n\nexport interface WalletBalances {\n address: string;\n pol: number;\n usdcNative: number;\n usdcE: number;\n totalUsdc: number;\n}\n\n// =============================================================================\n// Wallet Creation\n// =============================================================================\n\n/**\n * Generate a new Ethereum wallet.\n */\nexport function generateWallet(): WalletCredentials {\n const wallet = ethers.Wallet.createRandom();\n return {\n address: wallet.address,\n privateKey: wallet.privateKey,\n };\n}\n\n// =============================================================================\n// API Credential Derivation\n// =============================================================================\n\n/**\n * Sign the CLOB auth message (EIP-712).\n */\nasync function signClobAuthMessage(\n wallet: ethers.Wallet,\n timestamp: number,\n nonce: number\n): Promise<string> {\n const types = {\n ClobAuth: [\n { name: \"address\", type: \"address\" },\n { name: \"timestamp\", type: \"string\" },\n { name: \"nonce\", type: \"uint256\" },\n { name: \"message\", type: \"string\" },\n ],\n };\n\n const value = {\n address: wallet.address,\n timestamp: timestamp.toString(),\n nonce: nonce,\n message: CLOB_AUTH_MESSAGE,\n };\n\n return wallet.signTypedData(CLOB_AUTH_DOMAIN, types, value);\n}\n\n/**\n * Derive API credentials from wallet.\n * First tries to create new credentials, then falls back to deriving existing ones.\n */\nexport async function deriveApiCredentials(\n privateKey: string,\n nonce: number = 0\n): Promise<ApiCredentials> {\n const wallet = new ethers.Wallet(privateKey);\n const timestamp = Math.floor(Date.now() / 1000);\n const signature = await signClobAuthMessage(wallet, timestamp, nonce);\n\n const headers = {\n \"POLY_ADDRESS\": wallet.address,\n \"POLY_SIGNATURE\": signature,\n \"POLY_TIMESTAMP\": timestamp.toString(),\n \"POLY_NONCE\": nonce.toString(),\n };\n\n // Try to derive existing credentials first\n let response = await fetch(`${CLOB_API}/auth/derive-api-key`, {\n method: \"GET\",\n headers,\n });\n\n if (!response.ok) {\n // Try to create new credentials\n response = await fetch(`${CLOB_API}/auth/api-key`, {\n method: \"POST\",\n headers,\n });\n }\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`Failed to derive API credentials: ${response.status} ${text}`);\n }\n\n const data = await response.json();\n\n return {\n apiKey: data.apiKey,\n apiSecret: data.secret,\n apiPassphrase: data.passphrase,\n };\n}\n\n/**\n * Generate wallet and derive API credentials.\n */\nexport async function createWalletWithCredentials(): Promise<FullCredentials> {\n const wallet = generateWallet();\n const apiCreds = await deriveApiCredentials(wallet.privateKey);\n\n return {\n ...wallet,\n ...apiCreds,\n };\n}\n\n// =============================================================================\n// Balance Checking\n// =============================================================================\n\n/**\n * Get provider for Polygon.\n */\nfunction getProvider(): ethers.JsonRpcProvider {\n return new ethers.JsonRpcProvider(RPC_URL, CHAIN_ID);\n}\n\n/**\n * Check wallet balances (POL, USDC, USDC.e).\n */\nexport async function getBalances(address: string): Promise<WalletBalances> {\n const provider = getProvider();\n\n // POL balance\n const polBalance = await provider.getBalance(address);\n const pol = Number(ethers.formatEther(polBalance));\n\n // USDC Native balance\n const usdcNativeContract = new ethers.Contract(USDC_NATIVE, ERC20_ABI, provider);\n const usdcNativeBalance = await usdcNativeContract.balanceOf(address);\n const usdcNative = Number(ethers.formatUnits(usdcNativeBalance, 6));\n\n // USDC.e balance\n const usdcEContract = new ethers.Contract(USDC_E, ERC20_ABI, provider);\n const usdcEBalance = await usdcEContract.balanceOf(address);\n const usdcE = Number(ethers.formatUnits(usdcEBalance, 6));\n\n return {\n address,\n pol,\n usdcNative,\n usdcE,\n totalUsdc: usdcNative + usdcE,\n };\n}\n\n// =============================================================================\n// Contract Approvals\n// =============================================================================\n\ninterface ApprovalResult {\n contract: string;\n usdcApproved: boolean;\n usdcTxHash?: string;\n ctfApproved: boolean;\n ctfTxHash?: string;\n}\n\n/**\n * Approve Polymarket exchange contracts for trading.\n */\nexport async function approveExchangeContracts(\n privateKey: string,\n onProgress?: (message: string) => void\n): Promise<ApprovalResult[]> {\n const provider = getProvider();\n const wallet = new ethers.Wallet(privateKey, provider);\n const results: ApprovalResult[] = [];\n\n const usdcE = new ethers.Contract(USDC_E, ERC20_ABI, wallet);\n const ctf = new ethers.Contract(CTF_ADDRESS, ERC1155_ABI, wallet);\n\n const maxApproval = ethers.MaxUint256;\n\n for (const exchange of EXCHANGE_CONTRACTS) {\n const result: ApprovalResult = {\n contract: exchange.name,\n usdcApproved: false,\n ctfApproved: false,\n };\n\n // Check and approve USDC.e\n const currentAllowance = await usdcE.allowance(wallet.address, exchange.address);\n if (currentAllowance < ethers.parseUnits(\"1000000000\", 6)) {\n onProgress?.(`Approving USDC.e for ${exchange.name}...`);\n const tx = await usdcE.approve(exchange.address, maxApproval);\n const receipt = await tx.wait();\n result.usdcTxHash = receipt.hash;\n result.usdcApproved = true;\n } else {\n onProgress?.(`USDC.e already approved for ${exchange.name}`);\n result.usdcApproved = true;\n }\n\n // Check and approve CTF\n const isApproved = await ctf.isApprovedForAll(wallet.address, exchange.address);\n if (!isApproved) {\n onProgress?.(`Approving CTF for ${exchange.name}...`);\n const tx = await ctf.setApprovalForAll(exchange.address, true);\n const receipt = await tx.wait();\n result.ctfTxHash = receipt.hash;\n result.ctfApproved = true;\n } else {\n onProgress?.(`CTF already approved for ${exchange.name}`);\n result.ctfApproved = true;\n }\n\n results.push(result);\n }\n\n return results;\n}\n\n/**\n * Check if wallet has sufficient approvals for trading.\n */\nexport async function checkApprovals(address: string): Promise<{\n allApproved: boolean;\n details: { contract: string; usdcApproved: boolean; ctfApproved: boolean }[];\n}> {\n const provider = getProvider();\n const usdcE = new ethers.Contract(USDC_E, ERC20_ABI, provider);\n const ctf = new ethers.Contract(CTF_ADDRESS, ERC1155_ABI, provider);\n\n const details = [];\n\n for (const exchange of EXCHANGE_CONTRACTS) {\n const allowance = await usdcE.allowance(address, exchange.address);\n const isCtfApproved = await ctf.isApprovedForAll(address, exchange.address);\n\n details.push({\n contract: exchange.name,\n usdcApproved: allowance > 0n,\n ctfApproved: isCtfApproved,\n });\n }\n\n const allApproved = details.every((d) => d.usdcApproved && d.ctfApproved);\n\n return { allApproved, details };\n}\n","// Polygon Mainnet\nexport const CHAIN_ID = 137;\nexport const RPC_URL = \"https://1rpc.io/matic\";\n\n// Polymarket CLOB API\nexport const CLOB_API = \"https://clob.polymarket.com\";\n\n// Token addresses on Polygon\nexport const USDC_NATIVE = \"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359\";\nexport const USDC_E = \"0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174\"; // Polymarket uses this\nexport const CTF_ADDRESS = \"0x4D97DCd97eC945f40cF65F87097ACe5EA0476045\";\n\n// Polymarket exchange contracts that need approval\nexport const EXCHANGE_CONTRACTS = [\n { address: \"0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E\", name: \"CTF Exchange\" },\n { address: \"0xC5d563A36AE78145C45a50134d48A1215220f80a\", name: \"Neg Risk CTF Exchange\" },\n { address: \"0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296\", name: \"Neg Risk Adapter\" },\n];\n\n// Uniswap V3 Router on Polygon (for USDC → USDC.e swap)\nexport const UNISWAP_ROUTER = \"0xE592427A0AEce92De3Edee1F18E0157C05861564\";\n\n// EIP-712 domain for CLOB auth\nexport const CLOB_AUTH_DOMAIN = {\n name: \"ClobAuthDomain\",\n version: \"1\",\n chainId: CHAIN_ID,\n};\n\n// Message to sign for CLOB auth\nexport const CLOB_AUTH_MESSAGE = \"This message attests that I control the given wallet\";\n\n// ABIs\nexport const ERC20_ABI = [\n \"function balanceOf(address owner) view returns (uint256)\",\n \"function approve(address spender, uint256 amount) returns (bool)\",\n \"function allowance(address owner, address spender) view returns (uint256)\",\n];\n\nexport const ERC1155_ABI = [\n \"function setApprovalForAll(address operator, bool approved)\",\n \"function isApprovedForAll(address account, address operator) view returns (bool)\",\n];\n\nexport const UNISWAP_ROUTER_ABI = [\n \"function exactInputSingle((address tokenIn, address tokenOut, uint24 fee, address recipient, uint256 deadline, uint256 amountIn, uint256 amountOutMinimum, uint160 sqrtPriceLimitX96)) external payable returns (uint256 amountOut)\",\n];\n"],"mappings":"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","names":["ethers"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-polymarket-strategy",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Create a new Polymarket trading strategy project",
5
5
  "type": "module",
6
6
  "bin": {
@@ -18,6 +18,7 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "commander": "^12.0.0",
21
+ "ethers": "^6.11.0",
21
22
  "fs-extra": "^11.2.0",
22
23
  "picocolors": "^1.1.0"
23
24
  },