From 85f19d0bd6264d37d92f17d1c78ce331f9a15045 Mon Sep 17 00:00:00 2001 From: direkturcrypto Date: Fri, 27 Mar 2026 13:55:35 +0700 Subject: [PATCH] fix: use regex matching in patch script + add geoblock IP check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rewrite patch-clob-client.cjs to use regex instead of exact string matching, so it works regardless of code formatting differences between npm versions (fixes "Could not find request config line" on fresh VPS install) - Add multiple fallback patterns (config regex → fallback regex → axios call injection) with debug output if all fail - Add Polymarket geoblock API check (polymarket.com/api/geoblock) for both VPS direct IP and proxy IP at startup Co-Authored-By: Claude Opus 4.6 --- scripts/patch-clob-client.cjs | 102 +++++++++++++++++++++++++++------- src/utils/proxy.js | 40 ++++++++++++- 2 files changed, 120 insertions(+), 22 deletions(-) diff --git a/scripts/patch-clob-client.cjs b/scripts/patch-clob-client.cjs index 4d66dc3..92c08e5 100644 --- a/scripts/patch-clob-client.cjs +++ b/scripts/patch-clob-client.cjs @@ -8,6 +8,9 @@ * - Adds HttpsProxyAgent import to http-helpers/index.js * - Injects proxy agent into every axios request to polymarket.com * - Reads PROXY_URL from process.env at runtime + * + * Uses regex matching so it works regardless of code formatting + * (minified, prettified, different whitespace, etc.) */ const fs = require('fs'); @@ -37,14 +40,8 @@ if (code.includes('getProxyAgent')) { process.exit(0); } -// Find the line after the axios import to inject proxy code -const AXIOS_IMPORT = `require("axios")`; -if (!code.includes(AXIOS_IMPORT)) { - console.error('[patch] Could not find axios import in http-helpers — skipping'); - process.exit(0); -} +// ── Step 1: Inject proxy helper code ──────────────────────────────────────── -// Inject proxy imports and helper after axios import line const PROXY_CODE = ` // Proxy support for Polymarket API (auto-patched by scripts/patch-clob-client.cjs) const https_proxy_agent_1 = require("https-proxy-agent"); @@ -53,20 +50,45 @@ const getProxyAgent = () => { return new https_proxy_agent_1.HttpsProxyAgent(process.env.PROXY_URL); } return undefined; -};`; +}; +`; -// Insert after the browser_or_node require line -const INSERT_AFTER = `require("browser-or-node");`; -if (!code.includes(INSERT_AFTER)) { - console.error('[patch] Could not find browser-or-node import — skipping'); +// Try multiple insertion points — different versions format differently +const insertionPatterns = [ + // Pattern 1: require("browser-or-node") with semicolon + /require\s*\(\s*["']browser-or-node["']\s*\)\s*;/, + // Pattern 2: require("axios") line (fallback) + /require\s*\(\s*["']axios["']\s*\)\s*;/, + // Pattern 3: any require line near the top (last resort) + /const\s+\w+\s*=\s*require\s*\(\s*["']axios["']\s*\)/, +]; + +let inserted = false; +for (const pattern of insertionPatterns) { + const match = code.match(pattern); + if (match) { + code = code.replace(match[0], match[0] + PROXY_CODE); + console.log(`[patch] Injected proxy helper after: ${match[0].substring(0, 50)}...`); + inserted = true; + break; + } +} + +if (!inserted) { + console.error('[patch] Could not find insertion point for proxy code — skipping'); process.exit(0); } -code = code.replace(INSERT_AFTER, INSERT_AFTER + PROXY_CODE); +// ── Step 2: Patch the request config to inject proxy agent ────────────────── -// Patch the request function to inject proxy agent -const REQUEST_CONFIG = `const config = { method, url: endpoint, headers, data, params };`; -const PATCHED_CONFIG = `const config = { method, url: endpoint, headers, data, params }; +// Match: const config = { method, url: endpoint, headers, data, params } +// with any whitespace variation (spaces, newlines, tabs) +const configRegex = /const\s+config\s*=\s*\{\s*method\s*,\s*url\s*:\s*endpoint\s*,\s*headers\s*,\s*data\s*,\s*params\s*\}\s*;/; + +const configMatch = code.match(configRegex); + +if (configMatch) { + const PROXY_INJECT = `${configMatch[0]} // Add proxy agent for Polymarket API if (endpoint && endpoint.includes('polymarket.com')) { const agent = getProxyAgent(); @@ -75,13 +97,51 @@ const PATCHED_CONFIG = `const config = { method, url: endpoint, headers, data, p config.proxy = false; } }`; + code = code.replace(configMatch[0], PROXY_INJECT); + console.log('[patch] Injected proxy agent into request config'); +} else { + // Fallback: try to find any config object creation with method/endpoint + // and inject proxy after it + const fallbackRegex = /(?:const|let|var)\s+config\s*=\s*\{[^}]*method[^}]*endpoint[^}]*\}\s*;/; + const fallbackMatch = code.match(fallbackRegex); -if (!code.includes(REQUEST_CONFIG)) { - console.error('[patch] Could not find request config line — skipping'); - process.exit(0); + if (fallbackMatch) { + const PROXY_INJECT = `${fallbackMatch[0]} + // Add proxy agent for Polymarket API + if (endpoint && endpoint.includes('polymarket.com')) { + const agent = getProxyAgent(); + if (agent) { + config.httpsAgent = agent; + config.proxy = false; + } + }`; + code = code.replace(fallbackMatch[0], PROXY_INJECT); + console.log('[patch] Injected proxy agent into request config (fallback match)'); + } else { + // Last resort: find the axios request/call and inject before it + const axiosCallRegex = /axios_1\.default\s*\(\s*config\s*\)/; + const axiosMatch = code.match(axiosCallRegex); + + if (axiosMatch) { + const PROXY_INJECT = `// Add proxy agent for Polymarket API + if (config.url && config.url.includes('polymarket.com')) { + const agent = getProxyAgent(); + if (agent) { + config.httpsAgent = agent; + config.proxy = false; + } + } + ${axiosMatch[0]}`; + code = code.replace(axiosMatch[0], PROXY_INJECT); + console.log('[patch] Injected proxy agent before axios call (last resort)'); + } else { + console.error('[patch] Could not find request config or axios call — skipping'); + console.error('[patch] File content preview (first 2000 chars):'); + console.error(code.substring(0, 2000)); + process.exit(0); + } + } } -code = code.replace(REQUEST_CONFIG, PATCHED_CONFIG); - fs.writeFileSync(TARGET, code, 'utf8'); console.log('[patch] @polymarket/clob-client patched with proxy support ✅'); diff --git a/src/utils/proxy.js b/src/utils/proxy.js index 2520214..aac93de 100644 --- a/src/utils/proxy.js +++ b/src/utils/proxy.js @@ -86,6 +86,7 @@ export async function proxyFetch(url, opts = {}) { */ async function checkOutboundIP() { const IP_SERVICE = 'https://api.ipify.org?format=json'; + const GEOBLOCK_API = 'https://polymarket.com/api/geoblock'; // 1. Check VPS direct IP try { @@ -98,7 +99,22 @@ async function checkOutboundIP() { logger.warn('Could not detect VPS direct IP'); } - // 2. Check proxied IP (what Polymarket will see) + // 2. Check if VPS direct IP is geoblocked + try { + const geoResp = await fetch(GEOBLOCK_API, { signal: AbortSignal.timeout(10000) }); + if (geoResp.ok) { + const geo = await geoResp.json(); + if (geo.blocked) { + logger.warn(`VPS direct IP GEOBLOCKED — country: ${geo.country}, region: ${geo.region}`); + } else { + logger.info(`VPS direct IP NOT geoblocked — country: ${geo.country}`); + } + } + } catch { + logger.warn('Could not check VPS geoblock status'); + } + + // 3. Check proxied IP (what Polymarket will see) if (fetchDispatcher) { try { const proxyResp = await fetch(IP_SERVICE, { @@ -112,6 +128,28 @@ async function checkOutboundIP() { } catch { logger.warn('Could not detect proxy IP — proxy may not be working'); } + + // 4. Check if proxy IP is geoblocked + try { + const geoResp = await fetch(GEOBLOCK_API, { + dispatcher: fetchDispatcher, + signal: AbortSignal.timeout(10000), + }); + if (geoResp.ok) { + const geo = await geoResp.json(); + if (geo.blocked) { + logger.error('═══════════════════════════════════════════════════'); + logger.error(`PROXY IP GEOBLOCKED by Polymarket!`); + logger.error(`IP: ${geo.ip} | Country: ${geo.country} | Region: ${geo.region}`); + logger.error('Change PROXY_URL in .env to a proxy in an allowed region.'); + logger.error('═══════════════════════════════════════════════════'); + } else { + logger.success(`Proxy IP NOT geoblocked — country: ${geo.country} ✓`); + } + } + } catch { + logger.warn('Could not check proxy geoblock status'); + } } }