-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetup.mjs
More file actions
187 lines (160 loc) · 7.37 KB
/
setup.mjs
File metadata and controls
187 lines (160 loc) · 7.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#!/usr/bin/env node
/**
* Polymarket Trading Setup Script
*
* Diagnoses and fixes the proxy wallet configuration:
* 1. Checks on-chain balances (USDC, POL)
* 2. Determines correct SIGNATURE_TYPE (EOA vs POLY_PROXY)
* 3. Checks CLOB balance/allowance
* 4. Calls updateBalanceAllowance to sync
* 5. If USDC present + allowance missing, approves exchange contracts
*
* Usage:
* node setup.mjs # Full diagnostic
* node setup.mjs approve # Set USDC allowances (needs POL for gas)
*/
import "dotenv/config";
import { ClobClient } from "@polymarket/clob-client";
import { Wallet } from "@ethersproject/wallet";
import { JsonRpcProvider } from "@ethersproject/providers";
import { Contract } from "@ethersproject/contracts";
const POLYGON_RPC = "https://polygon-bor-rpc.publicnode.com";
const CLOB_HOST = "https://clob.polymarket.com";
const CHAIN_ID = 137;
// Polymarket contracts on Polygon
const USDC = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174";
const EXCHANGE = "0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E";
const NEG_RISK_EXCHANGE = "0xC5d563A36AE78145C45a50134d48A1215220f80a";
const NEG_RISK_ADAPTER = "0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296";
const CTF = "0x4D97DCd97eC945f40cF65F87097ACe5EA0476045";
const MAX_ALLOWANCE = "115792089237316195423570985008687907853269984665640564039457584007913129639935";
const ERC20_ABI = [
"function balanceOf(address) view returns (uint256)",
"function allowance(address owner, address spender) view returns (uint256)",
"function approve(address spender, uint256 amount) returns (bool)",
"function decimals() view returns (uint8)",
];
const ERC1155_ABI = [
"function isApprovedForAll(address account, address operator) view returns (bool)",
"function setApprovalForAll(address operator, bool approved)",
];
const PRIVATE_KEY = process.env.PRIVATE_KEY || "";
const FUNDER_ADDRESS = process.env.FUNDER_ADDRESS || "";
const SIGNATURE_TYPE = parseInt(process.env.SIGNATURE_TYPE || "0", 10);
async function main() {
const command = process.argv[2] || "diagnose";
const provider = new JsonRpcProvider(POLYGON_RPC);
const signer = new Wallet(PRIVATE_KEY, provider);
const eoaAddress = signer.address;
console.log("=== Polymarket Trading Setup ===\n");
console.log(`EOA address: ${eoaAddress}`);
console.log(`Funder address: ${FUNDER_ADDRESS || "(not set)"}`);
console.log(`Signature type: ${SIGNATURE_TYPE} (${["EOA", "POLY_PROXY", "POLY_GNOSIS_SAFE"][SIGNATURE_TYPE]})`);
// 1. Check on-chain balances
console.log("\n--- On-chain Balances ---");
const usdc = new Contract(USDC, ERC20_ABI, provider);
const eoaPol = await provider.getBalance(eoaAddress);
const eoaUsdc = await usdc.balanceOf(eoaAddress);
console.log(`EOA: ${(Number(eoaPol) / 1e18).toFixed(6)} POL, ${(Number(eoaUsdc) / 1e6).toFixed(6)} USDC`);
let proxyUsdc = BigInt(0);
if (FUNDER_ADDRESS) {
const proxyPol = await provider.getBalance(FUNDER_ADDRESS);
proxyUsdc = BigInt((await usdc.balanceOf(FUNDER_ADDRESS)).toString());
console.log(`Proxy: ${(Number(proxyPol) / 1e18).toFixed(6)} POL, ${(Number(proxyUsdc) / 1e6).toFixed(6)} USDC`);
}
// Determine which wallet has funds
const eoaHasFunds = Number(eoaUsdc) > 0;
const proxyHasFunds = Number(proxyUsdc) > 0;
const hasGas = Number(eoaPol) > 0;
// 2. Check CLOB balance
console.log("\n--- CLOB API Balance ---");
try {
const tempClient = new ClobClient(CLOB_HOST, CHAIN_ID, signer);
const creds = await tempClient.createOrDeriveApiKey();
const client = new ClobClient(
CLOB_HOST, CHAIN_ID, signer, creds,
SIGNATURE_TYPE,
FUNDER_ADDRESS || undefined,
);
const ba = await client.getBalanceAllowance({ asset_type: "COLLATERAL" });
console.log(`CLOB balance: ${ba.balance} (raw units)`);
console.log(`CLOB allowances:`);
for (const [addr, val] of Object.entries(ba.allowances)) {
const label = addr === EXCHANGE ? "Exchange" : addr === NEG_RISK_EXCHANGE ? "NegRiskExchange" : addr === NEG_RISK_ADAPTER ? "NegRiskAdapter" : addr;
console.log(` ${label}: ${val}`);
}
// Try to update/sync
await client.updateBalanceAllowance({ asset_type: "COLLATERAL" });
console.log("(Balance allowance sync requested)");
} catch (e) {
console.log(`CLOB error: ${e.message}`);
}
// 3. Check on-chain allowances
const checkAddr = FUNDER_ADDRESS || eoaAddress;
console.log(`\n--- On-chain Allowances for ${checkAddr} ---`);
const ctf = new Contract(CTF, ERC1155_ABI, provider);
for (const [name, addr] of [["Exchange", EXCHANGE], ["NegRiskExchange", NEG_RISK_EXCHANGE], ["NegRiskAdapter", NEG_RISK_ADAPTER]]) {
const usdcAllowance = await usdc.allowance(checkAddr, addr);
const ctfApproved = await ctf.isApprovedForAll(checkAddr, addr);
console.log(` ${name}: USDC=${(Number(usdcAllowance) / 1e6).toFixed(2)}, CTF=${ctfApproved}`);
}
// 4. Report issues and recommendations
console.log("\n--- Diagnosis ---");
const issues = [];
if (!eoaHasFunds && !proxyHasFunds) {
issues.push("NO USDC found in either EOA or proxy wallet on Polygon!");
issues.push(` → Deposit USDC.e to EOA: ${eoaAddress}`);
if (FUNDER_ADDRESS) {
issues.push(` → Or deposit through Polymarket UI to proxy: ${FUNDER_ADDRESS}`);
}
}
if (!hasGas) {
issues.push("EOA has 0 POL — cannot pay gas for approval transactions");
issues.push(` → Send 0.1 POL to: ${eoaAddress}`);
}
if (FUNDER_ADDRESS && SIGNATURE_TYPE !== 1) {
issues.push("FUNDER_ADDRESS is set but SIGNATURE_TYPE is not 1 (POLY_PROXY)");
issues.push(" → Set SIGNATURE_TYPE=1 in .env, OR remove FUNDER_ADDRESS");
}
if (issues.length === 0) {
console.log("No issues found! Configuration looks correct.");
} else {
for (const issue of issues) {
console.log(`⚠ ${issue}`);
}
}
// 5. If "approve" command and we have gas, set up allowances
if (command === "approve") {
if (!hasGas) {
console.log("\n❌ Cannot approve: EOA has no POL for gas.");
console.log(` Send some POL to ${eoaAddress} first.`);
return;
}
console.log("\n--- Setting up USDC + CTF Approvals ---");
const usdcWrite = new Contract(USDC, ERC20_ABI, signer);
const ctfWrite = new Contract(CTF, ERC1155_ABI, signer);
// Note: for proxy wallets, approvals need to go through the proxy contract
// For EOA mode (no funder), approvals are from the EOA directly
if (!FUNDER_ADDRESS || FUNDER_ADDRESS.toLowerCase() === eoaAddress.toLowerCase()) {
// EOA mode: approve directly
for (const [name, addr] of [["Exchange", EXCHANGE], ["NegRiskExchange", NEG_RISK_EXCHANGE], ["NegRiskAdapter", NEG_RISK_ADAPTER]]) {
console.log(`Approving USDC for ${name}...`);
const tx = await usdcWrite.approve(addr, MAX_ALLOWANCE);
console.log(` TX: ${tx.hash}`);
await tx.wait();
console.log(` Confirmed!`);
console.log(`Approving CTF for ${name}...`);
const tx2 = await ctfWrite.setApprovalForAll(addr, true);
console.log(` TX: ${tx2.hash}`);
await tx2.wait();
console.log(` Confirmed!`);
}
console.log("\n✓ All approvals set!");
} else {
console.log("Proxy wallet approvals need to be done through Polymarket's system.");
console.log("The CLOB's updateBalanceAllowance should handle this.");
console.log("If deposits are done through Polymarket UI, approvals are automatic.");
}
}
}
main().catch(console.error);