| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- //npm install @polymarket/clob-client
- //npm install ethers
- //npm install dotenv
- import {
- ClobClient,
- OrderType,
- Side,
- } from '@polymarket/clob-client'
- import { Wallet } from '@ethersproject/wallet'
- import dotenv from 'dotenv'
- // 加载环境变量 (.env.local 优先)
- 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
- function getSlug() {
- const now = new Date()
- const utcTimestamp = Math.floor(now.getTime() / 1000)
- const intervalSeconds = 15 * 60
- const nextInterval = Math.ceil(utcTimestamp / intervalSeconds) * intervalSeconds
- 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 getTokenIdsBySlug() {
- const slug = getSlug()
- console.log('正在获取市场信息,slug:', slug)
- 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()
- if (!data || data.length === 0) {
- throw new Error(`未找到 slug 为 ${slug} 的市场`)
- }
- if (!data[0].clobTokenIds) {
- throw new Error('市场数据中缺少 clobTokenIds 字段')
- }
- 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 { upTokenID: clobTokenIds[0], downTokenID: clobTokenIds[1] }
- }
- function parseDirectionArg() {
- const arg = (process.argv[2] || '').toLowerCase()
- if (arg !== 'up' && arg !== 'down') {
- console.error('用法: node bid.mjs <up|down> [price] [size]')
- console.error('示例: node bid.mjs up 0.49 5')
- process.exit(1)
- }
- const priceArg = process.argv[3]
- const sizeArg = process.argv[4]
- const price = priceArg ? parseFloat(priceArg) : orderPrice
- const size = sizeArg ? parseInt(sizeArg) : orderSize
- if (Number.isNaN(price) || Number.isNaN(size)) {
- console.error('价格或数量无效。示例: node bid.mjs up 0.49 5')
- process.exit(1)
- }
- return { direction: arg, price, size }
- }
- async function main() {
- try {
- const { direction, price, size } = parseDirectionArg()
- console.log('配置信息:')
- console.log('- 下单方向:', direction.toUpperCase())
- console.log('- 订单价格:', price)
- console.log('- 订单数量:', size)
- console.log('- 签名类型:', signatureType)
- console.log('- 地址:', funder)
- console.log('正在初始化 CLOB 客户端...')
- const creds = await new ClobClient(host, 137, signer).createOrDeriveApiKey()
- const clobClient = new ClobClient(
- host,
- 137,
- signer,
- creds,
- signatureType,
- funder
- )
- console.log('正在获取市场 tokenID...')
- const { upTokenID, downTokenID } = await getTokenIdsBySlug()
- const tokenID = direction === 'up' ? upTokenID : downTokenID
- console.log(`创建 ${direction.toUpperCase()} 限价单...`)
- const result = await clobClient.createAndPostOrder(
- {
- tokenID,
- price,
- side: Side.BUY,
- size,
- feeRateBps: 0,
- },
- {
- tickSize: '0.01',
- negRisk: false,
- },
- OrderType.GTC
- )
- if (result?.success) {
- console.log(`${direction.toUpperCase()} 订单成功:`, result)
- } else {
- console.log(`${direction.toUpperCase()} 订单返回:`, result)
- }
- } catch (error) {
- console.error('下单失败:', error.message)
- console.error('完整错误信息:', error)
- process.exit(1)
- }
- }
- // 执行
- main()
|