diff --git a/polymarket.db b/polymarket.db index 33dd4973c..27ee3b8ff 100644 Binary files a/polymarket.db and b/polymarket.db differ diff --git a/polymarket/检查usdc.py b/polymarket/检查usdc.py new file mode 100644 index 000000000..65c038b1e --- /dev/null +++ b/polymarket/检查usdc.py @@ -0,0 +1,32 @@ +from web3 import Web3 + +RPC_URL = "https://polygon-rpc.com" +MY_ADDRESS = "0xADcA20376A6CdCBd232577ac830F4116eC863DcF" + +# 两个不同的 USDC 地址 +USDC_E_ADDR = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174" # 桥接版 (Polymarket用这个) +USDC_NATIVE_ADDR = "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359" # 原生版 + +w3 = Web3(Web3.HTTPProvider(RPC_URL)) +abi = [{"constant": True, "inputs": [{"name": "_owner", "type": "address"}], "name": "balanceOf", + "outputs": [{"name": "balance", "type": "uint256"}], "type": "function"}] + + +def check(): + # 检查 USDC.e + c_e = w3.eth.contract(address=w3.to_checksum_address(USDC_E_ADDR), abi=abi) + bal_e = c_e.functions.balanceOf(MY_ADDRESS).call() / 1e6 + + # 检查 原生 USDC + c_n = w3.eth.contract(address=w3.to_checksum_address(USDC_NATIVE_ADDR), abi=abi) + bal_n = c_n.functions.balanceOf(MY_ADDRESS).call() / 1e6 + + print(f"💰 桥接版 USDC.e (旧): {bal_e} USDC") + print(f"💰 原生版 USDC (新): {bal_n} USDC") + + if bal_n > 0 and bal_e == 0: + print("\n⚠️ 发现原因:你的 USDC 是新版原生币,Polymarket 不支持!") + print("💡 解决方法:在 OKX 钱包里使用 Swap 功能,把 USDC 兑换成 USDC.e") + + +check() \ No newline at end of file diff --git a/polymarket/获取当前持仓.py b/polymarket/获取当前持仓.py new file mode 100644 index 000000000..dd74ed650 --- /dev/null +++ b/polymarket/获取当前持仓.py @@ -0,0 +1,63 @@ +import requests + +# --- 配置 --- +ADDRESS = "0xADcA20376A6CdCBd232577ac830F4116eC863DcF" +# Polygonscan API (使用公共接口) +POLYGONSCAN_API = "https://api.polygonscan.com/api" + + +def diagnose_wallet(addr): + print(f"探针启动: 正在扫描地址 {addr}\n") + + # 1. 检查 USDC.e 余额 (Polymarket 必须资产) + # USDC.e 合约地址: 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174 + usdc_contract = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174" + + params = { + "module": "account", + "action": "tokenbalance", + "contractaddress": usdc_contract, + "address": addr, + "tag": "latest" + } + + try: + r = requests.get(POLYGONSCAN_API, params=params).json() + balance = int(r.get('result', 0)) / 1e6 + print(f"💵 当前 USDC.e 余额: {balance:.2f} USD") + if balance < 1: + print("⚠️ 警告: 余额不足 1 美元,之前的买入操作极大概率失败了。") + except: + print("❌ 无法获取 USDC 余额") + + # 2. 检查最近的交易记录 + print("\n--- 最近 5 条链上交易记录 ---") + tx_params = { + "module": "account", + "action": "tokentx", + "address": addr, + "startblock": 0, + "endblock": 99999999, + "page": 1, + "offset": 5, + "sort": "desc" + } + + try: + r = requests.get(POLYGONSCAN_API, params=tx_params).json() + txs = r.get('result', []) + if not txs or isinstance(txs, str): + print("📭 链上查无交易。结论: 之前的买入脚本未能在链上发出任何指令。") + else: + for tx in txs: + print(f"🕒 时间: {tx.get('timeStamp')}") + print( + f"📦 代币: {tx.get('tokenSymbol')} | 数量: {int(tx.get('value')) / 10 ** int(tx.get('tokenDecimal')):.2f}") + print(f"🔗 Hash: {tx.get('hash')[:20]}...") + print("-" * 20) + except: + print("❌ 无法获取交易记录") + + +if __name__ == "__main__": + diagnose_wallet(ADDRESS) \ No newline at end of file diff --git a/polymarket/获取私钥.py b/polymarket/获取私钥.py new file mode 100644 index 000000000..08eab3187 --- /dev/null +++ b/polymarket/获取私钥.py @@ -0,0 +1,33 @@ +from eth_account import Account + +# 启用助记词功能 +Account.enable_unaudited_hdwallet_features() + +# 在此处填入你的 12 或 24 个助记词(用空格隔开) +mnemonic = "material vapor okay save company news village license head slogan sadness wire" + +# OKX 钱包/Metamask 第一个账户的标准路径 +path = "m/44'/60'/0'/0/0" + +try: + # 从助记词生成账户 + acct = Account.from_mnemonic(mnemonic, account_path=path) + + print("-" * 30) + print(f"✅ 钱包地址: {acct.address}") + print(f"🔑 私钥 (Private Key): {acct.key.hex()}") + print("-" * 30) + + # 验证地址是否匹配 + target_address = "0xADcA20376A6CdCBd232577ac830F4116eC863DcF" + if acct.address.lower() == target_address.lower(): + print("🎉 地址匹配成功!这就是你在 Polymarket 使用的账户。") + print("请复制上面的【私钥】用于后续操作。") + else: + print(f"⚠️ 地址不匹配!") + print(f"脚本计算出的地址: {acct.address}") + print(f"Polymarket 日志中的地址: {target_address}") + print("可能是路径不同,或者是 OKX 钱包的第2/3个账户?") + +except Exception as e: + print(f"❌ 错误: {e}") \ No newline at end of file diff --git a/polymarket/购买.py b/polymarket/购买.py new file mode 100644 index 000000000..c236a7abc --- /dev/null +++ b/polymarket/购买.py @@ -0,0 +1,220 @@ +import sys +import json +import requests +import math +from urllib.parse import urlparse +from eth_account import Account +from py_clob_client.client import ClobClient +from py_clob_client.clob_types import OrderArgs + +# 启用助记词功能 +Account.enable_unaudited_hdwallet_features() + +# --- 配置区域 --- +GAMMA_API = "https://gamma-api.polymarket.com" +HOST = "https://clob.polymarket.com" +CHAIN_ID = 137 # Polygon Mainnet + + +def parse_jsonish_list(v): + if v is None: + return [] + if isinstance(v, list): + return v + if isinstance(v, str): + s = v.strip() + if s.startswith("[") and s.endswith("]"): + try: + return json.loads(s) + except json.JSONDecodeError: + return [x.strip().strip("'").strip('"') for x in s[1:-1].split(",") if x.strip()] + return [x.strip() for x in s.split(",") if x.strip()] + return [] + + +class PolymarketTrader: + def __init__(self, mnemonic): + try: + self.acct = Account.from_mnemonic(mnemonic) + self.private_key = self.acct.key.hex() + self.address = self.acct.address + print(f"✅ 钱包已加载: {self.address}") + except Exception as e: + print(f"❌ 助记词格式错误: {e}") + sys.exit(1) + self.client = None + + def init_client(self): + try: + self.client = ClobClient( + host=HOST, + key=self.private_key, + chain_id=CHAIN_ID + ) + self.client.set_api_creds(self.client.create_or_derive_api_creds()) + print("✅ Polymarket API 登录成功") + except Exception as e: + print(f"❌ 登录失败: {e}") + sys.exit(1) + + def resolve_market(self, url, direction): + parsed_url = urlparse(url) + try: + slug = parsed_url.path.split("event/")[-1].strip("/") + slug = slug.split("?")[0] + except IndexError: + raise ValueError("无效的 URL 格式") + + print(f"🔍 解析 Slug: {slug}") + resp = requests.get(f"{GAMMA_API}/events", params={"slug": slug}) + if resp.status_code != 200: + raise ValueError(f"API 请求失败: {resp.status_code}") + + data = resp.json() + if not data: + raise ValueError("未找到该预测事件") + + target_market = data[0].get('markets', [])[0] + # 尝试找活跃的 + for m in data[0].get('markets', []): + if m.get('active'): + target_market = m + break + + outcomes = [str(x) for x in parse_jsonish_list(target_market.get("outcomes"))] + token_ids = [str(x) for x in parse_jsonish_list(target_market.get("clobTokenIds"))] + + token_map = dict(zip(outcomes, token_ids)) + print(f"📋 选项映射: {token_map.keys()}") + + target_token_id = token_map.get(direction) + if not target_token_id: + # 尝试常见变体 + if direction == "Up": + target_token_id = token_map.get("Yes") + elif direction == "Down": + target_token_id = token_map.get("No") + elif direction == "Yes": + target_token_id = token_map.get("Up") + elif direction == "No": + target_token_id = token_map.get("Down") + + if not target_token_id: + raise ValueError(f"方向 '{direction}' 无效。可选: {list(token_map.keys())}") + + return { + "token_id": target_token_id, + "question": target_market.get('question'), + "outcome": direction + } + + def buy(self, url, amount_usd, direction): + if not self.client: + self.init_client() + + print(f"\n🚀 开始分析: {url}") + + try: + market_data = self.resolve_market(url, direction) + token_id = market_data['token_id'] + + print(f"✅ 成功锁定 Token ID: {token_id[:10]}...{token_id[-10:]}") + print(f"🎯 预测问题: {market_data['question']}") + print(f"👉 购买方向: {market_data['outcome']}") + + # 获取盘口价格 + orderbook = self.client.get_order_book(token_id) + if not orderbook.asks: + print("❌ 市场暂无卖单") + return + + best_ask = float(orderbook.asks[0].price) + + # 设定买入价:稍微高一点以确保成交,但限制最高价 + exec_price = min(best_ask * 1.05, 0.99) + + # --- [核心修复逻辑] --- + # 问题:当价格为 0.99 时,1/0.99 = 1.0101... + # 如果系统截断为 1.01,则 1.01 * 0.99 = 0.9999 (小于 $1,报错) + # 修复:乘以 1.05 (5% 缓冲),并保留 2 位小数 + # 结果:1.0101 * 1.05 = 1.0606 -> round -> 1.06 + # 验证:1.06 * 0.99 = 1.0494 (大于 $1,成功) + + raw_quantity = (amount_usd / exec_price) * 1.05 + quantity = round(raw_quantity, 2) + + # 如果计算出来还是太小(极低概率),强制加 0.01 + if quantity * exec_price < 1.0: + quantity += 0.01 + + print(f"💰 当前卖一价: {best_ask} | 设定买入价: {exec_price:.3f}") + print(f"🛒 准备下单: ${amount_usd} (修正后数量: {quantity}, 预计总值: ${quantity * exec_price:.4f})") + + order_args = OrderArgs( + price=exec_price, + size=quantity, + side="BUY", + token_id=token_id, + ) + + print("📡 发送订单...") + resp = self.client.create_and_post_order(order_args) + + if resp and resp.get("success"): + print("✅ 购买成功!") + print(f"🆔 Order ID: {resp.get('orderID')}") + print(f"🔗 Transaction: {resp.get('transactionHash')}") + else: + print(f"⚠️ 下单回执: {resp}") + + except Exception as e: + print(f"❌ 发生错误: {e}") + import traceback + traceback.print_exc() + + def get_orders(self): + if not self.client: + self.init_client() + + print(f"\n📜 获取历史订单...") + + try: + # 获取用户的所有订单 + orders = self.client.get_orders() + print(orders) + if not orders: + print("❌ 未找到任何历史订单") + return + + print(f"📊 共 {len(orders)} 个订单") + for order in orders: + print(f"📝 订单ID: {order['orderID']}") + print(f" 状态: {order['status']}") + print(f" 方向: {order['side']}") + print(f" 价格: {order['price']}") + print(f" 数量: {order['size']}") + print(f" 创建时间: {order['createdAt']}") + print("--------") + + except Exception as e: + print(f"❌ 获取订单时出错: {e}") + import traceback + traceback.print_exc() + + +if __name__ == "__main__": + # 请填入你的助记词 + MNEMONIC = "material vapor okay save company news village license head slogan sadness wire" + + # 目标 URL + TARGET_URL = "https://polymarket.com/event/eth-updown-15m-1767457800?tid=1767458315299" + + # # 金额 (输入 1 即可) + # AMOUNT = 1 + + # # 方向+ + # DIRECTION = "Down" + + trader = PolymarketTrader(MNEMONIC) + print(trader.get_orders()) + # trader.buy(TARGET_URL, AMOUNT, DIRECTION) diff --git a/polymarket/购买1.0.py b/polymarket/购买1.0.py new file mode 100644 index 000000000..7592e6526 --- /dev/null +++ b/polymarket/购买1.0.py @@ -0,0 +1,131 @@ +import sys +import json +import requests +from urllib.parse import urlparse +from eth_account import Account +from py_clob_client.client import ClobClient +from py_clob_client.clob_types import MarketOrderArgs + +# 启用助记词功能 +Account.enable_unaudited_hdwallet_features() + +# --- 配置区域 --- +GAMMA_API = "https://gamma-api.polymarket.com" +HOST = "https://clob.polymarket.com" +CHAIN_ID = 137 + + +def parse_jsonish_list(v): + if v is None: return [] + if isinstance(v, list): return v + if isinstance(v, str): + s = v.strip() + if s.startswith("[") and s.endswith("]"): + try: + return json.loads(s) + except: + pass + return [x.strip() for x in s.split(",") if x.strip()] + return [] + + +class PolymarketTrader: + def __init__(self, mnemonic): + try: + self.acct = Account.from_mnemonic(mnemonic) + self.private_key = self.acct.key.hex() + self.address = self.acct.address + print(f"✅ 钱包已加载: {self.address}") + except Exception as e: + print(f"❌ 助记词错误: {e}") + sys.exit(1) + self.client = None + + def init_client(self): + try: + self.client = ClobClient(host=HOST, key=self.private_key, chain_id=CHAIN_ID) + self.client.set_api_creds(self.client.create_or_derive_api_creds()) + print("✅ Polymarket API 登录成功") + except Exception as e: + print(f"❌ 登录失败: {e}") + sys.exit(1) + + def resolve_market(self, url, direction): + parsed_url = urlparse(url) + try: + slug = parsed_url.path.split("event/")[-1].split("?")[0].strip("/") + except: + raise ValueError("无效 URL") + + print(f"🔍 解析 Slug: {slug}") + resp = requests.get(f"{GAMMA_API}/events", params={"slug": slug}) + data = resp.json() + if not data: raise ValueError("未找到市场") + + target_market = data[0].get('markets', [])[0] + for m in data[0].get('markets', []): + if m.get('active'): + target_market = m + break + + outcomes = [str(x) for x in parse_jsonish_list(target_market.get("outcomes"))] + token_ids = [str(x) for x in parse_jsonish_list(target_market.get("clobTokenIds"))] + token_map = dict(zip(outcomes, token_ids)) + + target_token_id = token_map.get(direction) + if not target_token_id: + alt = {"Up": "Yes", "Down": "No", "Yes": "Up", "No": "Down"} + target_token_id = token_map.get(alt.get(direction)) + + return {"token_id": target_token_id, "question": target_market.get('question')} + + def buy(self, url, amount_usd, direction): + if not self.client: self.init_client() + + try: + market_data = self.resolve_market(url, direction) + token_id = market_data['token_id'] + + # 获取当前卖一价,作为参考,设置一个合理的滑点保护价 + orderbook = self.client.get_order_book(token_id) + if not orderbook.asks: + print("❌ 市场无卖单") + return + best_ask = float(orderbook.asks[0].price) + + # 对于市价单,price 参数通常充当 Limit Price (最高愿意支付的价格) + # 设置为比卖一高 5%,但不超过 0.99 + limit_price = min(round(best_ask * 1.05, 2), 0.99) + + print(f"🎯 目标: {market_data['question']}") + print(f"💰 投入金额: ${amount_usd} | 最高接受价格: {limit_price}") + + # --- 根据你提供的类定义进行匹配 --- + order_args = MarketOrderArgs( + token_id=token_id, + amount=float(amount_usd), # BUY 订单这里填美元金额 + side="BUY", + price=limit_price # 设置滑点保护价 + ) + + print("📡 发送市价买入订单...") + resp = self.client.create_and_post_order(order_args) + + if resp and resp.get("success"): + print("✅ 购买成功!") + print(f"🆔 Order ID: {resp.get('orderID')}") + else: + print(f"⚠️ 下单响应: {resp}") + + except Exception as e: + print(f"❌ 执行失败: {e}") + + +if __name__ == "__main__": + MNEMONIC = "material vapor okay save company news village license head slogan sadness wire" + TARGET_URL = "https://polymarket.com/event/eth-updown-15m-1767457800?tid=1767458315299" + AMOUNT_USD = 1.05 # 建议略高于1,防止因手续费导致不满1元报错 + DIRECTION = "Up" + + trader = PolymarketTrader(MNEMONIC) + trader.buy(TARGET_URL, AMOUNT_USD, DIRECTION) diff --git a/polymarket/钱包授权.py b/polymarket/钱包授权.py new file mode 100644 index 000000000..ea7620dbd --- /dev/null +++ b/polymarket/钱包授权.py @@ -0,0 +1,111 @@ +from web3 import Web3 +import time + +# ================= 配置区 ================= +# 1. 填入你提取出的私钥 (以 0x 开头) +PRIVATE_KEY = "0xb759f8d56102c2e932d968c9a64fa79e8645fd5c28bef737c218ae3f3a13c480" + +# 2. Polygon RPC 节点 (如果失效可以换成 https://polygon.drpc.org) +RPC_URL = "https://polygon-rpc.com" + +# 3. 相关合约地址 (Polygon 网络) +USDC_ADDRESS = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174" # 官方 USDC (Bridged) +CLOB_EXCHANGE = "0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E" # Polymarket 交易授权合约 + + +# ========================================= + +def manual_approve(): + # 连接网络 + w3 = Web3(Web3.HTTPProvider(RPC_URL)) + + if not w3.is_connected(): + print("❌ 无法连接到 Polygon 网络,请检查网络或代理设置。") + return + + try: + # 加载账户 + account = w3.eth.account.from_key(PRIVATE_KEY) + my_address = account.address + print(f"👤 钱包地址: {my_address}") + + # 1. 检查 MATIC 余额 + balance = w3.eth.get_balance(my_address) + matic_balance = w3.from_wei(balance, 'ether') + print(f"⛽ 当前 MATIC 余额: {matic_balance:.4f} POL") + + if matic_balance < 0.01: + print("❌ 余额不足以支付 Gas 费,请先充值 MATIC。") + return + + # 2. 实例化 USDC 合约 + abi = [ + { + "constant": False, + "inputs": [{"name": "_spender", "type": "address"}, {"name": "_value", "type": "uint256"}], + "name": "approve", + "outputs": [{"name": "", "type": "bool"}], + "type": "function" + }, + { + "constant": True, + "inputs": [{"name": "_owner", "type": "address"}, {"name": "_spender", "type": "address"}], + "name": "allowance", + "outputs": [{"name": "", "type": "uint256"}], + "type": "function" + } + ] + usdc_contract = w3.eth.contract(address=w3.to_checksum_address(USDC_ADDRESS), abi=abi) + + # 3. 检查是否已经授权过 + current_allowance = usdc_contract.functions.allowance(my_address, CLOB_EXCHANGE).call() + if current_allowance > 10 ** 12: # 如果授权额度大于 1,000,000 USDC + print("✅ 已经拥有足够的授权额度,无需重复操作。") + return + + # 4. 构造授权交易 (无限额度) + print("⏳ 正在构建授权交易...") + max_amount = 2 ** 256 - 1 + + gas_price = w3.eth.gas_price + # 增加 20% 以确保快速成交 + adjusted_gas_price = int(gas_price * 1.2) + + tx = usdc_contract.functions.approve( + w3.to_checksum_address(CLOB_EXCHANGE), + max_amount + ).build_transaction({ + 'from': my_address, + 'nonce': w3.eth.get_transaction_count(my_address), + 'gas': 100000, + 'gasPrice': adjusted_gas_price, + 'chainId': 137 + }) + + # 5. 签名并发送 + signed_tx = w3.eth.account.sign_transaction(tx, PRIVATE_KEY) + + # 处理新旧版本 web3.py 的属性差异 + raw_tx = getattr(signed_tx, 'raw_transaction', getattr(signed_tx, 'rawTransaction', None)) + + print("📡 正在发送交易到区块链...") + tx_hash = w3.eth.send_raw_transaction(raw_tx) + print(f"✅ 交易已发出! Hash: {w3.to_hex(tx_hash)}") + + # 6. 等待确认 + print("⏳ 正在等待区块确认...") + receipt = w3.eth.wait_for_transaction_receipt(tx_hash, timeout=120) + + if receipt.status == 1: + print("-" * 30) + print("🎊 授权成功!你现在可以运行【购买.py】了。") + print("-" * 30) + else: + print("❌ 交易被拒绝,请检查 PolygonScan 确认原因。") + + except Exception as e: + print(f"❌ 发生错误: {str(e)}") + + +if __name__ == "__main__": + manual_approve() \ No newline at end of file diff --git a/polymarket/领取奖励.py b/polymarket/领取奖励.py new file mode 100644 index 000000000..6df0f3aef --- /dev/null +++ b/polymarket/领取奖励.py @@ -0,0 +1,42 @@ +from py_clob_client.client import ClobClient +from eth_account import Account + +# 启用助记词 +Account.enable_unaudited_hdwallet_features() + +# --- 配置 --- +HOST = "https://clob.polymarket.com" +MNEMONIC = "material vapor okay save company news village license head slogan sadness wire" + + +def auto_redeem(): + try: + acct = Account.from_mnemonic(MNEMONIC) + client = ClobClient(HOST, key=acct.key.hex(), chain_id=137) + client.set_api_creds(client.create_or_derive_api_creds()) + + print(f"✅ 钱包地址: {acct.address}") + + # 在新版 SDK 中,领奖函数通常是 redeem (不带 post_) + # 或者 post_redeem_positions + print("📡 尝试发送领奖请求...") + + try: + # 方案 A: 最新版标准方法 + resp = client.redeem() + except AttributeError: + # 方案 B: 兼容部分子版本 + resp = client.post_redeem_positions() + + if resp and resp.get("success"): + print("🚀 领奖成功!USDC 应该已回到你的可用余额中。") + else: + print(f"ℹ️ 状态提示: {resp}") + + except Exception as e: + print(f"❌ 运行出错: {e}") + print("💡 提示:如果此报错是 AttributeError,说明你目前没有可领取的奖金,或者该市场已自动结算。") + + +if __name__ == "__main__": + auto_redeem() \ No newline at end of file