create-polymarket-strategy 0.2.0 → 0.2.2
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 +317 -28
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/worker/package.json +1 -1
- package/templates/worker/src/durable-objects/positions.ts +189 -2
- package/templates/worker/src/durable-objects/scheduler.ts +108 -0
- package/templates/worker/src/lib/quote-manager.ts +358 -0
- package/templates/worker/src/scanner.ts +55 -3
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { program } from "commander";
|
|
5
5
|
import fs from "fs-extra";
|
|
6
6
|
import path from "path";
|
|
7
|
-
import { execSync } from "child_process";
|
|
7
|
+
import { execSync as execSync2 } from "child_process";
|
|
8
8
|
import pc from "picocolors";
|
|
9
9
|
import { fileURLToPath } from "url";
|
|
10
10
|
|
|
@@ -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);
|
|
@@ -173,6 +213,124 @@ async function checkApprovals(address) {
|
|
|
173
213
|
return { allApproved, details };
|
|
174
214
|
}
|
|
175
215
|
|
|
216
|
+
// src/wallet/onepassword.ts
|
|
217
|
+
import { execSync } from "child_process";
|
|
218
|
+
var WALLET_ITEM_PREFIX = "Polymarket Wallet";
|
|
219
|
+
function check1PasswordCli() {
|
|
220
|
+
try {
|
|
221
|
+
execSync("which op", { encoding: "utf8", stdio: "pipe" });
|
|
222
|
+
} catch {
|
|
223
|
+
return {
|
|
224
|
+
available: false,
|
|
225
|
+
authenticated: false,
|
|
226
|
+
error: "1Password CLI not installed. Install with: brew install --cask 1password-cli"
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
try {
|
|
230
|
+
execSync("op account list", { encoding: "utf8", stdio: "pipe" });
|
|
231
|
+
return { available: true, authenticated: true };
|
|
232
|
+
} catch {
|
|
233
|
+
return {
|
|
234
|
+
available: true,
|
|
235
|
+
authenticated: false,
|
|
236
|
+
error: "1Password CLI not authenticated. Enable app integration: Settings \u2192 Developer \u2192 Integrate with 1Password CLI"
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
async function storeIn1Password(name, credentials, vault = "Private") {
|
|
241
|
+
const itemName = `${WALLET_ITEM_PREFIX} - ${name}`;
|
|
242
|
+
try {
|
|
243
|
+
const fields = [
|
|
244
|
+
`address[text]=${credentials.address}`,
|
|
245
|
+
`private_key[password]=${credentials.privateKey}`,
|
|
246
|
+
`api_key[text]=${credentials.apiKey}`,
|
|
247
|
+
`api_secret[password]=${credentials.apiSecret}`,
|
|
248
|
+
`api_passphrase[password]=${credentials.apiPassphrase}`,
|
|
249
|
+
`created_at[text]=${(/* @__PURE__ */ new Date()).toISOString()}`
|
|
250
|
+
];
|
|
251
|
+
const cmd = [
|
|
252
|
+
"op",
|
|
253
|
+
"item",
|
|
254
|
+
"create",
|
|
255
|
+
"--category=Login",
|
|
256
|
+
`--title=${itemName}`,
|
|
257
|
+
`--vault=${vault}`,
|
|
258
|
+
...fields.map((f) => `"${f}"`)
|
|
259
|
+
].join(" ");
|
|
260
|
+
execSync(cmd, { encoding: "utf8", stdio: "pipe" });
|
|
261
|
+
return { itemName, success: true };
|
|
262
|
+
} catch (error) {
|
|
263
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
264
|
+
return { itemName, success: false, error: msg };
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
async function getFrom1Password(name) {
|
|
268
|
+
const itemName = `${WALLET_ITEM_PREFIX} - ${name}`;
|
|
269
|
+
try {
|
|
270
|
+
const output = execSync(
|
|
271
|
+
`op item get "${itemName}" --format json`,
|
|
272
|
+
{ encoding: "utf8", stdio: "pipe" }
|
|
273
|
+
);
|
|
274
|
+
const item = JSON.parse(output);
|
|
275
|
+
const fields = {};
|
|
276
|
+
for (const field of item.fields || []) {
|
|
277
|
+
if (field.label && field.value) {
|
|
278
|
+
fields[field.label] = field.value;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if (!fields.address || !fields.private_key) {
|
|
282
|
+
return { error: `Wallet "${itemName}" is missing required fields` };
|
|
283
|
+
}
|
|
284
|
+
return {
|
|
285
|
+
credentials: {
|
|
286
|
+
address: fields.address,
|
|
287
|
+
privateKey: fields.private_key,
|
|
288
|
+
apiKey: fields.api_key || "",
|
|
289
|
+
apiSecret: fields.api_secret || "",
|
|
290
|
+
apiPassphrase: fields.api_passphrase || ""
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
} catch (error) {
|
|
294
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
295
|
+
if (msg.includes("isn't an item")) {
|
|
296
|
+
return { error: `Wallet "${itemName}" not found in 1Password` };
|
|
297
|
+
}
|
|
298
|
+
return { error: msg };
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
function listWallets(vault) {
|
|
302
|
+
try {
|
|
303
|
+
const vaultArg = vault ? `--vault="${vault}"` : "";
|
|
304
|
+
const output = execSync(
|
|
305
|
+
`op item list --format json ${vaultArg}`,
|
|
306
|
+
{ encoding: "utf8", stdio: "pipe" }
|
|
307
|
+
);
|
|
308
|
+
const items = JSON.parse(output);
|
|
309
|
+
const wallets = [];
|
|
310
|
+
for (const item of items) {
|
|
311
|
+
if (item.title?.startsWith(WALLET_ITEM_PREFIX)) {
|
|
312
|
+
const name = item.title.replace(`${WALLET_ITEM_PREFIX} - `, "");
|
|
313
|
+
wallets.push(name);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return wallets;
|
|
317
|
+
} catch {
|
|
318
|
+
return [];
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
function getWalletAddress(name) {
|
|
322
|
+
const itemName = `${WALLET_ITEM_PREFIX} - ${name}`;
|
|
323
|
+
try {
|
|
324
|
+
const output = execSync(
|
|
325
|
+
`op item get "${itemName}" --fields address --reveal`,
|
|
326
|
+
{ encoding: "utf8", stdio: "pipe" }
|
|
327
|
+
);
|
|
328
|
+
return output.trim();
|
|
329
|
+
} catch {
|
|
330
|
+
return null;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
176
334
|
// src/index.ts
|
|
177
335
|
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
178
336
|
var TEMPLATE_DIR = path.resolve(__dirname, "..", "templates", "worker");
|
|
@@ -262,10 +420,10 @@ async function createStrategy(name, options) {
|
|
|
262
420
|
if (options.install) {
|
|
263
421
|
console.log(` ${pc.green("\u2713")} Installing dependencies...`);
|
|
264
422
|
try {
|
|
265
|
-
|
|
423
|
+
execSync2("pnpm install", { cwd: targetDir, stdio: "pipe" });
|
|
266
424
|
} catch {
|
|
267
425
|
try {
|
|
268
|
-
|
|
426
|
+
execSync2("npm install", { cwd: targetDir, stdio: "pipe" });
|
|
269
427
|
} catch {
|
|
270
428
|
console.log(
|
|
271
429
|
pc.yellow(" Could not install dependencies automatically.")
|
|
@@ -279,8 +437,8 @@ async function createStrategy(name, options) {
|
|
|
279
437
|
if (options.git) {
|
|
280
438
|
console.log(` ${pc.green("\u2713")} Initializing git repository...`);
|
|
281
439
|
try {
|
|
282
|
-
|
|
283
|
-
|
|
440
|
+
execSync2("git init", { cwd: targetDir, stdio: "pipe" });
|
|
441
|
+
execSync2("git add -A", { cwd: targetDir, stdio: "pipe" });
|
|
284
442
|
} catch {
|
|
285
443
|
console.log(pc.yellow(" Could not initialize git repository."));
|
|
286
444
|
}
|
|
@@ -296,10 +454,18 @@ async function createStrategy(name, options) {
|
|
|
296
454
|
console.log(pc.cyan(" wrangler deploy"));
|
|
297
455
|
console.log();
|
|
298
456
|
}
|
|
299
|
-
async function walletCreate() {
|
|
457
|
+
async function walletCreate(options) {
|
|
300
458
|
console.log();
|
|
301
459
|
console.log(pc.cyan("Creating new Polymarket wallet..."));
|
|
302
460
|
console.log();
|
|
461
|
+
if (options.store1password) {
|
|
462
|
+
const opStatus = check1PasswordCli();
|
|
463
|
+
if (!opStatus.available || !opStatus.authenticated) {
|
|
464
|
+
console.error(pc.red(`Error: ${opStatus.error}`));
|
|
465
|
+
process.exit(1);
|
|
466
|
+
}
|
|
467
|
+
console.log(` ${pc.green("\u2713")} 1Password CLI authenticated`);
|
|
468
|
+
}
|
|
303
469
|
console.log(` ${pc.yellow("\u2192")} Generating Ethereum wallet...`);
|
|
304
470
|
const wallet = generateWallet();
|
|
305
471
|
console.log(` ${pc.green("\u2713")} Address: ${pc.bold(wallet.address)}`);
|
|
@@ -307,16 +473,38 @@ async function walletCreate() {
|
|
|
307
473
|
try {
|
|
308
474
|
const apiCreds = await deriveApiCredentials(wallet.privateKey);
|
|
309
475
|
console.log(` ${pc.green("\u2713")} API credentials derived`);
|
|
476
|
+
const fullCreds = { ...wallet, ...apiCreds };
|
|
477
|
+
if (options.store1password && options.name) {
|
|
478
|
+
console.log(` ${pc.yellow("\u2192")} Storing in 1Password...`);
|
|
479
|
+
const result = await storeIn1Password(
|
|
480
|
+
options.name,
|
|
481
|
+
fullCreds,
|
|
482
|
+
options.vault || "Private"
|
|
483
|
+
);
|
|
484
|
+
if (result.success) {
|
|
485
|
+
console.log(` ${pc.green("\u2713")} Stored as "${result.itemName}"`);
|
|
486
|
+
} else {
|
|
487
|
+
console.error(pc.red(` \u2717 Failed to store: ${result.error}`));
|
|
488
|
+
}
|
|
489
|
+
}
|
|
310
490
|
console.log();
|
|
311
491
|
console.log(pc.cyan("\u2550".repeat(60)));
|
|
312
|
-
|
|
492
|
+
if (options.store1password && options.name) {
|
|
493
|
+
console.log(pc.bold("WALLET CREATED & STORED IN 1PASSWORD"));
|
|
494
|
+
} else {
|
|
495
|
+
console.log(pc.bold("SAVE THESE CREDENTIALS SECURELY"));
|
|
496
|
+
}
|
|
313
497
|
console.log(pc.cyan("\u2550".repeat(60)));
|
|
314
498
|
console.log();
|
|
315
499
|
console.log(`${pc.bold("Address:")} ${wallet.address}`);
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
500
|
+
if (!options.store1password) {
|
|
501
|
+
console.log(`${pc.bold("Private Key:")} ${wallet.privateKey}`);
|
|
502
|
+
console.log(`${pc.bold("API Key:")} ${apiCreds.apiKey}`);
|
|
503
|
+
console.log(`${pc.bold("API Secret:")} ${apiCreds.apiSecret}`);
|
|
504
|
+
console.log(`${pc.bold("API Passphrase:")} ${apiCreds.apiPassphrase}`);
|
|
505
|
+
} else {
|
|
506
|
+
console.log(pc.dim(" (credentials stored securely in 1Password)"));
|
|
507
|
+
}
|
|
320
508
|
console.log();
|
|
321
509
|
console.log(pc.cyan("\u2550".repeat(60)));
|
|
322
510
|
console.log();
|
|
@@ -329,13 +517,24 @@ async function walletCreate() {
|
|
|
329
517
|
console.log(` - Send ~1 POL for gas fees`);
|
|
330
518
|
console.log();
|
|
331
519
|
console.log(` 2. ${pc.yellow("Run on-chain setup:")}`);
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
520
|
+
if (options.store1password && options.name) {
|
|
521
|
+
console.log(
|
|
522
|
+
` npx create-polymarket-strategy wallet setup --from-1password ${options.name}`
|
|
523
|
+
);
|
|
524
|
+
} else {
|
|
525
|
+
console.log(
|
|
526
|
+
` npx create-polymarket-strategy wallet setup --private-key <key>`
|
|
527
|
+
);
|
|
528
|
+
}
|
|
335
529
|
console.log();
|
|
336
530
|
console.log(` 3. ${pc.yellow("Add secrets to your worker:")}`);
|
|
337
|
-
console.log(` wrangler secret put
|
|
531
|
+
console.log(` wrangler secret put WALLET_PRIVATE_KEY`);
|
|
338
532
|
console.log();
|
|
533
|
+
if (options.store1password && options.name) {
|
|
534
|
+
console.log(pc.dim(`To retrieve later:`));
|
|
535
|
+
console.log(pc.dim(` npx create-polymarket-strategy wallet get ${options.name}`));
|
|
536
|
+
console.log();
|
|
537
|
+
}
|
|
339
538
|
} catch (error) {
|
|
340
539
|
console.log(` ${pc.red("\u2717")} Failed to derive API credentials`);
|
|
341
540
|
console.log(
|
|
@@ -402,7 +601,80 @@ async function walletBalance(address) {
|
|
|
402
601
|
process.exit(1);
|
|
403
602
|
}
|
|
404
603
|
}
|
|
405
|
-
async function
|
|
604
|
+
async function walletGet(name) {
|
|
605
|
+
console.log();
|
|
606
|
+
console.log(pc.cyan(`Retrieving wallet "${name}" from 1Password...`));
|
|
607
|
+
console.log();
|
|
608
|
+
const opStatus = check1PasswordCli();
|
|
609
|
+
if (!opStatus.available || !opStatus.authenticated) {
|
|
610
|
+
console.error(pc.red(`Error: ${opStatus.error}`));
|
|
611
|
+
process.exit(1);
|
|
612
|
+
}
|
|
613
|
+
const result = await getFrom1Password(name);
|
|
614
|
+
if (result.error) {
|
|
615
|
+
console.error(pc.red(`Error: ${result.error}`));
|
|
616
|
+
process.exit(1);
|
|
617
|
+
}
|
|
618
|
+
const creds = result.credentials;
|
|
619
|
+
console.log(pc.cyan("\u2550".repeat(60)));
|
|
620
|
+
console.log(pc.bold(`${WALLET_ITEM_PREFIX} - ${name}`));
|
|
621
|
+
console.log(pc.cyan("\u2550".repeat(60)));
|
|
622
|
+
console.log();
|
|
623
|
+
console.log(`${pc.bold("Address:")} ${creds.address}`);
|
|
624
|
+
console.log(`${pc.bold("Private Key:")} ${creds.privateKey}`);
|
|
625
|
+
if (creds.apiKey) {
|
|
626
|
+
console.log(`${pc.bold("API Key:")} ${creds.apiKey}`);
|
|
627
|
+
console.log(`${pc.bold("API Secret:")} ${creds.apiSecret}`);
|
|
628
|
+
console.log(`${pc.bold("API Passphrase:")} ${creds.apiPassphrase}`);
|
|
629
|
+
}
|
|
630
|
+
console.log();
|
|
631
|
+
}
|
|
632
|
+
async function walletList() {
|
|
633
|
+
console.log();
|
|
634
|
+
console.log(pc.cyan("Listing Polymarket wallets in 1Password..."));
|
|
635
|
+
console.log();
|
|
636
|
+
const opStatus = check1PasswordCli();
|
|
637
|
+
if (!opStatus.available || !opStatus.authenticated) {
|
|
638
|
+
console.error(pc.red(`Error: ${opStatus.error}`));
|
|
639
|
+
process.exit(1);
|
|
640
|
+
}
|
|
641
|
+
const wallets = listWallets();
|
|
642
|
+
if (wallets.length === 0) {
|
|
643
|
+
console.log(pc.yellow("No Polymarket wallets found in 1Password."));
|
|
644
|
+
console.log();
|
|
645
|
+
console.log(pc.dim("Create one with:"));
|
|
646
|
+
console.log(pc.dim(" npx create-polymarket-strategy wallet create --name my-trader --store-1password"));
|
|
647
|
+
console.log();
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
650
|
+
console.log(pc.bold(`Found ${wallets.length} wallet(s):`));
|
|
651
|
+
console.log();
|
|
652
|
+
for (const name of wallets) {
|
|
653
|
+
const address = getWalletAddress(name);
|
|
654
|
+
console.log(` ${pc.cyan(name)}`);
|
|
655
|
+
console.log(` ${pc.dim(address || "address unavailable")}`);
|
|
656
|
+
}
|
|
657
|
+
console.log();
|
|
658
|
+
}
|
|
659
|
+
async function walletSetup(options) {
|
|
660
|
+
let privateKey = options.privateKey;
|
|
661
|
+
if (options.from1password) {
|
|
662
|
+
const opStatus = check1PasswordCli();
|
|
663
|
+
if (!opStatus.available || !opStatus.authenticated) {
|
|
664
|
+
console.error(pc.red(`Error: ${opStatus.error}`));
|
|
665
|
+
process.exit(1);
|
|
666
|
+
}
|
|
667
|
+
const result = await getFrom1Password(options.from1password);
|
|
668
|
+
if (result.error) {
|
|
669
|
+
console.error(pc.red(`Error: ${result.error}`));
|
|
670
|
+
process.exit(1);
|
|
671
|
+
}
|
|
672
|
+
privateKey = result.credentials.privateKey;
|
|
673
|
+
}
|
|
674
|
+
if (!privateKey) {
|
|
675
|
+
console.error(pc.red("Error: Either --private-key or --from-1password is required"));
|
|
676
|
+
process.exit(1);
|
|
677
|
+
}
|
|
406
678
|
console.log();
|
|
407
679
|
console.log(pc.cyan("Setting up wallet for Polymarket trading..."));
|
|
408
680
|
console.log();
|
|
@@ -413,7 +685,7 @@ async function walletSetup(privateKey) {
|
|
|
413
685
|
console.log(` ${pc.bold("Address:")} ${address}`);
|
|
414
686
|
console.log();
|
|
415
687
|
console.log(pc.yellow("Checking balances..."));
|
|
416
|
-
|
|
688
|
+
let balances = await getBalances(address);
|
|
417
689
|
console.log(` POL: ${balances.pol.toFixed(4)}`);
|
|
418
690
|
console.log(` USDC: $${balances.usdcNative.toFixed(2)}`);
|
|
419
691
|
console.log(` USDC.e: $${balances.usdcE.toFixed(2)}`);
|
|
@@ -424,15 +696,30 @@ async function walletSetup(privateKey) {
|
|
|
424
696
|
process.exit(1);
|
|
425
697
|
}
|
|
426
698
|
if (balances.usdcNative > 1 && balances.usdcE < 1) {
|
|
427
|
-
console.log(
|
|
428
|
-
|
|
429
|
-
"Note: You have native USDC but Polymarket requires USDC.e"
|
|
430
|
-
)
|
|
431
|
-
);
|
|
432
|
-
console.log(
|
|
433
|
-
pc.yellow("Use a DEX like Uniswap to swap USDC \u2192 USDC.e first")
|
|
434
|
-
);
|
|
699
|
+
console.log(pc.yellow("Swapping native USDC \u2192 USDC.e via Uniswap V3..."));
|
|
700
|
+
console.log(pc.dim("(Polymarket requires USDC.e, not native USDC)"));
|
|
435
701
|
console.log();
|
|
702
|
+
try {
|
|
703
|
+
const swapResult = await swapUsdcToUsdcE(
|
|
704
|
+
privateKey,
|
|
705
|
+
balances.usdcNative,
|
|
706
|
+
(msg) => {
|
|
707
|
+
console.log(` ${pc.yellow("\u2192")} ${msg}`);
|
|
708
|
+
}
|
|
709
|
+
);
|
|
710
|
+
console.log(
|
|
711
|
+
` ${pc.green("\u2713")} Swapped $${swapResult.amountIn.toFixed(2)} \u2192 $${swapResult.amountOut.toFixed(2)} USDC.e`
|
|
712
|
+
);
|
|
713
|
+
console.log(pc.dim(` Tx: ${swapResult.txHash}`));
|
|
714
|
+
console.log();
|
|
715
|
+
balances = await getBalances(address);
|
|
716
|
+
} catch (error) {
|
|
717
|
+
console.error(pc.red(` \u2717 Swap failed: ${error}`));
|
|
718
|
+
console.log(
|
|
719
|
+
pc.yellow(" You can manually swap at https://app.uniswap.org")
|
|
720
|
+
);
|
|
721
|
+
process.exit(1);
|
|
722
|
+
}
|
|
436
723
|
}
|
|
437
724
|
console.log(pc.yellow("Approving Polymarket exchange contracts..."));
|
|
438
725
|
console.log(
|
|
@@ -473,8 +760,10 @@ program.argument("[name]", "Project name").option("--no-git", "Skip git initiali
|
|
|
473
760
|
}
|
|
474
761
|
});
|
|
475
762
|
var walletCmd = program.command("wallet").description("Wallet management commands");
|
|
476
|
-
walletCmd.command("create").description("Create a new wallet and derive API credentials").action(walletCreate);
|
|
763
|
+
walletCmd.command("create").description("Create a new wallet and derive API credentials").option("--name <name>", "Trader/strategy name (required for 1Password storage)").option("--store-1password", "Store credentials in 1Password").option("--vault <vault>", "1Password vault name", "Private").action((options) => walletCreate(options));
|
|
477
764
|
walletCmd.command("balance").description("Check wallet balances").argument("<address>", "Wallet address").action(walletBalance);
|
|
478
|
-
walletCmd.command("setup").description("Approve exchange contracts for trading").
|
|
765
|
+
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));
|
|
766
|
+
walletCmd.command("get").description("Retrieve wallet credentials from 1Password").argument("<name>", "Trader/strategy name").action(walletGet);
|
|
767
|
+
walletCmd.command("list").description("List all Polymarket wallets in 1Password").action(walletList);
|
|
479
768
|
program.parse();
|
|
480
769
|
//# sourceMappingURL=index.js.map
|