//npm install @polymarket/clob-client //npm install ethers //npm install dotenv //Client initialization example and dumping API Keys import { ClobClient, OrderType, Side, } from '@polymarket/clob-client' import { Wallet } from '@ethersproject/wallet' import dotenv from 'dotenv' // 加载环境变量 dotenv.config({ path: '.env.local' }) // 验证必需的环境变量 if (!process.env.PRIVATE_KEY) { console.error('错误: 请在 .env.local 文件中设置 PRIVATE_KEY') process.exit(1) } if (!process.env.FUNDER_ADDRESS) { console.error('错误: 请在 .env.local 文件中设置 FUNDER_ADDRESS') process.exit(1) } const host = 'https://clob.polymarket.com' const funder = process.env.FUNDER_ADDRESS // 从环境变量读取私钥 const signer = new Wallet(process.env.PRIVATE_KEY) // 从环境变量读取配置,如果没有则使用默认值 const signatureType = parseInt(process.env.SIGNATURE_TYPE) || 1 const orderPrice = parseFloat(process.env.ORDER_PRICE) || 0.49 const orderSize = parseInt(process.env.ORDER_SIZE) || 5 console.log('配置信息:') console.log('- 签名类型:', signatureType) console.log('- 订单价格:', orderPrice) console.log('- 订单数量:', orderSize) console.log('- 地址:', funder) function getSlug() { const now = new Date() const utcTimestamp = Math.floor(now.getTime() / 1000) // 当前 UTC 时间戳(秒) // 计算下一个 15 分钟的时间点 // 15 分钟 = 900 秒 const intervalSeconds = 15 * 60 // 900 秒 const nextInterval = Math.ceil(utcTimestamp / intervalSeconds) * intervalSeconds // 生成 slug const slug = `btc-updown-15m-${nextInterval}` console.log('当前时间:', now.toISOString()) console.log('当前 UTC 时间戳:', utcTimestamp) console.log('下一个 15 分钟间隔时间戳:', nextInterval) console.log('生成的 slug:', slug) return slug } async function getNewestTokenID() { const slug = getSlug() console.log('正在获取市场信息,slug:', slug) try { const response = await fetch(`https://gamma-api.polymarket.com/markets?slug=${slug}`) if (!response.ok) { throw new Error(`HTTP 错误: ${response.status} ${response.statusText}`) } const data = await response.json() console.log('API 响应状态:', response.status) console.log('返回数据长度:', data.length) if (!data || data.length === 0) { throw new Error(`未找到 slug 为 ${slug} 的市场`) } if (!data[0].clobTokenIds) { throw new Error('市场数据中缺少 clobTokenIds 字段') } // clobTokenIds是字符串,需要解析JSON const clobTokenIds = JSON.parse(data[0].clobTokenIds) console.log('市场信息:', data[0].question) console.log('UP tokenID:', clobTokenIds[0]) console.log('DOWN tokenID:', clobTokenIds[1]) return clobTokenIds } catch (error) { console.error('获取市场信息失败:', error.message) throw error } } async function main() { try { console.log('正在初始化 CLOB 客户端...') //In general don't create a new API key, always derive or createOrDerive const creds = await new ClobClient(host, 137, signer).createOrDeriveApiKey() const clobClient = new ClobClient( host, 137, signer, creds, signatureType, funder ) // 获取最新的 tokenID console.log('正在获取市场信息...') const tokenIds = await getNewestTokenID() const upTokenID = tokenIds[0] const downTokenID = tokenIds[1] console.log('开始同时下单 UP 和 DOWN 限价单...') // 同时创建 UP 和 DOWN 订单 const orderPromises = [] // UP 订单 (买入) console.log('创建 UP 订单...') orderPromises.push( clobClient.createAndPostOrder( { tokenID: upTokenID, price: orderPrice, side: Side.BUY, size: orderSize, feeRateBps: 0, }, { tickSize: '0.01', negRisk: false }, OrderType.GTC ).then(result => { return { type: 'UP', result } }).catch(error => { console.error('UP 订单创建失败:', error.message) return { type: 'UP', error: error.message } }) ) // DOWN 订单 (买入) console.log('创建 DOWN 订单...') orderPromises.push( clobClient.createAndPostOrder( { tokenID: downTokenID, price: orderPrice, side: Side.BUY, size: orderSize, feeRateBps: 0, }, { tickSize: '0.01', negRisk: false }, OrderType.GTC ).then(result => { return { type: 'DOWN', result } }).catch(error => { console.error('DOWN 订单创建失败:', error.message) return { type: 'DOWN', error: error.message } }) ) // 等待所有订单完成 const results = await Promise.all(orderPromises) console.log('所有订单处理完成:') results.forEach(result => { if (result.error) { console.log(`${result.type} 订单失败:`, result.error) } else { console.log(`${result.type} 订单成功:`, result.result) } }) } catch (error) { console.error('执行过程中发生错误:', error.message) console.error('完整错误信息:', error) } } // 调用主函数 main()