@catalyst-team/poly-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. package/.env +0 -0
  2. package/README.md +803 -0
  3. package/dist/__tests__/clob-api.test.d.ts +5 -0
  4. package/dist/__tests__/clob-api.test.d.ts.map +1 -0
  5. package/dist/__tests__/clob-api.test.js +240 -0
  6. package/dist/__tests__/clob-api.test.js.map +1 -0
  7. package/dist/__tests__/integration/bridge-client.integration.test.d.ts +11 -0
  8. package/dist/__tests__/integration/bridge-client.integration.test.d.ts.map +1 -0
  9. package/dist/__tests__/integration/bridge-client.integration.test.js +260 -0
  10. package/dist/__tests__/integration/bridge-client.integration.test.js.map +1 -0
  11. package/dist/__tests__/integration/clob-api.integration.test.d.ts +13 -0
  12. package/dist/__tests__/integration/clob-api.integration.test.d.ts.map +1 -0
  13. package/dist/__tests__/integration/clob-api.integration.test.js +170 -0
  14. package/dist/__tests__/integration/clob-api.integration.test.js.map +1 -0
  15. package/dist/__tests__/integration/ctf-client.integration.test.d.ts +17 -0
  16. package/dist/__tests__/integration/ctf-client.integration.test.d.ts.map +1 -0
  17. package/dist/__tests__/integration/ctf-client.integration.test.js +234 -0
  18. package/dist/__tests__/integration/ctf-client.integration.test.js.map +1 -0
  19. package/dist/__tests__/integration/data-api.integration.test.d.ts +9 -0
  20. package/dist/__tests__/integration/data-api.integration.test.d.ts.map +1 -0
  21. package/dist/__tests__/integration/data-api.integration.test.js +161 -0
  22. package/dist/__tests__/integration/data-api.integration.test.js.map +1 -0
  23. package/dist/__tests__/integration/gamma-api.integration.test.d.ts +9 -0
  24. package/dist/__tests__/integration/gamma-api.integration.test.d.ts.map +1 -0
  25. package/dist/__tests__/integration/gamma-api.integration.test.js +170 -0
  26. package/dist/__tests__/integration/gamma-api.integration.test.js.map +1 -0
  27. package/dist/__tests__/test-utils.d.ts +92 -0
  28. package/dist/__tests__/test-utils.d.ts.map +1 -0
  29. package/dist/__tests__/test-utils.js +143 -0
  30. package/dist/__tests__/test-utils.js.map +1 -0
  31. package/dist/clients/bridge-client.d.ts +388 -0
  32. package/dist/clients/bridge-client.d.ts.map +1 -0
  33. package/dist/clients/bridge-client.js +587 -0
  34. package/dist/clients/bridge-client.js.map +1 -0
  35. package/dist/clients/clob-api.d.ts +318 -0
  36. package/dist/clients/clob-api.d.ts.map +1 -0
  37. package/dist/clients/clob-api.js +388 -0
  38. package/dist/clients/clob-api.js.map +1 -0
  39. package/dist/clients/ctf-client.d.ts +473 -0
  40. package/dist/clients/ctf-client.d.ts.map +1 -0
  41. package/dist/clients/ctf-client.js +915 -0
  42. package/dist/clients/ctf-client.js.map +1 -0
  43. package/dist/clients/data-api.d.ts +134 -0
  44. package/dist/clients/data-api.d.ts.map +1 -0
  45. package/dist/clients/data-api.js +265 -0
  46. package/dist/clients/data-api.js.map +1 -0
  47. package/dist/clients/gamma-api.d.ts +401 -0
  48. package/dist/clients/gamma-api.d.ts.map +1 -0
  49. package/dist/clients/gamma-api.js +352 -0
  50. package/dist/clients/gamma-api.js.map +1 -0
  51. package/dist/clients/trading-client.d.ts +252 -0
  52. package/dist/clients/trading-client.d.ts.map +1 -0
  53. package/dist/clients/trading-client.js +543 -0
  54. package/dist/clients/trading-client.js.map +1 -0
  55. package/dist/clients/websocket-manager.d.ts +100 -0
  56. package/dist/clients/websocket-manager.d.ts.map +1 -0
  57. package/dist/clients/websocket-manager.js +193 -0
  58. package/dist/clients/websocket-manager.js.map +1 -0
  59. package/dist/core/cache-adapter-bridge.d.ts +36 -0
  60. package/dist/core/cache-adapter-bridge.d.ts.map +1 -0
  61. package/dist/core/cache-adapter-bridge.js +81 -0
  62. package/dist/core/cache-adapter-bridge.js.map +1 -0
  63. package/dist/core/cache.d.ts +40 -0
  64. package/dist/core/cache.d.ts.map +1 -0
  65. package/dist/core/cache.js +71 -0
  66. package/dist/core/cache.js.map +1 -0
  67. package/dist/core/errors.d.ts +38 -0
  68. package/dist/core/errors.d.ts.map +1 -0
  69. package/dist/core/errors.js +84 -0
  70. package/dist/core/errors.js.map +1 -0
  71. package/dist/core/rate-limiter.d.ts +31 -0
  72. package/dist/core/rate-limiter.d.ts.map +1 -0
  73. package/dist/core/rate-limiter.js +70 -0
  74. package/dist/core/rate-limiter.js.map +1 -0
  75. package/dist/core/types.d.ts +314 -0
  76. package/dist/core/types.d.ts.map +1 -0
  77. package/dist/core/types.js +19 -0
  78. package/dist/core/types.js.map +1 -0
  79. package/dist/core/unified-cache.d.ts +63 -0
  80. package/dist/core/unified-cache.d.ts.map +1 -0
  81. package/dist/core/unified-cache.js +114 -0
  82. package/dist/core/unified-cache.js.map +1 -0
  83. package/dist/index.d.ts +94 -0
  84. package/dist/index.d.ts.map +1 -0
  85. package/dist/index.js +258 -0
  86. package/dist/index.js.map +1 -0
  87. package/dist/mcp/errors.d.ts +33 -0
  88. package/dist/mcp/errors.d.ts.map +1 -0
  89. package/dist/mcp/errors.js +86 -0
  90. package/dist/mcp/errors.js.map +1 -0
  91. package/dist/mcp/index.d.ts +62 -0
  92. package/dist/mcp/index.d.ts.map +1 -0
  93. package/dist/mcp/index.js +173 -0
  94. package/dist/mcp/index.js.map +1 -0
  95. package/dist/mcp/server.d.ts +17 -0
  96. package/dist/mcp/server.d.ts.map +1 -0
  97. package/dist/mcp/server.js +155 -0
  98. package/dist/mcp/server.js.map +1 -0
  99. package/dist/mcp/tools/guide.d.ts +12 -0
  100. package/dist/mcp/tools/guide.d.ts.map +1 -0
  101. package/dist/mcp/tools/guide.js +801 -0
  102. package/dist/mcp/tools/guide.js.map +1 -0
  103. package/dist/mcp/tools/index.d.ts +11 -0
  104. package/dist/mcp/tools/index.d.ts.map +1 -0
  105. package/dist/mcp/tools/index.js +27 -0
  106. package/dist/mcp/tools/index.js.map +1 -0
  107. package/dist/mcp/tools/market.d.ts +11 -0
  108. package/dist/mcp/tools/market.d.ts.map +1 -0
  109. package/dist/mcp/tools/market.js +314 -0
  110. package/dist/mcp/tools/market.js.map +1 -0
  111. package/dist/mcp/tools/order.d.ts +10 -0
  112. package/dist/mcp/tools/order.d.ts.map +1 -0
  113. package/dist/mcp/tools/order.js +258 -0
  114. package/dist/mcp/tools/order.js.map +1 -0
  115. package/dist/mcp/tools/trade.d.ts +38 -0
  116. package/dist/mcp/tools/trade.d.ts.map +1 -0
  117. package/dist/mcp/tools/trade.js +314 -0
  118. package/dist/mcp/tools/trade.js.map +1 -0
  119. package/dist/mcp/tools/trader.d.ts +11 -0
  120. package/dist/mcp/tools/trader.d.ts.map +1 -0
  121. package/dist/mcp/tools/trader.js +277 -0
  122. package/dist/mcp/tools/trader.js.map +1 -0
  123. package/dist/mcp/tools/wallet.d.ts +274 -0
  124. package/dist/mcp/tools/wallet.d.ts.map +1 -0
  125. package/dist/mcp/tools/wallet.js +579 -0
  126. package/dist/mcp/tools/wallet.js.map +1 -0
  127. package/dist/mcp/types.d.ts +413 -0
  128. package/dist/mcp/types.d.ts.map +1 -0
  129. package/dist/mcp/types.js +5 -0
  130. package/dist/mcp/types.js.map +1 -0
  131. package/dist/services/authorization-service.d.ts +97 -0
  132. package/dist/services/authorization-service.d.ts.map +1 -0
  133. package/dist/services/authorization-service.js +279 -0
  134. package/dist/services/authorization-service.js.map +1 -0
  135. package/dist/services/market-service.d.ts +108 -0
  136. package/dist/services/market-service.d.ts.map +1 -0
  137. package/dist/services/market-service.js +458 -0
  138. package/dist/services/market-service.js.map +1 -0
  139. package/dist/services/realtime-service.d.ts +82 -0
  140. package/dist/services/realtime-service.d.ts.map +1 -0
  141. package/dist/services/realtime-service.js +150 -0
  142. package/dist/services/realtime-service.js.map +1 -0
  143. package/dist/services/swap-service.d.ts +217 -0
  144. package/dist/services/swap-service.d.ts.map +1 -0
  145. package/dist/services/swap-service.js +695 -0
  146. package/dist/services/swap-service.js.map +1 -0
  147. package/dist/services/wallet-service.d.ts +94 -0
  148. package/dist/services/wallet-service.d.ts.map +1 -0
  149. package/dist/services/wallet-service.js +173 -0
  150. package/dist/services/wallet-service.js.map +1 -0
  151. package/dist/utils/price-utils.d.ts +153 -0
  152. package/dist/utils/price-utils.d.ts.map +1 -0
  153. package/dist/utils/price-utils.js +236 -0
  154. package/dist/utils/price-utils.js.map +1 -0
  155. package/docs/00-design.md +760 -0
  156. package/docs/01-mcp.md +2041 -0
  157. package/docs/02-API.md +1148 -0
  158. package/docs/e2e/01-trader-tools.md +159 -0
  159. package/docs/e2e/02-market-tools.md +180 -0
  160. package/docs/e2e/03-order-tools.md +166 -0
  161. package/docs/e2e/04-wallet-tools.md +224 -0
  162. package/docs/e2e/05-trading-tools.md +327 -0
  163. package/docs/e2e/06-integration-scenarios.md +481 -0
  164. package/docs/e2e/coordinator.md +376 -0
  165. package/examples/01-basic-usage.ts +68 -0
  166. package/examples/02-smart-money.ts +95 -0
  167. package/examples/03-market-analysis.ts +108 -0
  168. package/examples/04-kline-aggregation.ts +158 -0
  169. package/examples/05-follow-wallet-strategy.ts +156 -0
  170. package/examples/06-services-demo.ts +124 -0
  171. package/examples/07-realtime-websocket.ts +117 -0
  172. package/examples/08-trading-orders.ts +278 -0
  173. package/examples/09-rewards-tracking.ts +187 -0
  174. package/examples/10-ctf-operations.ts +336 -0
  175. package/examples/11-live-arbitrage-scan.ts +221 -0
  176. package/examples/12-trending-arb-monitor.ts +406 -0
  177. package/examples/README.md +179 -0
  178. package/package.json +62 -0
  179. package/scripts/README.md +163 -0
  180. package/scripts/approvals/approve-erc1155.ts +129 -0
  181. package/scripts/approvals/approve-neg-risk-erc1155.ts +149 -0
  182. package/scripts/approvals/approve-neg-risk.ts +102 -0
  183. package/scripts/approvals/check-all-allowances.ts +150 -0
  184. package/scripts/approvals/check-allowance.ts +129 -0
  185. package/scripts/approvals/check-ctf-approval.ts +158 -0
  186. package/scripts/datas/001-report.md +486 -0
  187. package/scripts/datas/clone-modal-screenshot.png +0 -0
  188. package/scripts/deposit/deposit-native-usdc.ts +179 -0
  189. package/scripts/deposit/deposit-usdc.ts +155 -0
  190. package/scripts/deposit/swap-usdc-to-usdce.ts +375 -0
  191. package/scripts/research/research-markets.ts +166 -0
  192. package/scripts/trading/check-orders.ts +50 -0
  193. package/scripts/trading/sell-nvidia-positions.ts +206 -0
  194. package/scripts/trading/test-order.ts +172 -0
  195. package/scripts/truth.md +440 -0
  196. package/scripts/verify/test-approve-trading.ts +98 -0
  197. package/scripts/verify/test-provider-fix.ts +43 -0
  198. package/scripts/verify/test-search-mcp.ts +113 -0
  199. package/scripts/verify/verify-all-apis.ts +160 -0
  200. package/scripts/wallet/check-wallet-balances.ts +75 -0
  201. package/scripts/wallet/test-wallet-operations.ts +191 -0
  202. package/scripts/wallet/verify-wallet-tools.ts +124 -0
  203. package/src/__tests__/clob-api.test.ts +301 -0
  204. package/src/__tests__/integration/bridge-client.integration.test.ts +314 -0
  205. package/src/__tests__/integration/clob-api.integration.test.ts +218 -0
  206. package/src/__tests__/integration/ctf-client.integration.test.ts +331 -0
  207. package/src/__tests__/integration/data-api.integration.test.ts +194 -0
  208. package/src/__tests__/integration/gamma-api.integration.test.ts +206 -0
  209. package/src/__tests__/test-utils.ts +170 -0
  210. package/src/clients/bridge-client.ts +841 -0
  211. package/src/clients/clob-api.ts +629 -0
  212. package/src/clients/ctf-client.ts +1216 -0
  213. package/src/clients/data-api.ts +469 -0
  214. package/src/clients/gamma-api.ts +597 -0
  215. package/src/clients/trading-client.ts +749 -0
  216. package/src/clients/websocket-manager.ts +267 -0
  217. package/src/core/cache-adapter-bridge.ts +94 -0
  218. package/src/core/cache.ts +85 -0
  219. package/src/core/errors.ts +117 -0
  220. package/src/core/rate-limiter.ts +74 -0
  221. package/src/core/types.ts +360 -0
  222. package/src/core/unified-cache.ts +153 -0
  223. package/src/index.ts +455 -0
  224. package/src/mcp/README.md +380 -0
  225. package/src/mcp/errors.ts +124 -0
  226. package/src/mcp/index.ts +309 -0
  227. package/src/mcp/server.ts +183 -0
  228. package/src/mcp/tools/guide.ts +821 -0
  229. package/src/mcp/tools/index.ts +73 -0
  230. package/src/mcp/tools/market.ts +363 -0
  231. package/src/mcp/tools/order.ts +326 -0
  232. package/src/mcp/tools/trade.ts +417 -0
  233. package/src/mcp/tools/trader.ts +322 -0
  234. package/src/mcp/tools/wallet.ts +683 -0
  235. package/src/mcp/types.ts +472 -0
  236. package/src/services/authorization-service.ts +357 -0
  237. package/src/services/market-service.ts +544 -0
  238. package/src/services/realtime-service.ts +196 -0
  239. package/src/services/swap-service.ts +896 -0
  240. package/src/services/wallet-service.ts +259 -0
  241. package/src/utils/price-utils.ts +307 -0
  242. package/tsconfig.json +8 -0
  243. package/vitest.config.ts +19 -0
  244. package/vitest.integration.config.ts +18 -0
@@ -0,0 +1,440 @@
1
+ # Polymarket 下单真相 (Truth About Order Placement)
2
+
3
+ 本文档记录了从部署到下单过程中的所有发现和真相。
4
+
5
+ ## 1. Polymarket 合约架构
6
+
7
+ Polymarket 使用多个智能合约来处理不同类型的市场:
8
+
9
+ ### 1.1 合约地址 (Polygon Mainnet)
10
+
11
+ | 合约名称 | 地址 | 用途 |
12
+ |---------|------|------|
13
+ | **USDC.e** | `0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174` | 交易代币 (桥接的 USDC) |
14
+ | **CTF Exchange** | `0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E` | 普通条件代币交易所 |
15
+ | **Neg Risk CTF Exchange** | `0xC5d563A36AE78145C45a50134d48A1215220f80a` | 负风险市场交易所 |
16
+ | **Neg Risk Adapter** | `0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296` | 负风险市场适配器 |
17
+ | **Conditional Tokens** | `0x4D97DCd97eC945f40cF65F87097ACe5EA0476045` | 条件代币合约 |
18
+
19
+ ### 1.2 市场类型
20
+
21
+ 1. **普通市场 (Regular Markets)**
22
+ - 使用 CTF Exchange
23
+ - 两个结果: YES/NO
24
+ - 只需要 CTF Exchange 的 allowance
25
+
26
+ 2. **负风险市场 (Neg Risk Markets)**
27
+ - 使用 Neg Risk CTF Exchange + Neg Risk Adapter
28
+ - 例如: "NVIDIA 会成为市值最大的公司吗?"
29
+ - **需要额外授权 Neg Risk Adapter 合约!**
30
+
31
+ ### 1.3 如何判断市场类型?
32
+
33
+ 查看 token ID 的结构或通过 CLOB API 检查 `negRisk` 字段:
34
+
35
+ ```typescript
36
+ const isNegRisk = await tradingClient.isNegRisk(tokenId);
37
+ ```
38
+
39
+ ## 2. Allowance 授权要求
40
+
41
+ ### 2.1 必须授权的合约
42
+
43
+ 要在 Polymarket 上交易,USDC.e 必须授权给以下合约:
44
+
45
+ ```
46
+ ✅ CTF Exchange - 普通市场必需
47
+ ✅ Neg Risk CTF Exchange - 负风险市场必需
48
+ ✅ Neg Risk Adapter - 负风险市场必需 (容易遗漏!)
49
+ ✅ Conditional Tokens - Split/Merge 操作必需
50
+ ```
51
+
52
+ ### 2.2 常见错误
53
+
54
+ **错误信息**: `"not enough balance / allowance"`
55
+
56
+ **可能原因**:
57
+ 1. ❌ USDC.e 余额不足
58
+ 2. ❌ 某个合约没有 allowance
59
+ 3. ❌ **Neg Risk Adapter 没有授权** (最容易遗漏)
60
+
61
+ ### 2.3 检查脚本
62
+
63
+ ```bash
64
+ # 检查所有 allowance
65
+ npx tsx scripts/check-all-allowances.ts
66
+
67
+ # 授权所有缺失的合约
68
+ npx tsx scripts/check-all-allowances.ts --approve
69
+ ```
70
+
71
+ ### 2.4 手动授权
72
+
73
+ 如果脚本失败,可以在 Polygonscan 上手动授权:
74
+
75
+ 1. 访问 https://polygonscan.com/token/0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174#writeContract
76
+ 2. 连接钱包
77
+ 3. 调用 `approve(spender, amount)`:
78
+ - spender: 合约地址 (如 `0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296`)
79
+ - amount: `115792089237316195423570985008687907853269984665640564039457584007913129639935` (MaxUint256)
80
+
81
+ ## 3. 订单类型差异
82
+
83
+ ### 3.1 GTC vs FOK
84
+
85
+ | 订单类型 | 全称 | 用途 | API 方法 |
86
+ |---------|------|------|----------|
87
+ | **GTC** | Good Till Cancelled | 限价单,挂单等待成交 | `createAndPostOrder()` |
88
+ | **GTD** | Good Till Date | 限价单,有过期时间 | `createAndPostOrder()` |
89
+ | **FOK** | Fill or Kill | 市价单,立即成交或取消 | `createAndPostMarketOrder()` |
90
+ | **FAK** | Fill and Kill | 市价单,部分成交也可以 | `createAndPostMarketOrder()` |
91
+
92
+ ### 3.2 代码区别
93
+
94
+ ```typescript
95
+ // GTC 限价单 (Earning Engine 使用)
96
+ const limitOrder = await trading.createOrder({
97
+ tokenId: '...',
98
+ side: 'BUY',
99
+ price: 0.50, // 限价
100
+ size: 10, // 份数
101
+ orderType: 'GTC',
102
+ });
103
+
104
+ // FOK 市价单 (套利脚本使用)
105
+ const marketOrder = await trading.createMarketOrder({
106
+ tokenId: '...',
107
+ side: 'BUY',
108
+ amount: 10, // USDC 金额
109
+ orderType: 'FOK',
110
+ });
111
+ ```
112
+
113
+ ### 3.3 重要发现
114
+
115
+ 两种订单类型都需要相同的 allowance!
116
+
117
+ - 如果 Neg Risk Adapter 没有授权,**两种订单都会失败**
118
+ - 错误信息一样: `"not enough balance / allowance"`
119
+
120
+ ## 4. API Key 问题
121
+
122
+ ### 4.1 错误信息
123
+
124
+ ```json
125
+ {"error": "Could not create api key"}
126
+ ```
127
+
128
+ ### 4.2 原因和解决
129
+
130
+ - Polymarket CLOB 客户端在每次初始化时尝试创建新的 API Key
131
+ - 如果账户已有 API Key,可能会失败
132
+ - **但这通常不影响下单**,因为会使用缓存的 API Key
133
+
134
+ 如果确实需要新的 API Key:
135
+ 1. 访问 Polymarket 网站
136
+ 2. 断开连接,重新连接钱包
137
+ 3. 系统会创建新的 API Key
138
+
139
+ ## 5. 部署到下单完整流程
140
+
141
+ ### 5.1 准备工作
142
+
143
+ 1. **获取私钥**
144
+ ```bash
145
+ # 确保 .env 中有 PRIVATE_KEY
146
+ PRIVATE_KEY=0x...
147
+ ```
148
+
149
+ 2. **获取 USDC.e**
150
+ - 钱包需要在 Polygon 上有 USDC.e
151
+ - 不是普通 USDC,是桥接的 USDC.e
152
+ - 可以从 Ethereum 通过 Polygon Bridge 桥接
153
+
154
+ 3. **设置所有 Allowance**
155
+ ```bash
156
+ cd packages/poly-sdk
157
+ npx tsx scripts/check-all-allowances.ts --approve
158
+ ```
159
+
160
+ ### 5.2 验证设置
161
+
162
+ ```bash
163
+ npx tsx scripts/check-all-allowances.ts
164
+
165
+ # 预期输出:
166
+ # CTF Exchange: ✅ Unlimited
167
+ # Neg Risk CTF Exchange: ✅ Unlimited
168
+ # Neg Risk Adapter: ✅ Unlimited
169
+ # Conditional Tokens: ✅ Unlimited
170
+ ```
171
+
172
+ ### 5.3 测试下单
173
+
174
+ ```bash
175
+ npx tsx scripts/test-order.ts
176
+ ```
177
+
178
+ ## 6. 调试 Checklist
179
+
180
+ 当下单失败时,按以下顺序检查:
181
+
182
+ - [ ] 1. USDC.e 余额是否足够?
183
+ - [ ] 2. CTF Exchange allowance 是否设置?
184
+ - [ ] 3. Neg Risk CTF Exchange allowance 是否设置?
185
+ - [ ] 4. **Neg Risk Adapter allowance 是否设置?** (最常遗漏)
186
+ - [ ] 5. Conditional Tokens allowance 是否设置?
187
+ - [ ] 6. Token ID 是否正确?
188
+ - [ ] 7. 价格是否在 0.01-0.99 范围内?
189
+ - [ ] 8. 市场是否活跃?
190
+ - [ ] 9. RPC 节点是否正常?
191
+
192
+ ## 7. 已知问题
193
+
194
+ ### 7.1 Gas 价格问题
195
+
196
+ Polygon 网络有时需要较高的 gas 价格:
197
+
198
+ ```
199
+ Error: transaction gas price below minimum:
200
+ gas tip cap 1500000000, minimum needed 25000000000
201
+ ```
202
+
203
+ **解决方案**:
204
+ ```typescript
205
+ const gasPrice = await provider.getGasPrice();
206
+ const adjustedGasPrice = gasPrice.mul(150).div(100); // 1.5x 当前价格
207
+ await contract.approve(spender, amount, { gasPrice: adjustedGasPrice });
208
+ ```
209
+
210
+ ### 7.2 RPC 不稳定
211
+
212
+ 某些公共 RPC 节点不稳定:
213
+
214
+ ```
215
+ Error: could not detect network
216
+ ```
217
+
218
+ **推荐 RPC**:
219
+ - `https://polygon-rpc.com` (官方)
220
+ - `https://polygon.llamarpc.com` (LlamaNodes)
221
+ - Alchemy/Infura (需要 API Key,更稳定)
222
+
223
+ ### 7.3 交易不广播
224
+
225
+ 有时交易提交后没有被广播:
226
+
227
+ ```
228
+ Transaction not found
229
+ ```
230
+
231
+ **原因**:
232
+ - RPC 节点问题
233
+ - Gas 价格太低
234
+ - Nonce 冲突
235
+
236
+ **解决方案**:
237
+ - 使用不同的 RPC
238
+ - 提高 gas 价格
239
+ - 等待一段时间后重试
240
+
241
+ ## 8. 套利脚本 vs Earning Engine
242
+
243
+ ### 8.1 为什么套利脚本能工作?
244
+
245
+ 套利脚本 (`scripts/v2/faze-bo3-arb.ts`) 使用 **FOK 市价单**:
246
+
247
+ ```typescript
248
+ tradingClient.createMarketOrder({
249
+ tokenId: MARKET_CONFIG.yesTokenId,
250
+ side: 'BUY',
251
+ amount: size * buyYesPrice,
252
+ orderType: 'FOK',
253
+ });
254
+ ```
255
+
256
+ ### 8.2 Earning Engine 的方式
257
+
258
+ Earning Engine 使用 **GTC 限价单**:
259
+
260
+ ```typescript
261
+ client.createOrder({
262
+ tokenId: action.tokenId,
263
+ side: action.side,
264
+ price: action.price,
265
+ size: action.size,
266
+ orderType: 'GTC',
267
+ });
268
+ ```
269
+
270
+ ### 8.3 关键结论
271
+
272
+ **两者都需要相同的 allowance**!
273
+
274
+ 如果 Neg Risk Adapter 没有授权:
275
+ - ❌ 套利脚本会失败
276
+ - ❌ Earning Engine 也会失败
277
+
278
+ ## 9. 本次调试发现
279
+
280
+ 日期: 2025-12-21
281
+
282
+ ### 发现的问题
283
+
284
+ 1. **Neg Risk Adapter 缺少 Allowance** ← **根本原因!**
285
+ ```
286
+ CTF Exchange: ✅ Unlimited
287
+ Neg Risk CTF Exchange: ✅ Unlimited
288
+ Neg Risk Adapter: ❌ None <-- 这是问题!
289
+ Conditional Tokens: ✅ Unlimited
290
+ ```
291
+
292
+ 2. **Gas 价格问题**
293
+ - ethers.js 默认 1.5 Gwei 太低
294
+ - Polygon 当前需要 25+ Gwei
295
+ - 需要在交易中手动设置更高的 gas 价格
296
+
297
+ 3. **RPC 不稳定**
298
+ - `polygon-rpc.com` 有时不广播交易
299
+ - 建议使用 `https://polygon-bor-rpc.publicnode.com`
300
+
301
+ 4. **最小订单量**
302
+ - Polymarket 最小订单量是 **5 份**
303
+ - 如果订单小于 5 份会报错
304
+
305
+ ### 解决方案
306
+
307
+ 1. 运行 `npx tsx scripts/approve-neg-risk.ts` 授权 Neg Risk Adapter
308
+ 2. 或者运行 `npx tsx scripts/check-all-allowances.ts --approve`
309
+ 3. 确保所有 4 个合约都有 Unlimited allowance
310
+
311
+ ### 验证结果
312
+
313
+ 授权后测试成功:
314
+ ```
315
+ ✅ GTC Order SUCCESS!
316
+ Order ID: 0x1fb3e5aaff045f5efbf4645e949cd9b573e6d063c4f0a365b4d827b239aae7cd
317
+
318
+ ✅ FOK Order SUCCESS!
319
+ Order ID: 0xea82673eee20bcf96de64c750ef74c540b183b51a596082ddd49aff8e8ae77bb
320
+ ```
321
+
322
+ ### 授权交易
323
+
324
+ - TX Hash: `0xf24a89ee18459a0acb003ad3f773318cc65290f196031f0d8f334c095a89e849`
325
+ - Block: 80602210
326
+
327
+ ## 10. ERC1155 授权 (卖出 YES/NO 代币)
328
+
329
+ ### 10.1 两种授权类型
330
+
331
+ Polymarket 需要两种不同的授权:
332
+
333
+ | 类型 | 标准 | 用途 | 合约 |
334
+ |------|------|------|------|
335
+ | **ERC20 Approve** | ERC20 | 授权 USDC.e 给交易所 | USDC.e → 各交易所 |
336
+ | **ERC1155 setApprovalForAll** | ERC1155 | 授权交易所转移 YES/NO 代币 | Conditional Tokens → 交易所 |
337
+
338
+ ### 10.2 为什么需要 ERC1155 授权?
339
+
340
+ - **买入 (BUY)**: 只需要 USDC.e 的 ERC20 授权
341
+ - **卖出 (SELL)**: 需要 Conditional Tokens 的 ERC1155 授权
342
+
343
+ 如果没有 ERC1155 授权,卖出订单会失败:
344
+ ```
345
+ "not enough balance / allowance"
346
+ ```
347
+
348
+ ### 10.3 如何设置 ERC1155 授权
349
+
350
+ ```typescript
351
+ const conditionalTokens = new ethers.Contract(
352
+ '0x4D97DCd97eC945f40cF65F87097ACe5EA0476045',
353
+ ['function setApprovalForAll(address operator, bool approved)'],
354
+ wallet
355
+ );
356
+
357
+ // 授权 CTF Exchange
358
+ await conditionalTokens.setApprovalForAll(CTF_EXCHANGE, true);
359
+
360
+ // 授权 Neg Risk CTF Exchange
361
+ await conditionalTokens.setApprovalForAll(NEG_RISK_CTF_EXCHANGE, true);
362
+ ```
363
+
364
+ ### 10.4 完整授权列表 (2025-12-22 更新)
365
+
366
+ ```
367
+ ERC20 授权 (USDC.e → 合约):
368
+ ✅ CTF Exchange - 普通市场 BUY
369
+ ✅ Neg Risk CTF Exchange - Neg Risk 市场 BUY
370
+ ✅ Neg Risk Adapter - Neg Risk 市场必需
371
+ ✅ Conditional Tokens - Split/Merge 操作
372
+
373
+ ERC1155 授权 (Conditional Tokens → 合约):
374
+ ✅ CTF Exchange - 普通市场 SELL
375
+ ✅ Neg Risk CTF Exchange - Neg Risk 市场 SELL
376
+ ✅ Neg Risk Adapter - ⚠️ Neg Risk 市场 SELL 必需!(容易遗漏)
377
+ ```
378
+
379
+ ### 10.5 授权脚本
380
+
381
+ ```bash
382
+ # 检查并设置所有 ERC20 授权
383
+ npx tsx scripts/check-all-allowances.ts --approve
384
+
385
+ # 检查并设置所有 ERC1155 授权 (包括 Neg Risk Adapter)
386
+ npx tsx scripts/approve-neg-risk-erc1155.ts
387
+ ```
388
+
389
+ ### 10.6 授权验证交易记录
390
+
391
+ **Neg Risk Adapter ERC1155 授权**:
392
+ - TX: `0x1fcb671978b300266b04e305432b81b76a9c3f499cdfeb4798009c5ce7708f4e`
393
+ - Block: 80609070
394
+ - Date: 2025-12-22
395
+
396
+ ## 11. Earning Engine Live 测试结果
397
+
398
+ ### 11.1 测试时间
399
+ 2025-12-21 21:42
400
+
401
+ ### 11.2 测试结果
402
+
403
+ **成功的订单**:
404
+ ```
405
+ ✅ BUY YES 10@0.93 [mm] → open
406
+ Polymarket ID: 0x09bbeb...
407
+
408
+ ✅ SELL NO 5@0.07 [mm] → open
409
+ Polymarket ID: 0x111a25...
410
+ ```
411
+
412
+ **失败的订单**:
413
+ ```
414
+ ❌ SELL YES - "not enough balance / allowance"
415
+ 原因: 需要 ERC1155 授权
416
+
417
+ ❌ BUY NO $0.53 - "invalid amount... min size: $1"
418
+ 原因: 订单金额太小
419
+ ```
420
+
421
+ ### 11.3 结论
422
+
423
+ 1. **核心问题已解决**: Neg Risk Adapter ERC20 授权修复了主要下单问题
424
+ 2. **BUY 订单正常工作**: 使用 USDC.e 买入代币无问题
425
+ 3. **SELL 订单需要额外授权**: 需要设置 ERC1155 setApprovalForAll
426
+ 4. **最小订单金额**: 市价单最小 $1,限价单最小 5 份
427
+
428
+ ## 12. 相关脚本
429
+
430
+ | 脚本 | 用途 |
431
+ |------|------|
432
+ | `check-all-allowances.ts` | 检查和设置所有 ERC20 allowance |
433
+ | `approve-neg-risk.ts` | 单独授权 Neg Risk Adapter |
434
+ | `test-order.ts` | 测试下单功能 |
435
+ | `check-allowance.ts` | 检查单个 allowance (旧版) |
436
+
437
+ ---
438
+
439
+ **最后更新**: 2025-12-21 21:45
440
+ **作者**: Claude (AI Assistant)
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Test Approve Trading
3
+ *
4
+ * Approve all required contracts for trading on Polymarket.
5
+ * This will send real transactions!
6
+ *
7
+ * Usage:
8
+ * PRIVATE_KEY=0x... npx tsx scripts/test-approve-trading.ts
9
+ */
10
+
11
+ import { ethers } from 'ethers';
12
+ import dotenv from 'dotenv';
13
+ import { AuthorizationService } from '../src/index.js';
14
+
15
+ dotenv.config();
16
+
17
+ const PRIVATE_KEY = process.env.POLY_PRIVATE_KEY || process.env.PRIVATE_KEY;
18
+
19
+ if (!PRIVATE_KEY) {
20
+ console.error('❌ Error: No private key found.');
21
+ process.exit(1);
22
+ }
23
+
24
+ const POLYGON_RPC = 'https://polygon-rpc.com';
25
+
26
+ async function main() {
27
+ console.log('╔════════════════════════════════════════════════════════════╗');
28
+ console.log('║ APPROVE TRADING TEST ║');
29
+ console.log('╚════════════════════════════════════════════════════════════╝\n');
30
+
31
+ const provider = new ethers.providers.JsonRpcProvider(POLYGON_RPC);
32
+ const signer = new ethers.Wallet(PRIVATE_KEY, provider);
33
+
34
+ console.log(`Wallet: ${signer.address}`);
35
+
36
+ // Check current balance for gas
37
+ const balance = await provider.getBalance(signer.address);
38
+ const maticBalance = ethers.utils.formatEther(balance);
39
+ console.log(`MATIC Balance: ${maticBalance}\n`);
40
+
41
+ if (parseFloat(maticBalance) < 0.1) {
42
+ console.error('❌ Insufficient MATIC for gas. Need at least 0.1 MATIC');
43
+ process.exit(1);
44
+ }
45
+
46
+ const authService = new AuthorizationService(signer);
47
+
48
+ // Check current state
49
+ console.log('Checking current allowances...');
50
+ const before = await authService.checkAllowances();
51
+ console.log(`Trading Ready: ${before.tradingReady ? '✅' : '❌'}\n`);
52
+
53
+ if (before.tradingReady) {
54
+ console.log('✅ Already ready for trading. No approvals needed.');
55
+ return;
56
+ }
57
+
58
+ // Approve all
59
+ console.log('Approving all contracts...\n');
60
+
61
+ try {
62
+ const result = await authService.approveAll();
63
+
64
+ console.log('Results:');
65
+ console.log(` Wallet: ${result.wallet}`);
66
+ console.log(` All Approved: ${result.allApproved ? '✅' : '❌'}`);
67
+
68
+ console.log('\n ERC20 Approvals:');
69
+ for (const approval of result.erc20Approvals) {
70
+ const status = approval.success ? '✅' : '❌';
71
+ console.log(` ${status} ${approval.contract}`);
72
+ if (approval.txHash) {
73
+ console.log(` TX: https://polygonscan.com/tx/${approval.txHash}`);
74
+ }
75
+ if (approval.error) {
76
+ console.log(` Error: ${approval.error}`);
77
+ }
78
+ }
79
+
80
+ console.log('\n ERC1155 Approvals:');
81
+ for (const approval of result.erc1155Approvals) {
82
+ const status = approval.success ? '✅' : '❌';
83
+ console.log(` ${status} ${approval.contract}`);
84
+ if (approval.txHash) {
85
+ console.log(` TX: https://polygonscan.com/tx/${approval.txHash}`);
86
+ }
87
+ if (approval.error) {
88
+ console.log(` Error: ${approval.error}`);
89
+ }
90
+ }
91
+
92
+ console.log(`\n${result.summary}`);
93
+ } catch (err) {
94
+ console.error(`\n❌ Error: ${err instanceof Error ? err.message : err}`);
95
+ }
96
+ }
97
+
98
+ main().catch(console.error);
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Verify provider fix for SwapService
3
+ * This script tests that the provider initialization works correctly
4
+ */
5
+
6
+ import { ethers } from 'ethers';
7
+
8
+ // Test that signer without provider works after fix
9
+ async function testProviderFix() {
10
+ console.log('Testing provider fix...\n');
11
+
12
+ // Simulate a signer without provider (like what SDK returns)
13
+ const privateKey = process.env.POLY_PRIVATE_KEY;
14
+ if (!privateKey) {
15
+ console.error('POLY_PRIVATE_KEY not set');
16
+ process.exit(1);
17
+ }
18
+
19
+ // Create signer WITHOUT provider (simulates SDK issue)
20
+ const signerNoProvider = new ethers.Wallet(privateKey);
21
+ console.log('1. Created signer without provider:');
22
+ console.log(' - Address:', signerNoProvider.address);
23
+ console.log(' - Has provider:', !!signerNoProvider.provider);
24
+
25
+ // Apply the fix: connect to provider if missing
26
+ const provider = new ethers.providers.JsonRpcProvider('https://polygon-rpc.com');
27
+ const signer = signerNoProvider.provider ? signerNoProvider : signerNoProvider.connect(provider);
28
+
29
+ console.log('\n2. After fix:');
30
+ console.log(' - Has provider:', !!signer.provider);
31
+
32
+ // Test that provider works
33
+ try {
34
+ const balance = await signer.provider!.getBalance(signer.address);
35
+ console.log(' - MATIC balance:', ethers.utils.formatEther(balance));
36
+ console.log('\n✅ Provider fix working correctly!');
37
+ } catch (err) {
38
+ console.error('\n❌ Provider still not working:', err);
39
+ process.exit(1);
40
+ }
41
+ }
42
+
43
+ testProviderFix().catch(console.error);
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Test Search Markets MCP Tool
3
+ *
4
+ * Verify the improved search functionality.
5
+ */
6
+
7
+ import { PolymarketSDK } from '../src/index.js';
8
+ import { createMcpHandler } from '../src/mcp/index.js';
9
+
10
+ async function main() {
11
+ console.log('╔════════════════════════════════════════════════════════════╗');
12
+ console.log('║ TEST: search_markets MCP TOOL ║');
13
+ console.log('╚════════════════════════════════════════════════════════════╝\n');
14
+
15
+ const sdk = new PolymarketSDK();
16
+ const handler = createMcpHandler(sdk);
17
+
18
+ // Test 1: Search for "bitcoin"
19
+ console.log('--- Test 1: Search for "bitcoin" ---');
20
+ try {
21
+ const result = await handler('search_markets', {
22
+ query: 'bitcoin',
23
+ limit: 5,
24
+ });
25
+
26
+ console.log('Results:');
27
+ const data = result as { markets: Array<{ question: string; volume24h: number }>; total: number };
28
+ data.markets.forEach((m, i) => {
29
+ console.log(` ${i + 1}. ${m.question}`);
30
+ console.log(` 24h Volume: $${m.volume24h?.toLocaleString() || 'N/A'}`);
31
+ });
32
+ console.log(`\nTotal matches: ${data.total}`);
33
+ } catch (err) {
34
+ console.log(`Error: ${err}`);
35
+ }
36
+
37
+ // Test 2: Search for "trump"
38
+ console.log('\n--- Test 2: Search for "trump" ---');
39
+ try {
40
+ const result = await handler('search_markets', {
41
+ query: 'trump',
42
+ limit: 5,
43
+ });
44
+
45
+ const data = result as { markets: Array<{ question: string; volume24h: number }>; total: number };
46
+ data.markets.forEach((m, i) => {
47
+ console.log(` ${i + 1}. ${m.question}`);
48
+ console.log(` 24h Volume: $${m.volume24h?.toLocaleString() || 'N/A'}`);
49
+ });
50
+ console.log(`\nTotal matches: ${data.total}`);
51
+ } catch (err) {
52
+ console.log(`Error: ${err}`);
53
+ }
54
+
55
+ // Test 3: Search with category filter
56
+ console.log('\n--- Test 3: Search "price" with Crypto category ---');
57
+ try {
58
+ const result = await handler('search_markets', {
59
+ query: 'price',
60
+ category: 'Crypto',
61
+ limit: 5,
62
+ });
63
+
64
+ const data = result as { markets: Array<{ question: string; volume24h: number }>; total: number };
65
+ data.markets.forEach((m, i) => {
66
+ console.log(` ${i + 1}. ${m.question}`);
67
+ });
68
+ console.log(`\nTotal matches: ${data.total}`);
69
+ } catch (err) {
70
+ console.log(`Error: ${err}`);
71
+ }
72
+
73
+ // Test 4: Multi-word search
74
+ console.log('\n--- Test 4: Multi-word search "fed interest rate" ---');
75
+ try {
76
+ const result = await handler('search_markets', {
77
+ query: 'fed interest rate',
78
+ limit: 5,
79
+ });
80
+
81
+ const data = result as { markets: Array<{ question: string; volume24h: number }>; total: number };
82
+ data.markets.forEach((m, i) => {
83
+ console.log(` ${i + 1}. ${m.question}`);
84
+ console.log(` 24h Volume: $${m.volume24h?.toLocaleString() || 'N/A'}`);
85
+ });
86
+ console.log(`\nTotal matches: ${data.total}`);
87
+ } catch (err) {
88
+ console.log(`Error: ${err}`);
89
+ }
90
+
91
+ // Test 5: Trending markets
92
+ console.log('\n--- Test 5: Trending markets (for comparison) ---');
93
+ try {
94
+ const result = await handler('get_trending_markets', {
95
+ limit: 5,
96
+ sortBy: 'volume',
97
+ });
98
+
99
+ const data = result as { markets: Array<{ question: string; volume24h: number }> };
100
+ data.markets.forEach((m, i) => {
101
+ console.log(` ${i + 1}. ${m.question}`);
102
+ console.log(` 24h Volume: $${m.volume24h?.toLocaleString() || 'N/A'}`);
103
+ });
104
+ } catch (err) {
105
+ console.log(`Error: ${err}`);
106
+ }
107
+
108
+ console.log('\n' + '═'.repeat(60));
109
+ console.log('TEST COMPLETE');
110
+ console.log('═'.repeat(60));
111
+ }
112
+
113
+ main().catch(console.error);