create-polymarket-strategy 0.2.1 → 0.2.3
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 +403 -112
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { program } from "commander";
|
|
|
5
5
|
import fs from "fs-extra";
|
|
6
6
|
import path from "path";
|
|
7
7
|
import { execSync as execSync2 } from "child_process";
|
|
8
|
-
import
|
|
8
|
+
import pc2 from "picocolors";
|
|
9
9
|
import { fileURLToPath } from "url";
|
|
10
10
|
|
|
11
11
|
// src/wallet/index.ts
|
|
@@ -13,7 +13,7 @@ import { ethers } from "ethers";
|
|
|
13
13
|
|
|
14
14
|
// src/wallet/constants.ts
|
|
15
15
|
var CHAIN_ID = 137;
|
|
16
|
-
var RPC_URL = "https://
|
|
16
|
+
var RPC_URL = "https://polygon.drpc.org";
|
|
17
17
|
var CLOB_API = "https://clob.polymarket.com";
|
|
18
18
|
var USDC_NATIVE = "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359";
|
|
19
19
|
var USDC_E = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174";
|
|
@@ -23,6 +23,7 @@ var EXCHANGE_CONTRACTS = [
|
|
|
23
23
|
{ address: "0xC5d563A36AE78145C45a50134d48A1215220f80a", name: "Neg Risk CTF Exchange" },
|
|
24
24
|
{ address: "0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296", name: "Neg Risk Adapter" }
|
|
25
25
|
];
|
|
26
|
+
var UNISWAP_ROUTER = "0xE592427A0AEce92De3Edee1F18E0157C05861564";
|
|
26
27
|
var CLOB_AUTH_DOMAIN = {
|
|
27
28
|
name: "ClobAuthDomain",
|
|
28
29
|
version: "1",
|
|
@@ -38,6 +39,9 @@ var ERC1155_ABI = [
|
|
|
38
39
|
"function setApprovalForAll(address operator, bool approved)",
|
|
39
40
|
"function isApprovedForAll(address account, address operator) view returns (bool)"
|
|
40
41
|
];
|
|
42
|
+
var UNISWAP_ROUTER_ABI = [
|
|
43
|
+
"function exactInputSingle((address tokenIn, address tokenOut, uint24 fee, address recipient, uint256 deadline, uint256 amountIn, uint256 amountOutMinimum, uint160 sqrtPriceLimitX96)) external payable returns (uint256 amountOut)"
|
|
44
|
+
];
|
|
41
45
|
|
|
42
46
|
// src/wallet/index.ts
|
|
43
47
|
function generateWallet() {
|
|
@@ -116,6 +120,42 @@ async function getBalances(address) {
|
|
|
116
120
|
totalUsdc: usdcNative + usdcE
|
|
117
121
|
};
|
|
118
122
|
}
|
|
123
|
+
async function swapUsdcToUsdcE(privateKey, amount, onProgress) {
|
|
124
|
+
const provider = getProvider();
|
|
125
|
+
const wallet = new ethers.Wallet(privateKey, provider);
|
|
126
|
+
const amountIn = ethers.parseUnits(amount.toFixed(6), 6);
|
|
127
|
+
onProgress?.("Approving Uniswap to spend USDC...");
|
|
128
|
+
const usdcNative = new ethers.Contract(USDC_NATIVE, ERC20_ABI, wallet);
|
|
129
|
+
const currentAllowance = await usdcNative.allowance(wallet.address, UNISWAP_ROUTER);
|
|
130
|
+
if (currentAllowance < amountIn) {
|
|
131
|
+
const approveTx = await usdcNative.approve(UNISWAP_ROUTER, amountIn);
|
|
132
|
+
await approveTx.wait();
|
|
133
|
+
}
|
|
134
|
+
onProgress?.(`Swapping ${amount.toFixed(2)} USDC \u2192 USDC.e...`);
|
|
135
|
+
const router = new ethers.Contract(UNISWAP_ROUTER, UNISWAP_ROUTER_ABI, wallet);
|
|
136
|
+
const minOut = amountIn * 99n / 100n;
|
|
137
|
+
const deadline = Math.floor(Date.now() / 1e3) + 300;
|
|
138
|
+
const swapParams = {
|
|
139
|
+
tokenIn: USDC_NATIVE,
|
|
140
|
+
tokenOut: USDC_E,
|
|
141
|
+
fee: 500,
|
|
142
|
+
// 0.05% fee tier - standard for stablecoin pairs
|
|
143
|
+
recipient: wallet.address,
|
|
144
|
+
deadline,
|
|
145
|
+
amountIn,
|
|
146
|
+
amountOutMinimum: minOut,
|
|
147
|
+
sqrtPriceLimitX96: 0
|
|
148
|
+
// No price limit
|
|
149
|
+
};
|
|
150
|
+
const swapTx = await router.exactInputSingle(swapParams);
|
|
151
|
+
const receipt = await swapTx.wait();
|
|
152
|
+
const amountOutEstimate = Number(ethers.formatUnits(minOut, 6));
|
|
153
|
+
return {
|
|
154
|
+
amountIn: amount,
|
|
155
|
+
amountOut: amountOutEstimate,
|
|
156
|
+
txHash: receipt.hash
|
|
157
|
+
};
|
|
158
|
+
}
|
|
119
159
|
async function approveExchangeContracts(privateKey, onProgress) {
|
|
120
160
|
const provider = getProvider();
|
|
121
161
|
const wallet = new ethers.Wallet(privateKey, provider);
|
|
@@ -291,6 +331,239 @@ function getWalletAddress(name) {
|
|
|
291
331
|
}
|
|
292
332
|
}
|
|
293
333
|
|
|
334
|
+
// src/executor/index.ts
|
|
335
|
+
import pc from "picocolors";
|
|
336
|
+
|
|
337
|
+
// src/executor/aws.ts
|
|
338
|
+
import {
|
|
339
|
+
SecretsManagerClient,
|
|
340
|
+
CreateSecretCommand,
|
|
341
|
+
GetSecretValueCommand,
|
|
342
|
+
PutSecretValueCommand,
|
|
343
|
+
DescribeSecretCommand
|
|
344
|
+
} from "@aws-sdk/client-secrets-manager";
|
|
345
|
+
import crypto from "crypto";
|
|
346
|
+
var REGION = "ap-northeast-2";
|
|
347
|
+
function getSecretsClient() {
|
|
348
|
+
return new SecretsManagerClient({ region: REGION });
|
|
349
|
+
}
|
|
350
|
+
async function isWalletRegistered(walletId) {
|
|
351
|
+
const client = getSecretsClient();
|
|
352
|
+
const secretName = `polymarket/wallets/${walletId}`;
|
|
353
|
+
try {
|
|
354
|
+
await client.send(new DescribeSecretCommand({ SecretId: secretName }));
|
|
355
|
+
return true;
|
|
356
|
+
} catch (error) {
|
|
357
|
+
if (error.name === "ResourceNotFoundException") {
|
|
358
|
+
return false;
|
|
359
|
+
}
|
|
360
|
+
throw error;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
async function registerWallet(walletId, credentials) {
|
|
364
|
+
const client = getSecretsClient();
|
|
365
|
+
const secretName = `polymarket/wallets/${walletId}`;
|
|
366
|
+
const secretValue = JSON.stringify({
|
|
367
|
+
private_key: credentials.privateKey,
|
|
368
|
+
api_key: credentials.apiKey,
|
|
369
|
+
api_secret: credentials.apiSecret,
|
|
370
|
+
api_passphrase: credentials.apiPassphrase
|
|
371
|
+
});
|
|
372
|
+
try {
|
|
373
|
+
await client.send(
|
|
374
|
+
new CreateSecretCommand({
|
|
375
|
+
Name: secretName,
|
|
376
|
+
SecretString: secretValue,
|
|
377
|
+
Description: `Polymarket wallet credentials for ${walletId}`
|
|
378
|
+
})
|
|
379
|
+
);
|
|
380
|
+
return { created: true, secretName };
|
|
381
|
+
} catch (error) {
|
|
382
|
+
if (error.name === "ResourceExistsException") {
|
|
383
|
+
await client.send(
|
|
384
|
+
new PutSecretValueCommand({
|
|
385
|
+
SecretId: secretName,
|
|
386
|
+
SecretString: secretValue
|
|
387
|
+
})
|
|
388
|
+
);
|
|
389
|
+
return { created: false, secretName };
|
|
390
|
+
}
|
|
391
|
+
throw error;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
async function generateApiKey(strategy, wallets, rateLimit = 100) {
|
|
395
|
+
const client = getSecretsClient();
|
|
396
|
+
const secretName = "executor/api-keys";
|
|
397
|
+
const suffix = crypto.randomBytes(6).toString("hex");
|
|
398
|
+
const apiKey = `exk_${strategy}_${suffix}`;
|
|
399
|
+
const info = {
|
|
400
|
+
strategy,
|
|
401
|
+
allowed_wallets: wallets,
|
|
402
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
403
|
+
rate_limit: rateLimit
|
|
404
|
+
};
|
|
405
|
+
let existingKeys = {};
|
|
406
|
+
try {
|
|
407
|
+
const response = await client.send(
|
|
408
|
+
new GetSecretValueCommand({ SecretId: secretName })
|
|
409
|
+
);
|
|
410
|
+
existingKeys = JSON.parse(response.SecretString || "{}");
|
|
411
|
+
} catch (error) {
|
|
412
|
+
if (error.name !== "ResourceNotFoundException") {
|
|
413
|
+
throw error;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
existingKeys[apiKey] = info;
|
|
417
|
+
try {
|
|
418
|
+
await client.send(
|
|
419
|
+
new CreateSecretCommand({
|
|
420
|
+
Name: secretName,
|
|
421
|
+
SecretString: JSON.stringify(existingKeys),
|
|
422
|
+
Description: "API keys for Polymarket order executor"
|
|
423
|
+
})
|
|
424
|
+
);
|
|
425
|
+
} catch (error) {
|
|
426
|
+
if (error.name === "ResourceExistsException") {
|
|
427
|
+
await client.send(
|
|
428
|
+
new PutSecretValueCommand({
|
|
429
|
+
SecretId: secretName,
|
|
430
|
+
SecretString: JSON.stringify(existingKeys)
|
|
431
|
+
})
|
|
432
|
+
);
|
|
433
|
+
} else {
|
|
434
|
+
throw error;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
return { apiKey, info };
|
|
438
|
+
}
|
|
439
|
+
function getExecutorUrl() {
|
|
440
|
+
return "https://omnsgrhcc4.execute-api.ap-northeast-2.amazonaws.com/v1";
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// src/executor/index.ts
|
|
444
|
+
async function executorRegister(options) {
|
|
445
|
+
console.log();
|
|
446
|
+
console.log(pc.cyan("Registering wallet with Seoul executor..."));
|
|
447
|
+
console.log();
|
|
448
|
+
if (options.awsProfile) {
|
|
449
|
+
process.env.AWS_PROFILE = options.awsProfile;
|
|
450
|
+
console.log(` ${pc.dim(`Using AWS profile: ${options.awsProfile}`)}`);
|
|
451
|
+
}
|
|
452
|
+
if (!options.from1password) {
|
|
453
|
+
console.error(pc.red("Error: --from-1password is required"));
|
|
454
|
+
process.exit(1);
|
|
455
|
+
}
|
|
456
|
+
const opStatus = check1PasswordCli();
|
|
457
|
+
if (!opStatus.available || !opStatus.authenticated) {
|
|
458
|
+
console.error(pc.red(`Error: ${opStatus.error}`));
|
|
459
|
+
process.exit(1);
|
|
460
|
+
}
|
|
461
|
+
console.log(` ${pc.yellow("\u2192")} Reading credentials from 1Password...`);
|
|
462
|
+
const result = await getFrom1Password(options.from1password);
|
|
463
|
+
if (result.error || !result.credentials) {
|
|
464
|
+
console.error(pc.red(`Error: ${result.error}`));
|
|
465
|
+
process.exit(1);
|
|
466
|
+
}
|
|
467
|
+
const creds = result.credentials;
|
|
468
|
+
if (!creds.apiKey || !creds.apiSecret || !creds.apiPassphrase) {
|
|
469
|
+
console.error(
|
|
470
|
+
pc.red("Error: Wallet is missing API credentials (apiKey, apiSecret, apiPassphrase)")
|
|
471
|
+
);
|
|
472
|
+
console.log(
|
|
473
|
+
pc.yellow(" Run 'wallet setup' first to derive API credentials")
|
|
474
|
+
);
|
|
475
|
+
process.exit(1);
|
|
476
|
+
}
|
|
477
|
+
const walletId = options.walletId || `${options.from1password}-live`;
|
|
478
|
+
console.log(` ${pc.yellow("\u2192")} Wallet ID: ${pc.bold(walletId)}`);
|
|
479
|
+
const alreadyRegistered = await isWalletRegistered(walletId);
|
|
480
|
+
if (alreadyRegistered) {
|
|
481
|
+
console.log(` ${pc.yellow("!")} Wallet already registered, updating...`);
|
|
482
|
+
}
|
|
483
|
+
console.log(` ${pc.yellow("\u2192")} Storing in AWS Secrets Manager...`);
|
|
484
|
+
try {
|
|
485
|
+
const registerResult = await registerWallet(walletId, {
|
|
486
|
+
privateKey: creds.privateKey,
|
|
487
|
+
apiKey: creds.apiKey,
|
|
488
|
+
apiSecret: creds.apiSecret,
|
|
489
|
+
apiPassphrase: creds.apiPassphrase
|
|
490
|
+
});
|
|
491
|
+
console.log(
|
|
492
|
+
` ${pc.green("\u2713")} ${registerResult.created ? "Created" : "Updated"}: ${registerResult.secretName}`
|
|
493
|
+
);
|
|
494
|
+
} catch (error) {
|
|
495
|
+
console.error(pc.red(`Error: ${error.message}`));
|
|
496
|
+
if (error.name === "CredentialsProviderError") {
|
|
497
|
+
console.log(pc.yellow(" Make sure AWS credentials are configured:"));
|
|
498
|
+
console.log(pc.yellow(" export AWS_PROFILE=polymarket"));
|
|
499
|
+
console.log(pc.yellow(" Or run: aws configure"));
|
|
500
|
+
}
|
|
501
|
+
process.exit(1);
|
|
502
|
+
}
|
|
503
|
+
console.log();
|
|
504
|
+
console.log(pc.cyan("\u2550".repeat(60)));
|
|
505
|
+
console.log(pc.bold("Wallet Registered with Executor"));
|
|
506
|
+
console.log(pc.cyan("\u2550".repeat(60)));
|
|
507
|
+
console.log();
|
|
508
|
+
console.log(` ${pc.bold("Wallet ID:")} ${walletId}`);
|
|
509
|
+
console.log(` ${pc.bold("Region:")} ap-northeast-2 (Seoul)`);
|
|
510
|
+
console.log(` ${pc.bold("Executor:")} ${getExecutorUrl()}`);
|
|
511
|
+
console.log();
|
|
512
|
+
console.log(pc.bold("Next step:"));
|
|
513
|
+
console.log();
|
|
514
|
+
console.log(
|
|
515
|
+
` ${pc.cyan(`npx create-polymarket-strategy executor generate-key --strategy ${options.from1password} --wallets ${walletId}`)}`
|
|
516
|
+
);
|
|
517
|
+
console.log();
|
|
518
|
+
}
|
|
519
|
+
async function executorGenerateKey(options) {
|
|
520
|
+
console.log();
|
|
521
|
+
console.log(pc.cyan("Generating executor API key..."));
|
|
522
|
+
console.log();
|
|
523
|
+
if (options.awsProfile) {
|
|
524
|
+
process.env.AWS_PROFILE = options.awsProfile;
|
|
525
|
+
console.log(` ${pc.dim(`Using AWS profile: ${options.awsProfile}`)}`);
|
|
526
|
+
}
|
|
527
|
+
const wallets = options.wallets.split(",").map((w) => w.trim());
|
|
528
|
+
const rateLimit = parseInt(options.rateLimit || "100", 10);
|
|
529
|
+
console.log(` ${pc.bold("Strategy:")} ${options.strategy}`);
|
|
530
|
+
console.log(` ${pc.bold("Wallets:")} ${wallets.join(", ")}`);
|
|
531
|
+
console.log(` ${pc.bold("Rate limit:")} ${rateLimit} req/min`);
|
|
532
|
+
console.log();
|
|
533
|
+
console.log(` ${pc.yellow("\u2192")} Generating API key...`);
|
|
534
|
+
try {
|
|
535
|
+
const result = await generateApiKey(options.strategy, wallets, rateLimit);
|
|
536
|
+
console.log(` ${pc.green("\u2713")} API key generated`);
|
|
537
|
+
console.log();
|
|
538
|
+
console.log(pc.cyan("\u2550".repeat(60)));
|
|
539
|
+
console.log(pc.bold("Executor API Key Generated"));
|
|
540
|
+
console.log(pc.cyan("\u2550".repeat(60)));
|
|
541
|
+
console.log();
|
|
542
|
+
console.log(` ${pc.bold("API Key:")} ${pc.green(result.apiKey)}`);
|
|
543
|
+
console.log(` ${pc.bold("Strategy:")} ${result.info.strategy}`);
|
|
544
|
+
console.log(` ${pc.bold("Wallets:")} ${result.info.allowed_wallets.join(", ")}`);
|
|
545
|
+
console.log();
|
|
546
|
+
console.log(pc.yellow("IMPORTANT: Save this key - it cannot be retrieved later!"));
|
|
547
|
+
console.log();
|
|
548
|
+
console.log(pc.bold("Configure your Worker:"));
|
|
549
|
+
console.log();
|
|
550
|
+
console.log(` ${pc.cyan("# Set as Cloudflare secret")}`);
|
|
551
|
+
console.log(` ${pc.cyan(`echo "${result.apiKey}" | wrangler secret put EXECUTOR_API_KEY`)}`);
|
|
552
|
+
console.log();
|
|
553
|
+
console.log(` ${pc.cyan("# Or in wrangler.jsonc vars (less secure)")}`);
|
|
554
|
+
console.log(` ${pc.dim(`"EXECUTOR_URL": "${getExecutorUrl()}"`)}`);
|
|
555
|
+
console.log(` ${pc.dim(`"EXECUTOR_WALLET_ID": "${wallets[0]}"`)}`);
|
|
556
|
+
console.log();
|
|
557
|
+
} catch (error) {
|
|
558
|
+
console.error(pc.red(`Error: ${error.message}`));
|
|
559
|
+
if (error.name === "CredentialsProviderError") {
|
|
560
|
+
console.log(pc.yellow(" Make sure AWS credentials are configured:"));
|
|
561
|
+
console.log(pc.yellow(" export AWS_PROFILE=polymarket"));
|
|
562
|
+
}
|
|
563
|
+
process.exit(1);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
294
567
|
// src/index.ts
|
|
295
568
|
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
296
569
|
var TEMPLATE_DIR = path.resolve(__dirname, "..", "templates", "worker");
|
|
@@ -353,20 +626,20 @@ async function createStrategy(name, options) {
|
|
|
353
626
|
const strategyClassName = toPascalCase(name);
|
|
354
627
|
const strategyVarName = toCamelCase(name);
|
|
355
628
|
if (await fs.pathExists(targetDir)) {
|
|
356
|
-
console.error(
|
|
629
|
+
console.error(pc2.red(`Error: Directory "${name}" already exists.`));
|
|
357
630
|
process.exit(1);
|
|
358
631
|
}
|
|
359
632
|
if (!await fs.pathExists(TEMPLATE_DIR)) {
|
|
360
|
-
console.error(
|
|
361
|
-
console.error(
|
|
633
|
+
console.error(pc2.red(`Error: Template not found at ${TEMPLATE_DIR}`));
|
|
634
|
+
console.error(pc2.yellow("This may be a development installation issue."));
|
|
362
635
|
process.exit(1);
|
|
363
636
|
}
|
|
364
637
|
console.log();
|
|
365
|
-
console.log(
|
|
638
|
+
console.log(pc2.cyan(`Creating Polymarket strategy: ${pc2.bold(name)}`));
|
|
366
639
|
console.log();
|
|
367
|
-
console.log(` ${
|
|
640
|
+
console.log(` ${pc2.green("\u2713")} Copying template...`);
|
|
368
641
|
await fs.copy(TEMPLATE_DIR, targetDir);
|
|
369
|
-
console.log(` ${
|
|
642
|
+
console.log(` ${pc2.green("\u2713")} Configuring project...`);
|
|
370
643
|
const replacements = {
|
|
371
644
|
"{{name}}": name,
|
|
372
645
|
"{{strategy-name}}": strategyName,
|
|
@@ -378,7 +651,7 @@ async function createStrategy(name, options) {
|
|
|
378
651
|
"{{strategy-name}}": strategyName
|
|
379
652
|
});
|
|
380
653
|
if (options.install) {
|
|
381
|
-
console.log(` ${
|
|
654
|
+
console.log(` ${pc2.green("\u2713")} Installing dependencies...`);
|
|
382
655
|
try {
|
|
383
656
|
execSync2("pnpm install", { cwd: targetDir, stdio: "pipe" });
|
|
384
657
|
} catch {
|
|
@@ -386,97 +659,97 @@ async function createStrategy(name, options) {
|
|
|
386
659
|
execSync2("npm install", { cwd: targetDir, stdio: "pipe" });
|
|
387
660
|
} catch {
|
|
388
661
|
console.log(
|
|
389
|
-
|
|
662
|
+
pc2.yellow(" Could not install dependencies automatically.")
|
|
390
663
|
);
|
|
391
664
|
console.log(
|
|
392
|
-
|
|
665
|
+
pc2.yellow(" Run 'npm install' or 'pnpm install' manually.")
|
|
393
666
|
);
|
|
394
667
|
}
|
|
395
668
|
}
|
|
396
669
|
}
|
|
397
670
|
if (options.git) {
|
|
398
|
-
console.log(` ${
|
|
671
|
+
console.log(` ${pc2.green("\u2713")} Initializing git repository...`);
|
|
399
672
|
try {
|
|
400
673
|
execSync2("git init", { cwd: targetDir, stdio: "pipe" });
|
|
401
674
|
execSync2("git add -A", { cwd: targetDir, stdio: "pipe" });
|
|
402
675
|
} catch {
|
|
403
|
-
console.log(
|
|
676
|
+
console.log(pc2.yellow(" Could not initialize git repository."));
|
|
404
677
|
}
|
|
405
678
|
}
|
|
406
679
|
console.log();
|
|
407
|
-
console.log(
|
|
680
|
+
console.log(pc2.green("Done! ") + pc2.bold(`Created ${name}`));
|
|
408
681
|
console.log();
|
|
409
682
|
console.log("Next steps:");
|
|
410
683
|
console.log();
|
|
411
|
-
console.log(
|
|
412
|
-
console.log(
|
|
413
|
-
console.log(
|
|
414
|
-
console.log(
|
|
684
|
+
console.log(pc2.cyan(` cd ${name}`));
|
|
685
|
+
console.log(pc2.cyan(` # Edit src/strategies/${strategyName}.ts`));
|
|
686
|
+
console.log(pc2.cyan(" # Configure wrangler.jsonc"));
|
|
687
|
+
console.log(pc2.cyan(" wrangler deploy"));
|
|
415
688
|
console.log();
|
|
416
689
|
}
|
|
417
690
|
async function walletCreate(options) {
|
|
418
691
|
console.log();
|
|
419
|
-
console.log(
|
|
692
|
+
console.log(pc2.cyan("Creating new Polymarket wallet..."));
|
|
420
693
|
console.log();
|
|
421
694
|
if (options.store1password) {
|
|
422
695
|
const opStatus = check1PasswordCli();
|
|
423
696
|
if (!opStatus.available || !opStatus.authenticated) {
|
|
424
|
-
console.error(
|
|
697
|
+
console.error(pc2.red(`Error: ${opStatus.error}`));
|
|
425
698
|
process.exit(1);
|
|
426
699
|
}
|
|
427
|
-
console.log(` ${
|
|
700
|
+
console.log(` ${pc2.green("\u2713")} 1Password CLI authenticated`);
|
|
428
701
|
}
|
|
429
|
-
console.log(` ${
|
|
702
|
+
console.log(` ${pc2.yellow("\u2192")} Generating Ethereum wallet...`);
|
|
430
703
|
const wallet = generateWallet();
|
|
431
|
-
console.log(` ${
|
|
432
|
-
console.log(` ${
|
|
704
|
+
console.log(` ${pc2.green("\u2713")} Address: ${pc2.bold(wallet.address)}`);
|
|
705
|
+
console.log(` ${pc2.yellow("\u2192")} Deriving Polymarket API credentials...`);
|
|
433
706
|
try {
|
|
434
707
|
const apiCreds = await deriveApiCredentials(wallet.privateKey);
|
|
435
|
-
console.log(` ${
|
|
708
|
+
console.log(` ${pc2.green("\u2713")} API credentials derived`);
|
|
436
709
|
const fullCreds = { ...wallet, ...apiCreds };
|
|
437
710
|
if (options.store1password && options.name) {
|
|
438
|
-
console.log(` ${
|
|
711
|
+
console.log(` ${pc2.yellow("\u2192")} Storing in 1Password...`);
|
|
439
712
|
const result = await storeIn1Password(
|
|
440
713
|
options.name,
|
|
441
714
|
fullCreds,
|
|
442
715
|
options.vault || "Private"
|
|
443
716
|
);
|
|
444
717
|
if (result.success) {
|
|
445
|
-
console.log(` ${
|
|
718
|
+
console.log(` ${pc2.green("\u2713")} Stored as "${result.itemName}"`);
|
|
446
719
|
} else {
|
|
447
|
-
console.error(
|
|
720
|
+
console.error(pc2.red(` \u2717 Failed to store: ${result.error}`));
|
|
448
721
|
}
|
|
449
722
|
}
|
|
450
723
|
console.log();
|
|
451
|
-
console.log(
|
|
724
|
+
console.log(pc2.cyan("\u2550".repeat(60)));
|
|
452
725
|
if (options.store1password && options.name) {
|
|
453
|
-
console.log(
|
|
726
|
+
console.log(pc2.bold("WALLET CREATED & STORED IN 1PASSWORD"));
|
|
454
727
|
} else {
|
|
455
|
-
console.log(
|
|
728
|
+
console.log(pc2.bold("SAVE THESE CREDENTIALS SECURELY"));
|
|
456
729
|
}
|
|
457
|
-
console.log(
|
|
730
|
+
console.log(pc2.cyan("\u2550".repeat(60)));
|
|
458
731
|
console.log();
|
|
459
|
-
console.log(`${
|
|
732
|
+
console.log(`${pc2.bold("Address:")} ${wallet.address}`);
|
|
460
733
|
if (!options.store1password) {
|
|
461
|
-
console.log(`${
|
|
462
|
-
console.log(`${
|
|
463
|
-
console.log(`${
|
|
464
|
-
console.log(`${
|
|
734
|
+
console.log(`${pc2.bold("Private Key:")} ${wallet.privateKey}`);
|
|
735
|
+
console.log(`${pc2.bold("API Key:")} ${apiCreds.apiKey}`);
|
|
736
|
+
console.log(`${pc2.bold("API Secret:")} ${apiCreds.apiSecret}`);
|
|
737
|
+
console.log(`${pc2.bold("API Passphrase:")} ${apiCreds.apiPassphrase}`);
|
|
465
738
|
} else {
|
|
466
|
-
console.log(
|
|
739
|
+
console.log(pc2.dim(" (credentials stored securely in 1Password)"));
|
|
467
740
|
}
|
|
468
741
|
console.log();
|
|
469
|
-
console.log(
|
|
742
|
+
console.log(pc2.cyan("\u2550".repeat(60)));
|
|
470
743
|
console.log();
|
|
471
|
-
console.log(
|
|
744
|
+
console.log(pc2.bold("Next steps:"));
|
|
472
745
|
console.log();
|
|
473
746
|
console.log(
|
|
474
|
-
` 1. ${
|
|
747
|
+
` 1. ${pc2.yellow("Fund this wallet on Polygon network:")}`
|
|
475
748
|
);
|
|
476
749
|
console.log(` - Send USDC to: ${wallet.address}`);
|
|
477
750
|
console.log(` - Send ~1 POL for gas fees`);
|
|
478
751
|
console.log();
|
|
479
|
-
console.log(` 2. ${
|
|
752
|
+
console.log(` 2. ${pc2.yellow("Run on-chain setup:")}`);
|
|
480
753
|
if (options.store1password && options.name) {
|
|
481
754
|
console.log(
|
|
482
755
|
` npx create-polymarket-strategy wallet setup --from-1password ${options.name}`
|
|
@@ -487,31 +760,31 @@ async function walletCreate(options) {
|
|
|
487
760
|
);
|
|
488
761
|
}
|
|
489
762
|
console.log();
|
|
490
|
-
console.log(` 3. ${
|
|
763
|
+
console.log(` 3. ${pc2.yellow("Add secrets to your worker:")}`);
|
|
491
764
|
console.log(` wrangler secret put WALLET_PRIVATE_KEY`);
|
|
492
765
|
console.log();
|
|
493
766
|
if (options.store1password && options.name) {
|
|
494
|
-
console.log(
|
|
495
|
-
console.log(
|
|
767
|
+
console.log(pc2.dim(`To retrieve later:`));
|
|
768
|
+
console.log(pc2.dim(` npx create-polymarket-strategy wallet get ${options.name}`));
|
|
496
769
|
console.log();
|
|
497
770
|
}
|
|
498
771
|
} catch (error) {
|
|
499
|
-
console.log(` ${
|
|
772
|
+
console.log(` ${pc2.red("\u2717")} Failed to derive API credentials`);
|
|
500
773
|
console.log(
|
|
501
|
-
|
|
774
|
+
pc2.yellow(
|
|
502
775
|
" This may be a network issue. You can derive credentials later."
|
|
503
776
|
)
|
|
504
777
|
);
|
|
505
778
|
console.log();
|
|
506
|
-
console.log(
|
|
507
|
-
console.log(
|
|
508
|
-
console.log(
|
|
779
|
+
console.log(pc2.cyan("\u2550".repeat(60)));
|
|
780
|
+
console.log(pc2.bold("WALLET CREATED (API credentials pending)"));
|
|
781
|
+
console.log(pc2.cyan("\u2550".repeat(60)));
|
|
509
782
|
console.log();
|
|
510
|
-
console.log(`${
|
|
511
|
-
console.log(`${
|
|
783
|
+
console.log(`${pc2.bold("Address:")} ${wallet.address}`);
|
|
784
|
+
console.log(`${pc2.bold("Private Key:")} ${wallet.privateKey}`);
|
|
512
785
|
console.log();
|
|
513
786
|
console.log(
|
|
514
|
-
|
|
787
|
+
pc2.yellow(
|
|
515
788
|
"Fund the wallet and re-run to derive API credentials."
|
|
516
789
|
)
|
|
517
790
|
);
|
|
@@ -520,99 +793,99 @@ async function walletCreate(options) {
|
|
|
520
793
|
}
|
|
521
794
|
async function walletBalance(address) {
|
|
522
795
|
console.log();
|
|
523
|
-
console.log(
|
|
796
|
+
console.log(pc2.cyan(`Checking balances for ${address}...`));
|
|
524
797
|
console.log();
|
|
525
798
|
try {
|
|
526
799
|
const balances = await getBalances(address);
|
|
527
|
-
console.log(
|
|
528
|
-
console.log(
|
|
529
|
-
console.log(
|
|
800
|
+
console.log(pc2.cyan("\u2550".repeat(50)));
|
|
801
|
+
console.log(pc2.bold("Polymarket Wallet Balance"));
|
|
802
|
+
console.log(pc2.cyan("\u2550".repeat(50)));
|
|
530
803
|
console.log();
|
|
531
804
|
console.log(
|
|
532
|
-
` ${
|
|
805
|
+
` ${pc2.bold("POL:")} ${balances.pol.toFixed(4)} (~$${(balances.pol * 0.4).toFixed(2)})`
|
|
533
806
|
);
|
|
534
|
-
console.log(` ${
|
|
807
|
+
console.log(` ${pc2.bold("USDC:")} $${balances.usdcNative.toFixed(2)}`);
|
|
535
808
|
console.log(
|
|
536
|
-
` ${
|
|
809
|
+
` ${pc2.bold("USDC.e:")} $${balances.usdcE.toFixed(2)} ${pc2.dim("(Polymarket uses this)")}`
|
|
537
810
|
);
|
|
538
811
|
console.log();
|
|
539
|
-
console.log(` ${
|
|
812
|
+
console.log(` ${pc2.bold("Total USDC:")} $${balances.totalUsdc.toFixed(2)}`);
|
|
540
813
|
console.log();
|
|
541
|
-
console.log(
|
|
814
|
+
console.log(pc2.cyan("\u2550".repeat(50)));
|
|
542
815
|
console.log(`View: https://polygonscan.com/address/${address}`);
|
|
543
816
|
console.log();
|
|
544
817
|
const approvals = await checkApprovals(address);
|
|
545
818
|
if (approvals.allApproved) {
|
|
546
|
-
console.log(
|
|
819
|
+
console.log(pc2.green("\u2713 All exchange contracts approved"));
|
|
547
820
|
} else {
|
|
548
|
-
console.log(
|
|
821
|
+
console.log(pc2.yellow("\u26A0 Some contracts not approved:"));
|
|
549
822
|
for (const detail of approvals.details) {
|
|
550
|
-
const status = detail.usdcApproved && detail.ctfApproved ?
|
|
823
|
+
const status = detail.usdcApproved && detail.ctfApproved ? pc2.green("\u2713") : pc2.red("\u2717");
|
|
551
824
|
console.log(` ${status} ${detail.contract}`);
|
|
552
825
|
}
|
|
553
826
|
console.log();
|
|
554
827
|
console.log(
|
|
555
|
-
|
|
828
|
+
pc2.dim("Run 'npx create-polymarket-strategy wallet setup' to approve")
|
|
556
829
|
);
|
|
557
830
|
}
|
|
558
831
|
console.log();
|
|
559
832
|
} catch (error) {
|
|
560
|
-
console.error(
|
|
833
|
+
console.error(pc2.red(`Error: ${error}`));
|
|
561
834
|
process.exit(1);
|
|
562
835
|
}
|
|
563
836
|
}
|
|
564
837
|
async function walletGet(name) {
|
|
565
838
|
console.log();
|
|
566
|
-
console.log(
|
|
839
|
+
console.log(pc2.cyan(`Retrieving wallet "${name}" from 1Password...`));
|
|
567
840
|
console.log();
|
|
568
841
|
const opStatus = check1PasswordCli();
|
|
569
842
|
if (!opStatus.available || !opStatus.authenticated) {
|
|
570
|
-
console.error(
|
|
843
|
+
console.error(pc2.red(`Error: ${opStatus.error}`));
|
|
571
844
|
process.exit(1);
|
|
572
845
|
}
|
|
573
846
|
const result = await getFrom1Password(name);
|
|
574
847
|
if (result.error) {
|
|
575
|
-
console.error(
|
|
848
|
+
console.error(pc2.red(`Error: ${result.error}`));
|
|
576
849
|
process.exit(1);
|
|
577
850
|
}
|
|
578
851
|
const creds = result.credentials;
|
|
579
|
-
console.log(
|
|
580
|
-
console.log(
|
|
581
|
-
console.log(
|
|
852
|
+
console.log(pc2.cyan("\u2550".repeat(60)));
|
|
853
|
+
console.log(pc2.bold(`${WALLET_ITEM_PREFIX} - ${name}`));
|
|
854
|
+
console.log(pc2.cyan("\u2550".repeat(60)));
|
|
582
855
|
console.log();
|
|
583
|
-
console.log(`${
|
|
584
|
-
console.log(`${
|
|
856
|
+
console.log(`${pc2.bold("Address:")} ${creds.address}`);
|
|
857
|
+
console.log(`${pc2.bold("Private Key:")} ${creds.privateKey}`);
|
|
585
858
|
if (creds.apiKey) {
|
|
586
|
-
console.log(`${
|
|
587
|
-
console.log(`${
|
|
588
|
-
console.log(`${
|
|
859
|
+
console.log(`${pc2.bold("API Key:")} ${creds.apiKey}`);
|
|
860
|
+
console.log(`${pc2.bold("API Secret:")} ${creds.apiSecret}`);
|
|
861
|
+
console.log(`${pc2.bold("API Passphrase:")} ${creds.apiPassphrase}`);
|
|
589
862
|
}
|
|
590
863
|
console.log();
|
|
591
864
|
}
|
|
592
865
|
async function walletList() {
|
|
593
866
|
console.log();
|
|
594
|
-
console.log(
|
|
867
|
+
console.log(pc2.cyan("Listing Polymarket wallets in 1Password..."));
|
|
595
868
|
console.log();
|
|
596
869
|
const opStatus = check1PasswordCli();
|
|
597
870
|
if (!opStatus.available || !opStatus.authenticated) {
|
|
598
|
-
console.error(
|
|
871
|
+
console.error(pc2.red(`Error: ${opStatus.error}`));
|
|
599
872
|
process.exit(1);
|
|
600
873
|
}
|
|
601
874
|
const wallets = listWallets();
|
|
602
875
|
if (wallets.length === 0) {
|
|
603
|
-
console.log(
|
|
876
|
+
console.log(pc2.yellow("No Polymarket wallets found in 1Password."));
|
|
604
877
|
console.log();
|
|
605
|
-
console.log(
|
|
606
|
-
console.log(
|
|
878
|
+
console.log(pc2.dim("Create one with:"));
|
|
879
|
+
console.log(pc2.dim(" npx create-polymarket-strategy wallet create --name my-trader --store-1password"));
|
|
607
880
|
console.log();
|
|
608
881
|
return;
|
|
609
882
|
}
|
|
610
|
-
console.log(
|
|
883
|
+
console.log(pc2.bold(`Found ${wallets.length} wallet(s):`));
|
|
611
884
|
console.log();
|
|
612
885
|
for (const name of wallets) {
|
|
613
886
|
const address = getWalletAddress(name);
|
|
614
|
-
console.log(` ${
|
|
615
|
-
console.log(` ${
|
|
887
|
+
console.log(` ${pc2.cyan(name)}`);
|
|
888
|
+
console.log(` ${pc2.dim(address || "address unavailable")}`);
|
|
616
889
|
}
|
|
617
890
|
console.log();
|
|
618
891
|
}
|
|
@@ -621,58 +894,73 @@ async function walletSetup(options) {
|
|
|
621
894
|
if (options.from1password) {
|
|
622
895
|
const opStatus = check1PasswordCli();
|
|
623
896
|
if (!opStatus.available || !opStatus.authenticated) {
|
|
624
|
-
console.error(
|
|
897
|
+
console.error(pc2.red(`Error: ${opStatus.error}`));
|
|
625
898
|
process.exit(1);
|
|
626
899
|
}
|
|
627
900
|
const result = await getFrom1Password(options.from1password);
|
|
628
901
|
if (result.error) {
|
|
629
|
-
console.error(
|
|
902
|
+
console.error(pc2.red(`Error: ${result.error}`));
|
|
630
903
|
process.exit(1);
|
|
631
904
|
}
|
|
632
905
|
privateKey = result.credentials.privateKey;
|
|
633
906
|
}
|
|
634
907
|
if (!privateKey) {
|
|
635
|
-
console.error(
|
|
908
|
+
console.error(pc2.red("Error: Either --private-key or --from-1password is required"));
|
|
636
909
|
process.exit(1);
|
|
637
910
|
}
|
|
638
911
|
console.log();
|
|
639
|
-
console.log(
|
|
912
|
+
console.log(pc2.cyan("Setting up wallet for Polymarket trading..."));
|
|
640
913
|
console.log();
|
|
641
914
|
try {
|
|
642
915
|
const { ethers: ethers2 } = await import("ethers");
|
|
643
916
|
const wallet = new ethers2.Wallet(privateKey);
|
|
644
917
|
const address = wallet.address;
|
|
645
|
-
console.log(` ${
|
|
918
|
+
console.log(` ${pc2.bold("Address:")} ${address}`);
|
|
646
919
|
console.log();
|
|
647
|
-
console.log(
|
|
648
|
-
|
|
920
|
+
console.log(pc2.yellow("Checking balances..."));
|
|
921
|
+
let balances = await getBalances(address);
|
|
649
922
|
console.log(` POL: ${balances.pol.toFixed(4)}`);
|
|
650
923
|
console.log(` USDC: $${balances.usdcNative.toFixed(2)}`);
|
|
651
924
|
console.log(` USDC.e: $${balances.usdcE.toFixed(2)}`);
|
|
652
925
|
console.log();
|
|
653
926
|
if (balances.pol < 0.01) {
|
|
654
|
-
console.error(
|
|
927
|
+
console.error(pc2.red("Error: Need at least 0.01 POL for gas fees"));
|
|
655
928
|
console.log(`Send POL to: ${address}`);
|
|
656
929
|
process.exit(1);
|
|
657
930
|
}
|
|
658
931
|
if (balances.usdcNative > 1 && balances.usdcE < 1) {
|
|
659
|
-
console.log(
|
|
660
|
-
|
|
661
|
-
"Note: You have native USDC but Polymarket requires USDC.e"
|
|
662
|
-
)
|
|
663
|
-
);
|
|
664
|
-
console.log(
|
|
665
|
-
pc.yellow("Use a DEX like Uniswap to swap USDC \u2192 USDC.e first")
|
|
666
|
-
);
|
|
932
|
+
console.log(pc2.yellow("Swapping native USDC \u2192 USDC.e via Uniswap V3..."));
|
|
933
|
+
console.log(pc2.dim("(Polymarket requires USDC.e, not native USDC)"));
|
|
667
934
|
console.log();
|
|
935
|
+
try {
|
|
936
|
+
const swapResult = await swapUsdcToUsdcE(
|
|
937
|
+
privateKey,
|
|
938
|
+
balances.usdcNative,
|
|
939
|
+
(msg) => {
|
|
940
|
+
console.log(` ${pc2.yellow("\u2192")} ${msg}`);
|
|
941
|
+
}
|
|
942
|
+
);
|
|
943
|
+
console.log(
|
|
944
|
+
` ${pc2.green("\u2713")} Swapped $${swapResult.amountIn.toFixed(2)} \u2192 $${swapResult.amountOut.toFixed(2)} USDC.e`
|
|
945
|
+
);
|
|
946
|
+
console.log(pc2.dim(` Tx: ${swapResult.txHash}`));
|
|
947
|
+
console.log();
|
|
948
|
+
balances = await getBalances(address);
|
|
949
|
+
} catch (error) {
|
|
950
|
+
console.error(pc2.red(` \u2717 Swap failed: ${error}`));
|
|
951
|
+
console.log(
|
|
952
|
+
pc2.yellow(" You can manually swap at https://app.uniswap.org")
|
|
953
|
+
);
|
|
954
|
+
process.exit(1);
|
|
955
|
+
}
|
|
668
956
|
}
|
|
669
|
-
console.log(
|
|
957
|
+
console.log(pc2.yellow("Approving Polymarket exchange contracts..."));
|
|
670
958
|
console.log(
|
|
671
|
-
|
|
959
|
+
pc2.dim("(3 contracts x 2 approvals each = up to 6 transactions)")
|
|
672
960
|
);
|
|
673
961
|
console.log();
|
|
674
962
|
const results = await approveExchangeContracts(privateKey, (msg) => {
|
|
675
|
-
console.log(` ${
|
|
963
|
+
console.log(` ${pc2.yellow("\u2192")} ${msg}`);
|
|
676
964
|
});
|
|
677
965
|
console.log();
|
|
678
966
|
let txCount = 0;
|
|
@@ -680,19 +968,19 @@ async function walletSetup(options) {
|
|
|
680
968
|
if (result.usdcTxHash) txCount++;
|
|
681
969
|
if (result.ctfTxHash) txCount++;
|
|
682
970
|
}
|
|
683
|
-
console.log(
|
|
684
|
-
console.log(
|
|
685
|
-
console.log(
|
|
971
|
+
console.log(pc2.cyan("\u2550".repeat(50)));
|
|
972
|
+
console.log(pc2.bold("Setup Complete"));
|
|
973
|
+
console.log(pc2.cyan("\u2550".repeat(50)));
|
|
686
974
|
console.log();
|
|
687
|
-
console.log(` ${
|
|
688
|
-
console.log(` ${
|
|
975
|
+
console.log(` ${pc2.green("\u2713")} All contracts approved`);
|
|
976
|
+
console.log(` ${pc2.dim(`${txCount} transaction(s) submitted`)}`);
|
|
689
977
|
console.log();
|
|
690
978
|
console.log(` USDC.e balance: $${balances.usdcE.toFixed(2)}`);
|
|
691
979
|
console.log();
|
|
692
|
-
console.log(
|
|
980
|
+
console.log(pc2.bold("Your wallet is ready for live trading!"));
|
|
693
981
|
console.log();
|
|
694
982
|
} catch (error) {
|
|
695
|
-
console.error(
|
|
983
|
+
console.error(pc2.red(`Error: ${error}`));
|
|
696
984
|
process.exit(1);
|
|
697
985
|
}
|
|
698
986
|
}
|
|
@@ -710,5 +998,8 @@ walletCmd.command("balance").description("Check wallet balances").argument("<add
|
|
|
710
998
|
walletCmd.command("setup").description("Approve exchange contracts for trading").option("--private-key <key>", "Wallet private key").option("--from-1password <name>", "Get private key from 1Password wallet").action((options) => walletSetup(options));
|
|
711
999
|
walletCmd.command("get").description("Retrieve wallet credentials from 1Password").argument("<name>", "Trader/strategy name").action(walletGet);
|
|
712
1000
|
walletCmd.command("list").description("List all Polymarket wallets in 1Password").action(walletList);
|
|
1001
|
+
var executorCmd = program.command("executor").description("Order executor management (Seoul Lambda)");
|
|
1002
|
+
executorCmd.command("register").description("Register wallet with Seoul executor").option("--from-1password <name>", "Get credentials from 1Password wallet").option("--wallet-id <id>", "Wallet ID for executor (default: {name}-live)").option("--aws-profile <profile>", "AWS profile to use").action((options) => executorRegister(options));
|
|
1003
|
+
executorCmd.command("generate-key").description("Generate API key for executor").requiredOption("--strategy <name>", "Strategy name").requiredOption("--wallets <ids>", "Comma-separated wallet IDs").option("--rate-limit <n>", "Rate limit (req/min)", "100").option("--aws-profile <profile>", "AWS profile to use").action((options) => executorGenerateKey(options));
|
|
713
1004
|
program.parse();
|
|
714
1005
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/wallet/index.ts","../src/wallet/constants.ts","../src/wallet/onepassword.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\";\nimport {\n check1PasswordCli,\n storeIn1Password,\n getFrom1Password,\n listWallets,\n getWalletAddress,\n WALLET_ITEM_PREFIX,\n} from \"./wallet/onepassword.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\ninterface WalletCreateOptions {\n name?: string;\n store1password?: boolean;\n vault?: string;\n}\n\nasync function walletCreate(options: WalletCreateOptions): Promise<void> {\n console.log();\n console.log(pc.cyan(\"Creating new Polymarket wallet...\"));\n console.log();\n\n // Check 1Password if storing\n if (options.store1password) {\n const opStatus = check1PasswordCli();\n if (!opStatus.available || !opStatus.authenticated) {\n console.error(pc.red(`Error: ${opStatus.error}`));\n process.exit(1);\n }\n console.log(` ${pc.green(\"✓\")} 1Password CLI authenticated`);\n }\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 const fullCreds = { ...wallet, ...apiCreds };\n\n // Store in 1Password if requested\n if (options.store1password && options.name) {\n console.log(` ${pc.yellow(\"→\")} Storing in 1Password...`);\n const result = await storeIn1Password(\n options.name,\n fullCreds,\n options.vault || \"Private\"\n );\n if (result.success) {\n console.log(` ${pc.green(\"✓\")} Stored as \"${result.itemName}\"`);\n } else {\n console.error(pc.red(` ✗ Failed to store: ${result.error}`));\n // Fall through to print credentials\n }\n }\n\n // Output credentials\n console.log();\n console.log(pc.cyan(\"═\".repeat(60)));\n if (options.store1password && options.name) {\n console.log(pc.bold(\"WALLET CREATED & STORED IN 1PASSWORD\"));\n } else {\n console.log(pc.bold(\"SAVE THESE CREDENTIALS SECURELY\"));\n }\n console.log(pc.cyan(\"═\".repeat(60)));\n console.log();\n console.log(`${pc.bold(\"Address:\")} ${wallet.address}`);\n if (!options.store1password) {\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 } else {\n console.log(pc.dim(\" (credentials stored securely in 1Password)\"));\n }\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 if (options.store1password && options.name) {\n console.log(\n ` npx create-polymarket-strategy wallet setup --from-1password ${options.name}`\n );\n } else {\n console.log(\n ` npx create-polymarket-strategy wallet setup --private-key <key>`\n );\n }\n console.log();\n console.log(` 3. ${pc.yellow(\"Add secrets to your worker:\")}`);\n console.log(` wrangler secret put WALLET_PRIVATE_KEY`);\n console.log();\n if (options.store1password && options.name) {\n console.log(pc.dim(`To retrieve later:`));\n console.log(pc.dim(` npx create-polymarket-strategy wallet get ${options.name}`));\n console.log();\n }\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 walletGet(name: string): Promise<void> {\n console.log();\n console.log(pc.cyan(`Retrieving wallet \"${name}\" from 1Password...`));\n console.log();\n\n const opStatus = check1PasswordCli();\n if (!opStatus.available || !opStatus.authenticated) {\n console.error(pc.red(`Error: ${opStatus.error}`));\n process.exit(1);\n }\n\n const result = await getFrom1Password(name);\n if (result.error) {\n console.error(pc.red(`Error: ${result.error}`));\n process.exit(1);\n }\n\n const creds = result.credentials!;\n console.log(pc.cyan(\"═\".repeat(60)));\n console.log(pc.bold(`${WALLET_ITEM_PREFIX} - ${name}`));\n console.log(pc.cyan(\"═\".repeat(60)));\n console.log();\n console.log(`${pc.bold(\"Address:\")} ${creds.address}`);\n console.log(`${pc.bold(\"Private Key:\")} ${creds.privateKey}`);\n if (creds.apiKey) {\n console.log(`${pc.bold(\"API Key:\")} ${creds.apiKey}`);\n console.log(`${pc.bold(\"API Secret:\")} ${creds.apiSecret}`);\n console.log(`${pc.bold(\"API Passphrase:\")} ${creds.apiPassphrase}`);\n }\n console.log();\n}\n\nasync function walletList(): Promise<void> {\n console.log();\n console.log(pc.cyan(\"Listing Polymarket wallets in 1Password...\"));\n console.log();\n\n const opStatus = check1PasswordCli();\n if (!opStatus.available || !opStatus.authenticated) {\n console.error(pc.red(`Error: ${opStatus.error}`));\n process.exit(1);\n }\n\n const wallets = listWallets();\n\n if (wallets.length === 0) {\n console.log(pc.yellow(\"No Polymarket wallets found in 1Password.\"));\n console.log();\n console.log(pc.dim(\"Create one with:\"));\n console.log(pc.dim(\" npx create-polymarket-strategy wallet create --name my-trader --store-1password\"));\n console.log();\n return;\n }\n\n console.log(pc.bold(`Found ${wallets.length} wallet(s):`));\n console.log();\n for (const name of wallets) {\n const address = getWalletAddress(name);\n console.log(` ${pc.cyan(name)}`);\n console.log(` ${pc.dim(address || \"address unavailable\")}`);\n }\n console.log();\n}\n\ninterface WalletSetupOptions {\n privateKey?: string;\n from1password?: string;\n}\n\nasync function walletSetup(options: WalletSetupOptions): Promise<void> {\n let privateKey = options.privateKey;\n\n // Get from 1Password if specified\n if (options.from1password) {\n const opStatus = check1PasswordCli();\n if (!opStatus.available || !opStatus.authenticated) {\n console.error(pc.red(`Error: ${opStatus.error}`));\n process.exit(1);\n }\n\n const result = await getFrom1Password(options.from1password);\n if (result.error) {\n console.error(pc.red(`Error: ${result.error}`));\n process.exit(1);\n }\n privateKey = result.credentials!.privateKey;\n }\n\n if (!privateKey) {\n console.error(pc.red(\"Error: Either --private-key or --from-1password is required\"));\n process.exit(1);\n }\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 .option(\"--name <name>\", \"Trader/strategy name (required for 1Password storage)\")\n .option(\"--store-1password\", \"Store credentials in 1Password\")\n .option(\"--vault <vault>\", \"1Password vault name\", \"Private\")\n .action((options) => walletCreate(options));\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 .option(\"--private-key <key>\", \"Wallet private key\")\n .option(\"--from-1password <name>\", \"Get private key from 1Password wallet\")\n .action((options) => walletSetup(options));\n\nwalletCmd\n .command(\"get\")\n .description(\"Retrieve wallet credentials from 1Password\")\n .argument(\"<name>\", \"Trader/strategy name\")\n .action(walletGet);\n\nwalletCmd\n .command(\"list\")\n .description(\"List all Polymarket wallets in 1Password\")\n .action(walletList);\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","/**\n * 1Password CLI Integration\n *\n * Provides secure storage for wallet credentials.\n */\n\nimport { execSync } from \"child_process\";\nimport type { FullCredentials } from \"./index.js\";\n\n// Standard naming convention for Polymarket wallets\nexport const WALLET_ITEM_PREFIX = \"Polymarket Wallet\";\n\n/**\n * Check if 1Password CLI is available and authenticated.\n */\nexport function check1PasswordCli(): { available: boolean; authenticated: boolean; error?: string } {\n try {\n execSync(\"which op\", { encoding: \"utf8\", stdio: \"pipe\" });\n } catch {\n return {\n available: false,\n authenticated: false,\n error: \"1Password CLI not installed. Install with: brew install --cask 1password-cli\",\n };\n }\n\n try {\n execSync(\"op account list\", { encoding: \"utf8\", stdio: \"pipe\" });\n return { available: true, authenticated: true };\n } catch {\n return {\n available: true,\n authenticated: false,\n error: \"1Password CLI not authenticated. Enable app integration: Settings → Developer → Integrate with 1Password CLI\",\n };\n }\n}\n\n/**\n * Store wallet credentials in 1Password.\n *\n * @param name - Trader/strategy name (e.g., \"temperature\")\n * @param credentials - Full wallet and API credentials\n * @param vault - 1Password vault name (default: \"Private\")\n */\nexport async function storeIn1Password(\n name: string,\n credentials: FullCredentials,\n vault: string = \"Private\"\n): Promise<{ itemName: string; success: boolean; error?: string }> {\n const itemName = `${WALLET_ITEM_PREFIX} - ${name}`;\n\n try {\n // Build op item create command\n const fields = [\n `address[text]=${credentials.address}`,\n `private_key[password]=${credentials.privateKey}`,\n `api_key[text]=${credentials.apiKey}`,\n `api_secret[password]=${credentials.apiSecret}`,\n `api_passphrase[password]=${credentials.apiPassphrase}`,\n `created_at[text]=${new Date().toISOString()}`,\n ];\n\n const cmd = [\n \"op\",\n \"item\",\n \"create\",\n \"--category=Login\",\n `--title=${itemName}`,\n `--vault=${vault}`,\n ...fields.map((f) => `\"${f}\"`),\n ].join(\" \");\n\n execSync(cmd, { encoding: \"utf8\", stdio: \"pipe\" });\n\n return { itemName, success: true };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n return { itemName, success: false, error: msg };\n }\n}\n\n/**\n * Retrieve wallet credentials from 1Password.\n *\n * @param name - Trader/strategy name (e.g., \"temperature\")\n */\nexport async function getFrom1Password(\n name: string\n): Promise<{ credentials?: FullCredentials; error?: string }> {\n const itemName = `${WALLET_ITEM_PREFIX} - ${name}`;\n\n try {\n // Get all fields at once\n const output = execSync(\n `op item get \"${itemName}\" --format json`,\n { encoding: \"utf8\", stdio: \"pipe\" }\n );\n\n const item = JSON.parse(output);\n const fields: Record<string, string> = {};\n\n for (const field of item.fields || []) {\n if (field.label && field.value) {\n fields[field.label] = field.value;\n }\n }\n\n if (!fields.address || !fields.private_key) {\n return { error: `Wallet \"${itemName}\" is missing required fields` };\n }\n\n return {\n credentials: {\n address: fields.address,\n privateKey: fields.private_key,\n apiKey: fields.api_key || \"\",\n apiSecret: fields.api_secret || \"\",\n apiPassphrase: fields.api_passphrase || \"\",\n },\n };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n if (msg.includes(\"isn't an item\")) {\n return { error: `Wallet \"${itemName}\" not found in 1Password` };\n }\n return { error: msg };\n }\n}\n\n/**\n * List all Polymarket wallets in 1Password.\n */\nexport function listWallets(vault?: string): string[] {\n try {\n const vaultArg = vault ? `--vault=\"${vault}\"` : \"\";\n const output = execSync(\n `op item list --format json ${vaultArg}`,\n { encoding: \"utf8\", stdio: \"pipe\" }\n );\n\n const items = JSON.parse(output);\n const wallets: string[] = [];\n\n for (const item of items) {\n if (item.title?.startsWith(WALLET_ITEM_PREFIX)) {\n const name = item.title.replace(`${WALLET_ITEM_PREFIX} - `, \"\");\n wallets.push(name);\n }\n }\n\n return wallets;\n } catch {\n return [];\n }\n}\n\n/**\n * Get just the wallet address from 1Password (quick lookup).\n */\nexport function getWalletAddress(name: string): string | null {\n const itemName = `${WALLET_ITEM_PREFIX} - ${name}`;\n\n try {\n const output = execSync(\n `op item get \"${itemName}\" --fields address --reveal`,\n { encoding: \"utf8\", stdio: \"pipe\" }\n );\n return output.trim();\n } catch {\n return null;\n }\n}\n"],"mappings":"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","names":["execSync","execSync","ethers"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/wallet/index.ts","../src/wallet/constants.ts","../src/wallet/onepassword.ts","../src/executor/index.ts","../src/executor/aws.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 swapUsdcToUsdcE,\n} from \"./wallet/index.js\";\nimport {\n check1PasswordCli,\n storeIn1Password,\n getFrom1Password,\n listWallets,\n getWalletAddress,\n WALLET_ITEM_PREFIX,\n} from \"./wallet/onepassword.js\";\nimport {\n executorRegister,\n executorGenerateKey,\n} from \"./executor/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\ninterface WalletCreateOptions {\n name?: string;\n store1password?: boolean;\n vault?: string;\n}\n\nasync function walletCreate(options: WalletCreateOptions): Promise<void> {\n console.log();\n console.log(pc.cyan(\"Creating new Polymarket wallet...\"));\n console.log();\n\n // Check 1Password if storing\n if (options.store1password) {\n const opStatus = check1PasswordCli();\n if (!opStatus.available || !opStatus.authenticated) {\n console.error(pc.red(`Error: ${opStatus.error}`));\n process.exit(1);\n }\n console.log(` ${pc.green(\"✓\")} 1Password CLI authenticated`);\n }\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 const fullCreds = { ...wallet, ...apiCreds };\n\n // Store in 1Password if requested\n if (options.store1password && options.name) {\n console.log(` ${pc.yellow(\"→\")} Storing in 1Password...`);\n const result = await storeIn1Password(\n options.name,\n fullCreds,\n options.vault || \"Private\"\n );\n if (result.success) {\n console.log(` ${pc.green(\"✓\")} Stored as \"${result.itemName}\"`);\n } else {\n console.error(pc.red(` ✗ Failed to store: ${result.error}`));\n // Fall through to print credentials\n }\n }\n\n // Output credentials\n console.log();\n console.log(pc.cyan(\"═\".repeat(60)));\n if (options.store1password && options.name) {\n console.log(pc.bold(\"WALLET CREATED & STORED IN 1PASSWORD\"));\n } else {\n console.log(pc.bold(\"SAVE THESE CREDENTIALS SECURELY\"));\n }\n console.log(pc.cyan(\"═\".repeat(60)));\n console.log();\n console.log(`${pc.bold(\"Address:\")} ${wallet.address}`);\n if (!options.store1password) {\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 } else {\n console.log(pc.dim(\" (credentials stored securely in 1Password)\"));\n }\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 if (options.store1password && options.name) {\n console.log(\n ` npx create-polymarket-strategy wallet setup --from-1password ${options.name}`\n );\n } else {\n console.log(\n ` npx create-polymarket-strategy wallet setup --private-key <key>`\n );\n }\n console.log();\n console.log(` 3. ${pc.yellow(\"Add secrets to your worker:\")}`);\n console.log(` wrangler secret put WALLET_PRIVATE_KEY`);\n console.log();\n if (options.store1password && options.name) {\n console.log(pc.dim(`To retrieve later:`));\n console.log(pc.dim(` npx create-polymarket-strategy wallet get ${options.name}`));\n console.log();\n }\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 walletGet(name: string): Promise<void> {\n console.log();\n console.log(pc.cyan(`Retrieving wallet \"${name}\" from 1Password...`));\n console.log();\n\n const opStatus = check1PasswordCli();\n if (!opStatus.available || !opStatus.authenticated) {\n console.error(pc.red(`Error: ${opStatus.error}`));\n process.exit(1);\n }\n\n const result = await getFrom1Password(name);\n if (result.error) {\n console.error(pc.red(`Error: ${result.error}`));\n process.exit(1);\n }\n\n const creds = result.credentials!;\n console.log(pc.cyan(\"═\".repeat(60)));\n console.log(pc.bold(`${WALLET_ITEM_PREFIX} - ${name}`));\n console.log(pc.cyan(\"═\".repeat(60)));\n console.log();\n console.log(`${pc.bold(\"Address:\")} ${creds.address}`);\n console.log(`${pc.bold(\"Private Key:\")} ${creds.privateKey}`);\n if (creds.apiKey) {\n console.log(`${pc.bold(\"API Key:\")} ${creds.apiKey}`);\n console.log(`${pc.bold(\"API Secret:\")} ${creds.apiSecret}`);\n console.log(`${pc.bold(\"API Passphrase:\")} ${creds.apiPassphrase}`);\n }\n console.log();\n}\n\nasync function walletList(): Promise<void> {\n console.log();\n console.log(pc.cyan(\"Listing Polymarket wallets in 1Password...\"));\n console.log();\n\n const opStatus = check1PasswordCli();\n if (!opStatus.available || !opStatus.authenticated) {\n console.error(pc.red(`Error: ${opStatus.error}`));\n process.exit(1);\n }\n\n const wallets = listWallets();\n\n if (wallets.length === 0) {\n console.log(pc.yellow(\"No Polymarket wallets found in 1Password.\"));\n console.log();\n console.log(pc.dim(\"Create one with:\"));\n console.log(pc.dim(\" npx create-polymarket-strategy wallet create --name my-trader --store-1password\"));\n console.log();\n return;\n }\n\n console.log(pc.bold(`Found ${wallets.length} wallet(s):`));\n console.log();\n for (const name of wallets) {\n const address = getWalletAddress(name);\n console.log(` ${pc.cyan(name)}`);\n console.log(` ${pc.dim(address || \"address unavailable\")}`);\n }\n console.log();\n}\n\ninterface WalletSetupOptions {\n privateKey?: string;\n from1password?: string;\n}\n\nasync function walletSetup(options: WalletSetupOptions): Promise<void> {\n let privateKey = options.privateKey;\n\n // Get from 1Password if specified\n if (options.from1password) {\n const opStatus = check1PasswordCli();\n if (!opStatus.available || !opStatus.authenticated) {\n console.error(pc.red(`Error: ${opStatus.error}`));\n process.exit(1);\n }\n\n const result = await getFrom1Password(options.from1password);\n if (result.error) {\n console.error(pc.red(`Error: ${result.error}`));\n process.exit(1);\n }\n privateKey = result.credentials!.privateKey;\n }\n\n if (!privateKey) {\n console.error(pc.red(\"Error: Either --private-key or --from-1password is required\"));\n process.exit(1);\n }\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 let 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(pc.yellow(\"Swapping native USDC → USDC.e via Uniswap V3...\"));\n console.log(pc.dim(\"(Polymarket requires USDC.e, not native USDC)\"));\n console.log();\n\n try {\n const swapResult = await swapUsdcToUsdcE(\n privateKey,\n balances.usdcNative,\n (msg) => {\n console.log(` ${pc.yellow(\"→\")} ${msg}`);\n }\n );\n console.log(\n ` ${pc.green(\"✓\")} Swapped $${swapResult.amountIn.toFixed(2)} → $${swapResult.amountOut.toFixed(2)} USDC.e`\n );\n console.log(pc.dim(` Tx: ${swapResult.txHash}`));\n console.log();\n\n // Refresh balances after swap\n balances = await getBalances(address);\n } catch (error) {\n console.error(pc.red(` ✗ Swap failed: ${error}`));\n console.log(\n pc.yellow(\" You can manually swap at https://app.uniswap.org\")\n );\n process.exit(1);\n }\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 .option(\"--name <name>\", \"Trader/strategy name (required for 1Password storage)\")\n .option(\"--store-1password\", \"Store credentials in 1Password\")\n .option(\"--vault <vault>\", \"1Password vault name\", \"Private\")\n .action((options) => walletCreate(options));\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 .option(\"--private-key <key>\", \"Wallet private key\")\n .option(\"--from-1password <name>\", \"Get private key from 1Password wallet\")\n .action((options) => walletSetup(options));\n\nwalletCmd\n .command(\"get\")\n .description(\"Retrieve wallet credentials from 1Password\")\n .argument(\"<name>\", \"Trader/strategy name\")\n .action(walletGet);\n\nwalletCmd\n .command(\"list\")\n .description(\"List all Polymarket wallets in 1Password\")\n .action(walletList);\n\n// Executor subcommands\nconst executorCmd = program\n .command(\"executor\")\n .description(\"Order executor management (Seoul Lambda)\");\n\nexecutorCmd\n .command(\"register\")\n .description(\"Register wallet with Seoul executor\")\n .option(\"--from-1password <name>\", \"Get credentials from 1Password wallet\")\n .option(\"--wallet-id <id>\", \"Wallet ID for executor (default: {name}-live)\")\n .option(\"--aws-profile <profile>\", \"AWS profile to use\")\n .action((options) => executorRegister(options));\n\nexecutorCmd\n .command(\"generate-key\")\n .description(\"Generate API key for executor\")\n .requiredOption(\"--strategy <name>\", \"Strategy name\")\n .requiredOption(\"--wallets <ids>\", \"Comma-separated wallet IDs\")\n .option(\"--rate-limit <n>\", \"Rate limit (req/min)\", \"100\")\n .option(\"--aws-profile <profile>\", \"AWS profile to use\")\n .action((options) => executorGenerateKey(options));\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 UNISWAP_ROUTER,\n CLOB_AUTH_DOMAIN,\n CLOB_AUTH_MESSAGE,\n ERC20_ABI,\n ERC1155_ABI,\n UNISWAP_ROUTER_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// USDC Swap (Native USDC → USDC.e)\n// =============================================================================\n\nexport interface SwapResult {\n amountIn: number;\n amountOut: number;\n txHash: string;\n}\n\n/**\n * Swap native USDC to USDC.e via Uniswap V3.\n * Polymarket requires USDC.e, not native USDC.\n */\nexport async function swapUsdcToUsdcE(\n privateKey: string,\n amount: number, // Amount in USDC (human readable, e.g., 100.00)\n onProgress?: (message: string) => void\n): Promise<SwapResult> {\n const provider = getProvider();\n const wallet = new ethers.Wallet(privateKey, provider);\n const amountIn = ethers.parseUnits(amount.toFixed(6), 6); // USDC has 6 decimals\n\n // Step 1: Approve Uniswap router to spend native USDC\n onProgress?.(\"Approving Uniswap to spend USDC...\");\n const usdcNative = new ethers.Contract(USDC_NATIVE, ERC20_ABI, wallet);\n\n const currentAllowance = await usdcNative.allowance(wallet.address, UNISWAP_ROUTER);\n if (currentAllowance < amountIn) {\n const approveTx = await usdcNative.approve(UNISWAP_ROUTER, amountIn);\n await approveTx.wait();\n }\n\n // Step 2: Execute swap via Uniswap V3 exactInputSingle\n onProgress?.(`Swapping ${amount.toFixed(2)} USDC → USDC.e...`);\n const router = new ethers.Contract(UNISWAP_ROUTER, UNISWAP_ROUTER_ABI, wallet);\n\n // Allow 1% slippage (USDC/USDC.e is ~1:1)\n const minOut = (amountIn * 99n) / 100n;\n const deadline = Math.floor(Date.now() / 1000) + 300; // 5 minutes\n\n const swapParams = {\n tokenIn: USDC_NATIVE,\n tokenOut: USDC_E,\n fee: 500, // 0.05% fee tier - standard for stablecoin pairs\n recipient: wallet.address,\n deadline: deadline,\n amountIn: amountIn,\n amountOutMinimum: minOut,\n sqrtPriceLimitX96: 0, // No price limit\n };\n\n const swapTx = await router.exactInputSingle(swapParams);\n const receipt = await swapTx.wait();\n\n // Get actual amount out from the swap\n // For simplicity, we assume ~1:1 swap for stablecoins\n // In production, you'd parse the Swap event from the receipt\n const amountOutEstimate = Number(ethers.formatUnits(minOut, 6));\n\n return {\n amountIn: amount,\n amountOut: amountOutEstimate,\n txHash: receipt.hash,\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://polygon.drpc.org\";\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","/**\n * 1Password CLI Integration\n *\n * Provides secure storage for wallet credentials.\n */\n\nimport { execSync } from \"child_process\";\nimport type { FullCredentials } from \"./index.js\";\n\n// Standard naming convention for Polymarket wallets\nexport const WALLET_ITEM_PREFIX = \"Polymarket Wallet\";\n\n/**\n * Check if 1Password CLI is available and authenticated.\n */\nexport function check1PasswordCli(): { available: boolean; authenticated: boolean; error?: string } {\n try {\n execSync(\"which op\", { encoding: \"utf8\", stdio: \"pipe\" });\n } catch {\n return {\n available: false,\n authenticated: false,\n error: \"1Password CLI not installed. Install with: brew install --cask 1password-cli\",\n };\n }\n\n try {\n execSync(\"op account list\", { encoding: \"utf8\", stdio: \"pipe\" });\n return { available: true, authenticated: true };\n } catch {\n return {\n available: true,\n authenticated: false,\n error: \"1Password CLI not authenticated. Enable app integration: Settings → Developer → Integrate with 1Password CLI\",\n };\n }\n}\n\n/**\n * Store wallet credentials in 1Password.\n *\n * @param name - Trader/strategy name (e.g., \"temperature\")\n * @param credentials - Full wallet and API credentials\n * @param vault - 1Password vault name (default: \"Private\")\n */\nexport async function storeIn1Password(\n name: string,\n credentials: FullCredentials,\n vault: string = \"Private\"\n): Promise<{ itemName: string; success: boolean; error?: string }> {\n const itemName = `${WALLET_ITEM_PREFIX} - ${name}`;\n\n try {\n // Build op item create command\n const fields = [\n `address[text]=${credentials.address}`,\n `private_key[password]=${credentials.privateKey}`,\n `api_key[text]=${credentials.apiKey}`,\n `api_secret[password]=${credentials.apiSecret}`,\n `api_passphrase[password]=${credentials.apiPassphrase}`,\n `created_at[text]=${new Date().toISOString()}`,\n ];\n\n const cmd = [\n \"op\",\n \"item\",\n \"create\",\n \"--category=Login\",\n `--title=${itemName}`,\n `--vault=${vault}`,\n ...fields.map((f) => `\"${f}\"`),\n ].join(\" \");\n\n execSync(cmd, { encoding: \"utf8\", stdio: \"pipe\" });\n\n return { itemName, success: true };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n return { itemName, success: false, error: msg };\n }\n}\n\n/**\n * Retrieve wallet credentials from 1Password.\n *\n * @param name - Trader/strategy name (e.g., \"temperature\")\n */\nexport async function getFrom1Password(\n name: string\n): Promise<{ credentials?: FullCredentials; error?: string }> {\n const itemName = `${WALLET_ITEM_PREFIX} - ${name}`;\n\n try {\n // Get all fields at once\n const output = execSync(\n `op item get \"${itemName}\" --format json`,\n { encoding: \"utf8\", stdio: \"pipe\" }\n );\n\n const item = JSON.parse(output);\n const fields: Record<string, string> = {};\n\n for (const field of item.fields || []) {\n if (field.label && field.value) {\n fields[field.label] = field.value;\n }\n }\n\n if (!fields.address || !fields.private_key) {\n return { error: `Wallet \"${itemName}\" is missing required fields` };\n }\n\n return {\n credentials: {\n address: fields.address,\n privateKey: fields.private_key,\n apiKey: fields.api_key || \"\",\n apiSecret: fields.api_secret || \"\",\n apiPassphrase: fields.api_passphrase || \"\",\n },\n };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n if (msg.includes(\"isn't an item\")) {\n return { error: `Wallet \"${itemName}\" not found in 1Password` };\n }\n return { error: msg };\n }\n}\n\n/**\n * List all Polymarket wallets in 1Password.\n */\nexport function listWallets(vault?: string): string[] {\n try {\n const vaultArg = vault ? `--vault=\"${vault}\"` : \"\";\n const output = execSync(\n `op item list --format json ${vaultArg}`,\n { encoding: \"utf8\", stdio: \"pipe\" }\n );\n\n const items = JSON.parse(output);\n const wallets: string[] = [];\n\n for (const item of items) {\n if (item.title?.startsWith(WALLET_ITEM_PREFIX)) {\n const name = item.title.replace(`${WALLET_ITEM_PREFIX} - `, \"\");\n wallets.push(name);\n }\n }\n\n return wallets;\n } catch {\n return [];\n }\n}\n\n/**\n * Get just the wallet address from 1Password (quick lookup).\n */\nexport function getWalletAddress(name: string): string | null {\n const itemName = `${WALLET_ITEM_PREFIX} - ${name}`;\n\n try {\n const output = execSync(\n `op item get \"${itemName}\" --fields address --reveal`,\n { encoding: \"utf8\", stdio: \"pipe\" }\n );\n return output.trim();\n } catch {\n return null;\n }\n}\n","import pc from \"picocolors\";\nimport { getFrom1Password, check1PasswordCli } from \"../wallet/onepassword.js\";\nimport {\n registerWallet,\n generateApiKey,\n isWalletRegistered,\n getExecutorUrl,\n} from \"./aws.js\";\n\nexport interface ExecutorRegisterOptions {\n from1password?: string;\n walletId?: string;\n awsProfile?: string;\n}\n\nexport interface ExecutorGenerateKeyOptions {\n strategy: string;\n wallets: string;\n rateLimit?: string;\n awsProfile?: string;\n}\n\n/**\n * Register a wallet with the Seoul executor.\n */\nexport async function executorRegister(\n options: ExecutorRegisterOptions\n): Promise<void> {\n console.log();\n console.log(pc.cyan(\"Registering wallet with Seoul executor...\"));\n console.log();\n\n // Set AWS profile if specified\n if (options.awsProfile) {\n process.env.AWS_PROFILE = options.awsProfile;\n console.log(` ${pc.dim(`Using AWS profile: ${options.awsProfile}`)}`);\n }\n\n // Get credentials from 1Password\n if (!options.from1password) {\n console.error(pc.red(\"Error: --from-1password is required\"));\n process.exit(1);\n }\n\n const opStatus = check1PasswordCli();\n if (!opStatus.available || !opStatus.authenticated) {\n console.error(pc.red(`Error: ${opStatus.error}`));\n process.exit(1);\n }\n\n console.log(` ${pc.yellow(\"→\")} Reading credentials from 1Password...`);\n const result = await getFrom1Password(options.from1password);\n if (result.error || !result.credentials) {\n console.error(pc.red(`Error: ${result.error}`));\n process.exit(1);\n }\n\n const creds = result.credentials;\n\n // Check if all required fields are present\n if (!creds.apiKey || !creds.apiSecret || !creds.apiPassphrase) {\n console.error(\n pc.red(\"Error: Wallet is missing API credentials (apiKey, apiSecret, apiPassphrase)\")\n );\n console.log(\n pc.yellow(\" Run 'wallet setup' first to derive API credentials\")\n );\n process.exit(1);\n }\n\n // Determine wallet ID\n const walletId = options.walletId || `${options.from1password}-live`;\n console.log(` ${pc.yellow(\"→\")} Wallet ID: ${pc.bold(walletId)}`);\n\n // Check if already registered\n const alreadyRegistered = await isWalletRegistered(walletId);\n if (alreadyRegistered) {\n console.log(` ${pc.yellow(\"!\")} Wallet already registered, updating...`);\n }\n\n // Register with executor\n console.log(` ${pc.yellow(\"→\")} Storing in AWS Secrets Manager...`);\n try {\n const registerResult = await registerWallet(walletId, {\n privateKey: creds.privateKey,\n apiKey: creds.apiKey,\n apiSecret: creds.apiSecret,\n apiPassphrase: creds.apiPassphrase,\n });\n\n console.log(\n ` ${pc.green(\"✓\")} ${registerResult.created ? \"Created\" : \"Updated\"}: ${registerResult.secretName}`\n );\n } catch (error: any) {\n console.error(pc.red(`Error: ${error.message}`));\n if (error.name === \"CredentialsProviderError\") {\n console.log(pc.yellow(\" Make sure AWS credentials are configured:\"));\n console.log(pc.yellow(\" export AWS_PROFILE=polymarket\"));\n console.log(pc.yellow(\" Or run: aws configure\"));\n }\n process.exit(1);\n }\n\n // Output next steps\n console.log();\n console.log(pc.cyan(\"═\".repeat(60)));\n console.log(pc.bold(\"Wallet Registered with Executor\"));\n console.log(pc.cyan(\"═\".repeat(60)));\n console.log();\n console.log(` ${pc.bold(\"Wallet ID:\")} ${walletId}`);\n console.log(` ${pc.bold(\"Region:\")} ap-northeast-2 (Seoul)`);\n console.log(` ${pc.bold(\"Executor:\")} ${getExecutorUrl()}`);\n console.log();\n console.log(pc.bold(\"Next step:\"));\n console.log();\n console.log(\n ` ${pc.cyan(`npx create-polymarket-strategy executor generate-key --strategy ${options.from1password} --wallets ${walletId}`)}`\n );\n console.log();\n}\n\n/**\n * Generate an API key for the executor.\n */\nexport async function executorGenerateKey(\n options: ExecutorGenerateKeyOptions\n): Promise<void> {\n console.log();\n console.log(pc.cyan(\"Generating executor API key...\"));\n console.log();\n\n // Set AWS profile if specified\n if (options.awsProfile) {\n process.env.AWS_PROFILE = options.awsProfile;\n console.log(` ${pc.dim(`Using AWS profile: ${options.awsProfile}`)}`);\n }\n\n const wallets = options.wallets.split(\",\").map((w) => w.trim());\n const rateLimit = parseInt(options.rateLimit || \"100\", 10);\n\n console.log(` ${pc.bold(\"Strategy:\")} ${options.strategy}`);\n console.log(` ${pc.bold(\"Wallets:\")} ${wallets.join(\", \")}`);\n console.log(` ${pc.bold(\"Rate limit:\")} ${rateLimit} req/min`);\n console.log();\n\n console.log(` ${pc.yellow(\"→\")} Generating API key...`);\n\n try {\n const result = await generateApiKey(options.strategy, wallets, rateLimit);\n\n console.log(` ${pc.green(\"✓\")} API key generated`);\n console.log();\n console.log(pc.cyan(\"═\".repeat(60)));\n console.log(pc.bold(\"Executor API Key Generated\"));\n console.log(pc.cyan(\"═\".repeat(60)));\n console.log();\n console.log(` ${pc.bold(\"API Key:\")} ${pc.green(result.apiKey)}`);\n console.log(` ${pc.bold(\"Strategy:\")} ${result.info.strategy}`);\n console.log(` ${pc.bold(\"Wallets:\")} ${result.info.allowed_wallets.join(\", \")}`);\n console.log();\n console.log(pc.yellow(\"IMPORTANT: Save this key - it cannot be retrieved later!\"));\n console.log();\n console.log(pc.bold(\"Configure your Worker:\"));\n console.log();\n console.log(` ${pc.cyan(\"# Set as Cloudflare secret\")}`);\n console.log(` ${pc.cyan(`echo \"${result.apiKey}\" | wrangler secret put EXECUTOR_API_KEY`)}`);\n console.log();\n console.log(` ${pc.cyan(\"# Or in wrangler.jsonc vars (less secure)\")}`);\n console.log(` ${pc.dim(`\"EXECUTOR_URL\": \"${getExecutorUrl()}\"`)}`);\n console.log(` ${pc.dim(`\"EXECUTOR_WALLET_ID\": \"${wallets[0]}\"`)}`);\n console.log();\n } catch (error: any) {\n console.error(pc.red(`Error: ${error.message}`));\n if (error.name === \"CredentialsProviderError\") {\n console.log(pc.yellow(\" Make sure AWS credentials are configured:\"));\n console.log(pc.yellow(\" export AWS_PROFILE=polymarket\"));\n }\n process.exit(1);\n }\n}\n","import {\n SecretsManagerClient,\n CreateSecretCommand,\n GetSecretValueCommand,\n PutSecretValueCommand,\n DescribeSecretCommand,\n} from \"@aws-sdk/client-secrets-manager\";\nimport crypto from \"crypto\";\n\nconst REGION = \"ap-northeast-2\";\n\nexport interface WalletCredentials {\n privateKey: string;\n apiKey: string;\n apiSecret: string;\n apiPassphrase: string;\n}\n\nexport interface ApiKeyInfo {\n strategy: string;\n allowed_wallets: string[];\n created_at: string;\n rate_limit: number;\n}\n\n/**\n * Get Secrets Manager client for Seoul region.\n * Uses AWS_PROFILE env var or default credential chain.\n */\nexport function getSecretsClient(): SecretsManagerClient {\n return new SecretsManagerClient({ region: REGION });\n}\n\n/**\n * Check if a wallet is already registered.\n */\nexport async function isWalletRegistered(walletId: string): Promise<boolean> {\n const client = getSecretsClient();\n const secretName = `polymarket/wallets/${walletId}`;\n\n try {\n await client.send(new DescribeSecretCommand({ SecretId: secretName }));\n return true;\n } catch (error: any) {\n if (error.name === \"ResourceNotFoundException\") {\n return false;\n }\n throw error;\n }\n}\n\n/**\n * Register a wallet with the executor.\n * Stores credentials in AWS Secrets Manager.\n */\nexport async function registerWallet(\n walletId: string,\n credentials: WalletCredentials\n): Promise<{ created: boolean; secretName: string }> {\n const client = getSecretsClient();\n const secretName = `polymarket/wallets/${walletId}`;\n\n const secretValue = JSON.stringify({\n private_key: credentials.privateKey,\n api_key: credentials.apiKey,\n api_secret: credentials.apiSecret,\n api_passphrase: credentials.apiPassphrase,\n });\n\n try {\n await client.send(\n new CreateSecretCommand({\n Name: secretName,\n SecretString: secretValue,\n Description: `Polymarket wallet credentials for ${walletId}`,\n })\n );\n return { created: true, secretName };\n } catch (error: any) {\n if (error.name === \"ResourceExistsException\") {\n // Update existing secret\n await client.send(\n new PutSecretValueCommand({\n SecretId: secretName,\n SecretString: secretValue,\n })\n );\n return { created: false, secretName };\n }\n throw error;\n }\n}\n\n/**\n * Generate an API key for the executor.\n * Adds key to executor/api-keys secret.\n */\nexport async function generateApiKey(\n strategy: string,\n wallets: string[],\n rateLimit: number = 100\n): Promise<{ apiKey: string; info: ApiKeyInfo }> {\n const client = getSecretsClient();\n const secretName = \"executor/api-keys\";\n\n // Generate key with random suffix\n const suffix = crypto.randomBytes(6).toString(\"hex\");\n const apiKey = `exk_${strategy}_${suffix}`;\n\n const info: ApiKeyInfo = {\n strategy,\n allowed_wallets: wallets,\n created_at: new Date().toISOString(),\n rate_limit: rateLimit,\n };\n\n // Get existing keys or start fresh\n let existingKeys: Record<string, ApiKeyInfo> = {};\n try {\n const response = await client.send(\n new GetSecretValueCommand({ SecretId: secretName })\n );\n existingKeys = JSON.parse(response.SecretString || \"{}\");\n } catch (error: any) {\n if (error.name !== \"ResourceNotFoundException\") {\n throw error;\n }\n }\n\n // Add new key\n existingKeys[apiKey] = info;\n\n // Save\n try {\n await client.send(\n new CreateSecretCommand({\n Name: secretName,\n SecretString: JSON.stringify(existingKeys),\n Description: \"API keys for Polymarket order executor\",\n })\n );\n } catch (error: any) {\n if (error.name === \"ResourceExistsException\") {\n await client.send(\n new PutSecretValueCommand({\n SecretId: secretName,\n SecretString: JSON.stringify(existingKeys),\n })\n );\n } else {\n throw error;\n }\n }\n\n return { apiKey, info };\n}\n\n/**\n * List all registered wallets.\n */\nexport async function listRegisteredWallets(): Promise<string[]> {\n // Note: This would require listing secrets with prefix filter\n // For now, just return empty - user should track their own wallets\n return [];\n}\n\n/**\n * Get executor URL (hardcoded for now).\n */\nexport function getExecutorUrl(): string {\n return \"https://omnsgrhcc4.execute-api.ap-northeast-2.amazonaws.com/v1\";\n}\n"],"mappings":"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","names":["execSync","pc","pc","execSync","ethers"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-polymarket-strategy",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Create a new Polymarket trading strategy project",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"prepublishOnly": "pnpm run build"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
+
"@aws-sdk/client-secrets-manager": "^3.1000.0",
|
|
20
21
|
"commander": "^12.0.0",
|
|
21
22
|
"ethers": "^6.11.0",
|
|
22
23
|
"fs-extra": "^11.2.0",
|