index.mjs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. //npm install @polymarket/clob-client
  2. //npm install ethers
  3. //npm install dotenv
  4. //Client initialization example and dumping API Keys
  5. import {
  6. ClobClient,
  7. OrderType,
  8. Side,
  9. } from '@polymarket/clob-client'
  10. import { Wallet } from '@ethersproject/wallet'
  11. import dotenv from 'dotenv'
  12. // 加载环境变量
  13. dotenv.config({ path: '.env.local' })
  14. // 验证必需的环境变量
  15. if (!process.env.PRIVATE_KEY) {
  16. console.error('错误: 请在 .env.local 文件中设置 PRIVATE_KEY')
  17. process.exit(1)
  18. }
  19. if (!process.env.FUNDER_ADDRESS) {
  20. console.error('错误: 请在 .env.local 文件中设置 FUNDER_ADDRESS')
  21. process.exit(1)
  22. }
  23. const host = 'https://clob.polymarket.com'
  24. const funder = process.env.FUNDER_ADDRESS
  25. // 从环境变量读取私钥
  26. const signer = new Wallet(process.env.PRIVATE_KEY)
  27. // 从环境变量读取配置,如果没有则使用默认值
  28. const signatureType = parseInt(process.env.SIGNATURE_TYPE) || 1
  29. const orderPrice = parseFloat(process.env.ORDER_PRICE) || 0.49
  30. const orderSize = parseInt(process.env.ORDER_SIZE) || 5
  31. console.log('配置信息:')
  32. console.log('- 签名类型:', signatureType)
  33. console.log('- 订单价格:', orderPrice)
  34. console.log('- 订单数量:', orderSize)
  35. console.log('- 地址:', funder)
  36. function getSlug() {
  37. const now = new Date()
  38. const utcTimestamp = Math.floor(now.getTime() / 1000) // 当前 UTC 时间戳(秒)
  39. // 计算下一个 15 分钟的时间点
  40. // 15 分钟 = 900 秒
  41. const intervalSeconds = 15 * 60 // 900 秒
  42. const nextInterval = Math.ceil(utcTimestamp / intervalSeconds) * intervalSeconds
  43. // 生成 slug
  44. const slug = `btc-updown-15m-${nextInterval}`
  45. console.log('当前时间:', now.toISOString())
  46. console.log('当前 UTC 时间戳:', utcTimestamp)
  47. console.log('下一个 15 分钟间隔时间戳:', nextInterval)
  48. console.log('生成的 slug:', slug)
  49. return slug
  50. }
  51. async function getNewestTokenID() {
  52. const slug = getSlug()
  53. console.log('正在获取市场信息,slug:', slug)
  54. try {
  55. const response = await fetch(`https://gamma-api.polymarket.com/markets?slug=${slug}`)
  56. if (!response.ok) {
  57. throw new Error(`HTTP 错误: ${response.status} ${response.statusText}`)
  58. }
  59. const data = await response.json()
  60. console.log('API 响应状态:', response.status)
  61. console.log('返回数据长度:', data.length)
  62. if (!data || data.length === 0) {
  63. throw new Error(`未找到 slug 为 ${slug} 的市场`)
  64. }
  65. if (!data[0].clobTokenIds) {
  66. throw new Error('市场数据中缺少 clobTokenIds 字段')
  67. }
  68. // clobTokenIds是字符串,需要解析JSON
  69. const clobTokenIds = JSON.parse(data[0].clobTokenIds)
  70. console.log('市场信息:', data[0].question)
  71. console.log('UP tokenID:', clobTokenIds[0])
  72. console.log('DOWN tokenID:', clobTokenIds[1])
  73. return clobTokenIds
  74. } catch (error) {
  75. console.error('获取市场信息失败:', error.message)
  76. throw error
  77. }
  78. }
  79. async function main() {
  80. try {
  81. console.log('正在初始化 CLOB 客户端...')
  82. //In general don't create a new API key, always derive or createOrDerive
  83. const creds = await new ClobClient(host, 137, signer).createOrDeriveApiKey()
  84. const clobClient = new ClobClient(
  85. host,
  86. 137,
  87. signer,
  88. creds,
  89. signatureType,
  90. funder
  91. )
  92. // 获取最新的 tokenID
  93. console.log('正在获取市场信息...')
  94. const tokenIds = await getNewestTokenID()
  95. const upTokenID = tokenIds[0]
  96. const downTokenID = tokenIds[1]
  97. console.log('开始同时下单 UP 和 DOWN 限价单...')
  98. // 同时创建 UP 和 DOWN 订单
  99. const orderPromises = []
  100. // UP 订单 (买入)
  101. console.log('创建 UP 订单...')
  102. orderPromises.push(
  103. clobClient.createAndPostOrder(
  104. {
  105. tokenID: upTokenID,
  106. price: orderPrice,
  107. side: Side.BUY,
  108. size: orderSize,
  109. feeRateBps: 0,
  110. },
  111. {
  112. tickSize: '0.01',
  113. negRisk: false
  114. },
  115. OrderType.GTC
  116. ).then(result => {
  117. return { type: 'UP', result }
  118. }).catch(error => {
  119. console.error('UP 订单创建失败:', error.message)
  120. return { type: 'UP', error: error.message }
  121. })
  122. )
  123. // DOWN 订单 (买入)
  124. console.log('创建 DOWN 订单...')
  125. orderPromises.push(
  126. clobClient.createAndPostOrder(
  127. {
  128. tokenID: downTokenID,
  129. price: orderPrice,
  130. side: Side.BUY,
  131. size: orderSize,
  132. feeRateBps: 0,
  133. },
  134. {
  135. tickSize: '0.01',
  136. negRisk: false
  137. },
  138. OrderType.GTC
  139. ).then(result => {
  140. return { type: 'DOWN', result }
  141. }).catch(error => {
  142. console.error('DOWN 订单创建失败:', error.message)
  143. return { type: 'DOWN', error: error.message }
  144. })
  145. )
  146. // 等待所有订单完成
  147. const results = await Promise.all(orderPromises)
  148. console.log('所有订单处理完成:')
  149. results.forEach(result => {
  150. if (result.error) {
  151. console.log(`${result.type} 订单失败:`, result.error)
  152. } else {
  153. console.log(`${result.type} 订单成功:`, result.result)
  154. }
  155. })
  156. } catch (error) {
  157. console.error('执行过程中发生错误:', error.message)
  158. console.error('完整错误信息:', error)
  159. }
  160. }
  161. // 调用主函数
  162. main()