@d8x/perpetuals-sdk 2.0.0-alpha → 2.0.2-alpha

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 (192) hide show
  1. package/dist/cjs/config/priceFeedConfig.json +16 -2
  2. package/dist/cjs/config/symbolList.json +2 -1
  3. package/dist/cjs/constants.d.ts +1 -0
  4. package/dist/cjs/constants.js +2 -1
  5. package/dist/cjs/constants.js.map +1 -1
  6. package/dist/cjs/d8XMath.d.ts +12 -0
  7. package/dist/cjs/d8XMath.js +22 -1
  8. package/dist/cjs/d8XMath.js.map +1 -1
  9. package/dist/cjs/perpetualDataHandler.d.ts +6 -0
  10. package/dist/cjs/perpetualDataHandler.js +27 -9
  11. package/dist/cjs/perpetualDataHandler.js.map +1 -1
  12. package/dist/cjs/polyMktsPxFeed.d.ts +14 -0
  13. package/dist/cjs/polyMktsPxFeed.js +59 -0
  14. package/dist/cjs/polyMktsPxFeed.js.map +1 -0
  15. package/dist/cjs/priceFeeds.d.ts +2 -0
  16. package/dist/cjs/priceFeeds.js +42 -6
  17. package/dist/cjs/priceFeeds.js.map +1 -1
  18. package/dist/cjs/traderInterface.js +14 -0
  19. package/dist/cjs/traderInterface.js.map +1 -1
  20. package/dist/cjs/version.d.ts +1 -1
  21. package/dist/cjs/version.js +1 -1
  22. package/dist/esm/config/priceFeedConfig.json +16 -2
  23. package/dist/esm/config/symbolList.json +2 -1
  24. package/dist/esm/constants.d.ts +1 -0
  25. package/dist/esm/constants.js +1 -0
  26. package/dist/esm/constants.js.map +1 -1
  27. package/dist/{cjs/contracts/factories/MockToken__factory.d.ts → esm/contracts/factories/PerpStorage__factory.d.ts} +115 -128
  28. package/dist/esm/contracts/factories/{MockToken__factory.js → PerpStorage__factory.js} +128 -139
  29. package/dist/esm/contracts/factories/PerpStorage__factory.js.map +1 -0
  30. package/dist/esm/d8XMath.d.ts +12 -0
  31. package/dist/esm/d8XMath.js +19 -0
  32. package/dist/esm/d8XMath.js.map +1 -1
  33. package/dist/esm/perpetualDataHandler.d.ts +6 -0
  34. package/dist/esm/perpetualDataHandler.js +29 -11
  35. package/dist/esm/perpetualDataHandler.js.map +1 -1
  36. package/dist/esm/polyMktsPxFeed.d.ts +14 -0
  37. package/dist/esm/polyMktsPxFeed.js +56 -0
  38. package/dist/esm/polyMktsPxFeed.js.map +1 -0
  39. package/dist/esm/priceFeeds.d.ts +2 -0
  40. package/dist/esm/priceFeeds.js +42 -6
  41. package/dist/esm/priceFeeds.js.map +1 -1
  42. package/dist/esm/traderInterface.js +16 -2
  43. package/dist/esm/traderInterface.js.map +1 -1
  44. package/dist/esm/version.d.ts +1 -1
  45. package/dist/esm/version.js +1 -1
  46. package/doc/marketData.md +0 -775
  47. package/package.json +1 -1
  48. package/src/config/priceFeedConfig.json +16 -2
  49. package/src/config/symbolList.json +2 -1
  50. package/src/constants.ts +1 -0
  51. package/src/d8XMath.ts +21 -0
  52. package/src/perpetualDataHandler.ts +33 -10
  53. package/src/polyMktsPxFeed.ts +71 -0
  54. package/src/priceFeeds.ts +44 -7
  55. package/src/traderInterface.ts +16 -2
  56. package/src/version.ts +1 -1
  57. package/dist/cjs/abi/BeaconProxy.json +0 -71
  58. package/dist/cjs/abi/Maintainer.json +0 -774
  59. package/dist/cjs/abi/MockToken.json +0 -347
  60. package/dist/cjs/abi/UUPSUpgradeable.json +0 -104
  61. package/dist/cjs/abi/WeETH.json +0 -310
  62. package/dist/cjs/abi-zkevm/LimitOrderBook.json +0 -910
  63. package/dist/cjs/abi-zkevm/LimitOrderBookFactory.json +0 -236
  64. package/dist/cjs/contracts/BeaconProxy.d.ts +0 -63
  65. package/dist/cjs/contracts/BeaconProxy.js +0 -3
  66. package/dist/cjs/contracts/BeaconProxy.js.map +0 -1
  67. package/dist/cjs/contracts/Maintainer.d.ts +0 -799
  68. package/dist/cjs/contracts/Maintainer.js +0 -3
  69. package/dist/cjs/contracts/Maintainer.js.map +0 -1
  70. package/dist/cjs/contracts/MockToken.d.ts +0 -263
  71. package/dist/cjs/contracts/MockToken.js +0 -3
  72. package/dist/cjs/contracts/MockToken.js.map +0 -1
  73. package/dist/cjs/contracts/UUPSUpgradeable.d.ts +0 -118
  74. package/dist/cjs/contracts/UUPSUpgradeable.js +0 -3
  75. package/dist/cjs/contracts/UUPSUpgradeable.js.map +0 -1
  76. package/dist/cjs/contracts/WeETH.d.ts +0 -503
  77. package/dist/cjs/contracts/WeETH.js +0 -3
  78. package/dist/cjs/contracts/WeETH.js.map +0 -1
  79. package/dist/cjs/contracts/factories/BeaconProxy__factory.d.ts +0 -61
  80. package/dist/cjs/contracts/factories/BeaconProxy__factory.js +0 -89
  81. package/dist/cjs/contracts/factories/BeaconProxy__factory.js.map +0 -1
  82. package/dist/cjs/contracts/factories/Maintainer__factory.d.ts +0 -609
  83. package/dist/cjs/contracts/factories/Maintainer__factory.js +0 -792
  84. package/dist/cjs/contracts/factories/Maintainer__factory.js.map +0 -1
  85. package/dist/cjs/contracts/factories/MockToken__factory.js +0 -365
  86. package/dist/cjs/contracts/factories/MockToken__factory.js.map +0 -1
  87. package/dist/cjs/contracts/factories/UUPSUpgradeable__factory.d.ts +0 -87
  88. package/dist/cjs/contracts/factories/UUPSUpgradeable__factory.js +0 -122
  89. package/dist/cjs/contracts/factories/UUPSUpgradeable__factory.js.map +0 -1
  90. package/dist/cjs/contracts/factories/WeETH__factory.d.ts +0 -545
  91. package/dist/cjs/contracts/factories/WeETH__factory.js +0 -721
  92. package/dist/cjs/contracts/factories/WeETH__factory.js.map +0 -1
  93. package/dist/cjs/contracts/factories/lean0/IPerpetualManager__factory.d.ts +0 -4136
  94. package/dist/cjs/contracts/factories/lean0/IPerpetualManager__factory.js +0 -5324
  95. package/dist/cjs/contracts/factories/lean0/IPerpetualManager__factory.js.map +0 -1
  96. package/dist/cjs/contracts/factories/lean0/LimitOrderBookFactory__factory.d.ts +0 -189
  97. package/dist/cjs/contracts/factories/lean0/LimitOrderBookFactory__factory.js +0 -254
  98. package/dist/cjs/contracts/factories/lean0/LimitOrderBookFactory__factory.js.map +0 -1
  99. package/dist/cjs/contracts/factories/lean0/LimitOrderBook__factory.d.ts +0 -715
  100. package/dist/cjs/contracts/factories/lean0/LimitOrderBook__factory.js +0 -928
  101. package/dist/cjs/contracts/factories/lean0/LimitOrderBook__factory.js.map +0 -1
  102. package/dist/cjs/contracts/factories/lean0/ShareToken__factory.d.ts +0 -344
  103. package/dist/cjs/contracts/factories/lean0/ShareToken__factory.js +0 -456
  104. package/dist/cjs/contracts/factories/lean0/ShareToken__factory.js.map +0 -1
  105. package/dist/cjs/contracts/factories/lean0/index.d.ts +0 -4
  106. package/dist/cjs/contracts/factories/lean0/index.js +0 -15
  107. package/dist/cjs/contracts/factories/lean0/index.js.map +0 -1
  108. package/dist/cjs/contracts/lean0/IPerpetualManager.d.ts +0 -2821
  109. package/dist/cjs/contracts/lean0/IPerpetualManager.js +0 -3
  110. package/dist/cjs/contracts/lean0/IPerpetualManager.js.map +0 -1
  111. package/dist/cjs/contracts/lean0/LimitOrderBook.d.ts +0 -533
  112. package/dist/cjs/contracts/lean0/LimitOrderBook.js +0 -3
  113. package/dist/cjs/contracts/lean0/LimitOrderBook.js.map +0 -1
  114. package/dist/cjs/contracts/lean0/LimitOrderBookFactory.d.ts +0 -210
  115. package/dist/cjs/contracts/lean0/LimitOrderBookFactory.js +0 -3
  116. package/dist/cjs/contracts/lean0/LimitOrderBookFactory.js.map +0 -1
  117. package/dist/cjs/contracts/lean0/ShareToken.d.ts +0 -320
  118. package/dist/cjs/contracts/lean0/ShareToken.js +0 -3
  119. package/dist/cjs/contracts/lean0/ShareToken.js.map +0 -1
  120. package/dist/cjs/contracts/lean0/index.d.ts +0 -4
  121. package/dist/cjs/contracts/lean0/index.js +0 -3
  122. package/dist/cjs/contracts/lean0/index.js.map +0 -1
  123. package/dist/esm/abi/BeaconProxy.json +0 -71
  124. package/dist/esm/abi/Maintainer.json +0 -774
  125. package/dist/esm/abi/MockToken.json +0 -347
  126. package/dist/esm/abi/UUPSUpgradeable.json +0 -104
  127. package/dist/esm/abi/WeETH.json +0 -310
  128. package/dist/esm/abi/lean0/IPerpetualManager.json +0 -5306
  129. package/dist/esm/abi/lean0/LimitOrderBook.json +0 -910
  130. package/dist/esm/abi/lean0/LimitOrderBookFactory.json +0 -236
  131. package/dist/esm/abi/lean0/ShareToken.json +0 -438
  132. package/dist/esm/abi-zkevm/LimitOrderBook.json +0 -910
  133. package/dist/esm/abi-zkevm/LimitOrderBookFactory.json +0 -236
  134. package/dist/esm/contracts/BeaconProxy.d.ts +0 -63
  135. package/dist/esm/contracts/BeaconProxy.js +0 -2
  136. package/dist/esm/contracts/BeaconProxy.js.map +0 -1
  137. package/dist/esm/contracts/Maintainer.d.ts +0 -799
  138. package/dist/esm/contracts/Maintainer.js +0 -2
  139. package/dist/esm/contracts/Maintainer.js.map +0 -1
  140. package/dist/esm/contracts/MockToken.d.ts +0 -263
  141. package/dist/esm/contracts/MockToken.js +0 -2
  142. package/dist/esm/contracts/MockToken.js.map +0 -1
  143. package/dist/esm/contracts/UUPSUpgradeable.d.ts +0 -118
  144. package/dist/esm/contracts/UUPSUpgradeable.js +0 -2
  145. package/dist/esm/contracts/UUPSUpgradeable.js.map +0 -1
  146. package/dist/esm/contracts/WeETH.d.ts +0 -503
  147. package/dist/esm/contracts/WeETH.js +0 -2
  148. package/dist/esm/contracts/WeETH.js.map +0 -1
  149. package/dist/esm/contracts/factories/BeaconProxy__factory.d.ts +0 -61
  150. package/dist/esm/contracts/factories/BeaconProxy__factory.js +0 -85
  151. package/dist/esm/contracts/factories/BeaconProxy__factory.js.map +0 -1
  152. package/dist/esm/contracts/factories/Maintainer__factory.d.ts +0 -609
  153. package/dist/esm/contracts/factories/Maintainer__factory.js +0 -788
  154. package/dist/esm/contracts/factories/Maintainer__factory.js.map +0 -1
  155. package/dist/esm/contracts/factories/MockToken__factory.d.ts +0 -273
  156. package/dist/esm/contracts/factories/MockToken__factory.js.map +0 -1
  157. package/dist/esm/contracts/factories/UUPSUpgradeable__factory.d.ts +0 -87
  158. package/dist/esm/contracts/factories/UUPSUpgradeable__factory.js +0 -118
  159. package/dist/esm/contracts/factories/UUPSUpgradeable__factory.js.map +0 -1
  160. package/dist/esm/contracts/factories/WeETH__factory.d.ts +0 -545
  161. package/dist/esm/contracts/factories/WeETH__factory.js +0 -717
  162. package/dist/esm/contracts/factories/WeETH__factory.js.map +0 -1
  163. package/dist/esm/contracts/factories/lean0/IPerpetualManager__factory.d.ts +0 -4136
  164. package/dist/esm/contracts/factories/lean0/IPerpetualManager__factory.js +0 -5320
  165. package/dist/esm/contracts/factories/lean0/IPerpetualManager__factory.js.map +0 -1
  166. package/dist/esm/contracts/factories/lean0/LimitOrderBookFactory__factory.d.ts +0 -189
  167. package/dist/esm/contracts/factories/lean0/LimitOrderBookFactory__factory.js +0 -250
  168. package/dist/esm/contracts/factories/lean0/LimitOrderBookFactory__factory.js.map +0 -1
  169. package/dist/esm/contracts/factories/lean0/LimitOrderBook__factory.d.ts +0 -715
  170. package/dist/esm/contracts/factories/lean0/LimitOrderBook__factory.js +0 -924
  171. package/dist/esm/contracts/factories/lean0/LimitOrderBook__factory.js.map +0 -1
  172. package/dist/esm/contracts/factories/lean0/ShareToken__factory.d.ts +0 -344
  173. package/dist/esm/contracts/factories/lean0/ShareToken__factory.js +0 -452
  174. package/dist/esm/contracts/factories/lean0/ShareToken__factory.js.map +0 -1
  175. package/dist/esm/contracts/factories/lean0/index.d.ts +0 -4
  176. package/dist/esm/contracts/factories/lean0/index.js +0 -8
  177. package/dist/esm/contracts/factories/lean0/index.js.map +0 -1
  178. package/dist/esm/contracts/lean0/IPerpetualManager.d.ts +0 -2821
  179. package/dist/esm/contracts/lean0/IPerpetualManager.js +0 -2
  180. package/dist/esm/contracts/lean0/IPerpetualManager.js.map +0 -1
  181. package/dist/esm/contracts/lean0/LimitOrderBook.d.ts +0 -533
  182. package/dist/esm/contracts/lean0/LimitOrderBook.js +0 -2
  183. package/dist/esm/contracts/lean0/LimitOrderBook.js.map +0 -1
  184. package/dist/esm/contracts/lean0/LimitOrderBookFactory.d.ts +0 -210
  185. package/dist/esm/contracts/lean0/LimitOrderBookFactory.js +0 -2
  186. package/dist/esm/contracts/lean0/LimitOrderBookFactory.js.map +0 -1
  187. package/dist/esm/contracts/lean0/ShareToken.d.ts +0 -320
  188. package/dist/esm/contracts/lean0/ShareToken.js +0 -2
  189. package/dist/esm/contracts/lean0/ShareToken.js.map +0 -1
  190. package/dist/esm/contracts/lean0/index.d.ts +0 -4
  191. package/dist/esm/contracts/lean0/index.js +0 -2
  192. package/dist/esm/contracts/lean0/index.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@d8x/perpetuals-sdk",
3
- "version": "2.0.0-alpha",
3
+ "version": "2.0.2-alpha",
4
4
  "description": "Node TypeScript SDK for D8X Perpetual Futures",
5
5
  "author": "D8X",
6
6
  "homepage": "https://github.com/D8-X/d8x-futures-node-sdk#readme",
@@ -2,6 +2,12 @@
2
2
  {
3
3
  "network": "mainnet",
4
4
  "ids": [
5
+ {
6
+ "symbol": "TRUMP24-USD",
7
+ "id": "0x3011e4ede0f6befa0ad3f571001d3e1ffeef3d4af78c3112aaac90416e3a43e7",
8
+ "type": "polymarket",
9
+ "origin": "0xdd22472e552920b8438158ea7238bfadfa4f736aa4cee91a6b86c39ead110917"
10
+ },
5
11
  {
6
12
  "symbol": "USDC-USD",
7
13
  "id": "0xeaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a",
@@ -153,12 +159,19 @@
153
159
  "endpoints": ["https://hermes.pyth.network"],
154
160
  "writeEndpoints": ["https://hermes.pyth.network"]
155
161
  },
156
- { "type": "onchain", "endpoints": [], "writeEndpoints": [] }
162
+ { "type": "onchain", "endpoints": [], "writeEndpoints": [] },
163
+ { "type": "polymarket", "endpoints": [], "writeEndpoints": ["https://odin-poly.d8x.xyz"] }
157
164
  ]
158
165
  },
159
166
  {
160
167
  "network": "odin",
161
168
  "ids": [
169
+ {
170
+ "symbol": "TRUMP24-USD",
171
+ "id": "0x3011e4ede0f6befa0ad3f571001d3e1ffeef3d4af78c3112aaac90416e3a43e7",
172
+ "type": "polymarket",
173
+ "origin": "0xdd22472e552920b8438158ea7238bfadfa4f736aa4cee91a6b86c39ead110917"
174
+ },
162
175
  {
163
176
  "symbol": "USDC-USD",
164
177
  "id": "0xeaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a",
@@ -233,7 +246,8 @@
233
246
  }
234
247
  ],
235
248
  "endpoints": [
236
- { "type": "odin", "endpoints": ["https://hermes.pyth.network"], "writeEndpoints": ["https://odin.d8x.xyz"] }
249
+ { "type": "odin", "endpoints": ["https://hermes.pyth.network"], "writeEndpoints": ["https://odin.d8x.xyz"] },
250
+ { "type": "polymarket", "endpoints": [""], "writeEndpoints": ["https://odin-poly.d8x.xyz"] }
237
251
  ]
238
252
  }
239
253
  ]
@@ -25,5 +25,6 @@
25
25
  "ZRO": "ZRO",
26
26
  "ETHf": "ETHFI",
27
27
  "ZK": "ZK",
28
- "PNDL": "PENDLE"
28
+ "PNDL": "PENDLE",
29
+ "TR24": "TRUMP24"
29
30
  }
package/src/constants.ts CHANGED
@@ -30,6 +30,7 @@ export const MASK_LIMIT_ORDER = BigInt("0x04000000");
30
30
  export const MASK_MARKET_ORDER = BigInt("0x40000000");
31
31
  export const MASK_STOP_ORDER = BigInt("0x20000000");
32
32
  export const MASK_KEEP_POS_LEVERAGE = BigInt("0x08000000");
33
+ export const MASK_PREDICTIVE_MARKET = 2n;
33
34
 
34
35
  export const ORDER_TYPE_LIMIT = "LIMIT";
35
36
  export const ORDER_TYPE_MARKET = "MARKET";
package/src/d8XMath.ts CHANGED
@@ -401,3 +401,24 @@ export function getDepositAmountForLvgTrade(
401
401
  let b = (Math.abs(pos0 + tradeAmnt) * S2Mark) / S3 / targetLvg;
402
402
  return -(b0 + pnl - b);
403
403
  }
404
+
405
+ /**
406
+ * Convert a perpetual price to probability (predtictive markets)
407
+ * @param px Perpetual price
408
+ * @returns Probability in [0,1]
409
+ */
410
+ export function priceToProb(px: number) {
411
+ if (px <= 0) {
412
+ throw new Error(`Price must be positive: ${px}`);
413
+ }
414
+ return Math.log(px);
415
+ }
416
+
417
+ /**
418
+ * Convert a probability to a predictive market price
419
+ * @param prob Probability in [0,1]
420
+ * @returns Perpetual price
421
+ */
422
+ export function probToPrice(prob: number) {
423
+ return Math.exp(prob);
424
+ }
@@ -20,6 +20,7 @@ import {
20
20
  MASK_KEEP_POS_LEVERAGE,
21
21
  MASK_LIMIT_ORDER,
22
22
  MASK_MARKET_ORDER,
23
+ MASK_PREDICTIVE_MARKET,
23
24
  MASK_STOP_ORDER,
24
25
  MAX_64x64,
25
26
  MULTICALL_ADDRESS,
@@ -56,6 +57,8 @@ import {
56
57
  div64x64,
57
58
  floatToABK64x64,
58
59
  dec18ToFloat,
60
+ priceToProb,
61
+ probToPrice,
59
62
  } from "./d8XMath";
60
63
  import {
61
64
  TokenOverride,
@@ -645,7 +648,7 @@ export default class PerpetualDataHandler {
645
648
  referralRebate: ABK64x64ToFloat(perpInfos[j].fReferralRebateCC),
646
649
  priceIds: perpInfos[j].priceIds,
647
650
  isPyth: perpInfos[j].isPyth,
648
- perpFlags: perpInfos[j].perpFlags,
651
+ perpFlags: BigInt(perpInfos[j].perpFlags.toString()),
649
652
  };
650
653
  infoArr.push(info);
651
654
  }
@@ -1330,13 +1333,13 @@ export default class PerpetualDataHandler {
1330
1333
  symbolToPerpInfoMap: Map<string, PerpetualStaticInfo>
1331
1334
  ): Order {
1332
1335
  // find symbol of perpetual id
1333
- let symbol = PerpetualDataHandler._getByValue(symbolToPerpInfoMap, Number(order.iPerpetualId), "id");
1336
+ const symbol = PerpetualDataHandler._getByValue(symbolToPerpInfoMap, Number(order.iPerpetualId), "id");
1334
1337
  if (symbol == undefined) {
1335
1338
  throw new Error(`Perpetual id ${order.iPerpetualId} not found. Check with marketData.exchangeInfo().`);
1336
1339
  }
1337
- let side = order.fAmount > BigInt(0) ? BUY_SIDE : SELL_SIDE;
1338
- let limitPrice, stopPrice;
1339
- let fLimitPrice: bigint | undefined = BigInt(order.fLimitPrice);
1340
+ const side = BigInt(order.fAmount.toString()) > BigInt(0) ? BUY_SIDE : SELL_SIDE;
1341
+ let limitPrice: number | undefined, stopPrice: number | undefined;
1342
+ const fLimitPrice = BigInt(order.fLimitPrice);
1340
1343
  if (fLimitPrice == 0n) {
1341
1344
  limitPrice = side == BUY_SIDE ? undefined : 0;
1342
1345
  } else if (fLimitPrice == MAX_64x64) {
@@ -1344,12 +1347,18 @@ export default class PerpetualDataHandler {
1344
1347
  } else {
1345
1348
  limitPrice = ABK64x64ToFloat(fLimitPrice);
1346
1349
  }
1347
- let fStopPrice: bigint | undefined = BigInt(order.fTriggerPrice);
1350
+ const fStopPrice: bigint = BigInt(order.fTriggerPrice);
1348
1351
  if (fStopPrice == 0n || fStopPrice == MAX_64x64) {
1349
1352
  stopPrice = undefined;
1350
1353
  } else {
1351
1354
  stopPrice = ABK64x64ToFloat(fStopPrice);
1352
1355
  }
1356
+ // adjust prices for market type
1357
+ const sInfo = symbolToPerpInfoMap.get(symbol)!;
1358
+ if (PerpetualDataHandler.isPredictiveMarket(sInfo)) {
1359
+ limitPrice = limitPrice !== undefined && limitPrice !== 0 ? priceToProb(limitPrice) : limitPrice;
1360
+ stopPrice = stopPrice !== undefined && stopPrice !== 0 ? priceToProb(stopPrice) : stopPrice;
1361
+ }
1353
1362
  let userOrder: Order = {
1354
1363
  symbol: symbol!,
1355
1364
  side: side,
@@ -1399,6 +1408,7 @@ export default class PerpetualDataHandler {
1399
1408
  } else {
1400
1409
  throw Error(`invalid side in order spec, use ${BUY_SIDE} or ${SELL_SIDE}`);
1401
1410
  }
1411
+ const isPred = PerpetualDataHandler.isPredictiveMarket(perpStaticInfo.get(order.symbol)!);
1402
1412
  let fLimitPrice: bigint;
1403
1413
  if (order.limitPrice == undefined) {
1404
1414
  // we need to set the limit price to infinity or zero for
@@ -1407,13 +1417,16 @@ export default class PerpetualDataHandler {
1407
1417
  // we set the limit to 0 or infinity
1408
1418
  fLimitPrice = order.side == BUY_SIDE ? MAX_64x64 : BigInt(0);
1409
1419
  } else {
1410
- fLimitPrice = floatToABK64x64(order.limitPrice);
1420
+ fLimitPrice = floatToABK64x64(isPred ? probToPrice(order.limitPrice) : order.limitPrice);
1411
1421
  }
1412
1422
 
1413
- let iDeadline = order.deadline == undefined ? Date.now() / 1000 + ORDER_MAX_DURATION_SEC : order.deadline;
1414
- let fTriggerPrice = order.stopPrice == undefined ? BigInt(0) : floatToABK64x64(order.stopPrice);
1423
+ const iDeadline = order.deadline == undefined ? Date.now() / 1000 + ORDER_MAX_DURATION_SEC : order.deadline;
1424
+ const fTriggerPrice =
1425
+ order.stopPrice == undefined
1426
+ ? BigInt(0)
1427
+ : floatToABK64x64(isPred ? probToPrice(order.stopPrice) : order.stopPrice);
1415
1428
 
1416
- let smOrder: SmartContractOrder = {
1429
+ const smOrder: SmartContractOrder = {
1417
1430
  flags: flags,
1418
1431
  iPerpetualId: perpetualId,
1419
1432
  brokerFeeTbps: order.brokerFeeTbps == undefined ? 0 : order.brokerFeeTbps,
@@ -1899,4 +1912,14 @@ export default class PerpetualDataHandler {
1899
1912
  callbackTarget: order.callbackTarget,
1900
1913
  };
1901
1914
  }
1915
+
1916
+ /**
1917
+ * Determines whether a given perpetual represents a predictive market
1918
+ * @param staticInfo Perpetual static info
1919
+ * @returns True if this is a predictive market
1920
+ */
1921
+ public static isPredictiveMarket(staticInfo: PerpetualStaticInfo) {
1922
+ // return true; // for testing
1923
+ return containsFlag(staticInfo.perpFlags, MASK_PREDICTIVE_MARKET);
1924
+ }
1902
1925
  }
@@ -0,0 +1,71 @@
1
+ import type { PriceFeedConfig } from "./nodeSDKTypes";
2
+
3
+ interface PolyConfig {
4
+ sym: string;
5
+ idDec: string;
6
+ id: string;
7
+ }
8
+
9
+ /**
10
+ * PolyMktsPxFeed gets prices from the official polymarket api
11
+ * and applies the exp(px) transformation
12
+ *
13
+ */
14
+ export default class PolyMktsPxFeed {
15
+ private ids: Map<string, PolyConfig>;
16
+
17
+ constructor(config: PriceFeedConfig) {
18
+ this.ids = new Map<string, PolyConfig>();
19
+ for (let k = 0; k < config.ids.length; k++) {
20
+ if (config.ids[k].type == "polymarket") {
21
+ const sym = config.ids[k].symbol;
22
+ const idDec = PolyMktsPxFeed.hexToDecimalString(config.ids[k].id);
23
+ const el: PolyConfig = {
24
+ sym: sym,
25
+ id: config.ids[k].id,
26
+ idDec: idDec,
27
+ };
28
+ this.ids.set(sym, el);
29
+ }
30
+ }
31
+ }
32
+
33
+ public isPolyMktsSym(sym: string) {
34
+ return this.ids.get(sym) == undefined;
35
+ }
36
+
37
+ public async fetchPriceForSym(sym: string): Promise<number> {
38
+ const mkt = this.ids.get(sym);
39
+ if (mkt == undefined) {
40
+ throw new Error(`symbol not in polymarket universe: ${sym}`);
41
+ }
42
+ return this.fetchPrice(mkt.idDec);
43
+ }
44
+
45
+ public async fetchPrice(tokenIdDec: string): Promise<number> {
46
+ const query = "https://clob.polymarket.com/midpoint?token_id=" + tokenIdDec;
47
+ let response = await fetch(query);
48
+ if (response.status !== 200) {
49
+ throw new Error(`unexpected status code: ${response.status}`);
50
+ }
51
+ if (!response.ok) {
52
+ throw new Error(`failed to fetch posts (${response.status}): ${response.statusText} ${query}`);
53
+ }
54
+ const data = await response.json();
55
+ const px = Number(data.mid);
56
+ return Math.exp(px);
57
+ }
58
+
59
+ static hexToDecimalString(hexString: string): string {
60
+ // Remove the "0x" prefix if it exists
61
+ if (hexString.startsWith("0x")) {
62
+ hexString = hexString.slice(2);
63
+ }
64
+
65
+ // Convert the hex string to a BigInt
66
+ const bigIntValue = BigInt("0x" + hexString);
67
+
68
+ // Convert the BigInt to a decimal string
69
+ return bigIntValue.toString(10);
70
+ }
71
+ }
package/src/priceFeeds.ts CHANGED
@@ -12,6 +12,8 @@ import PerpetualDataHandler from "./perpetualDataHandler";
12
12
  import Triangulator from "./triangulator";
13
13
  import OnChainPxFeed from "./onChainPxFeed";
14
14
  import OnChainPxFactory from "./onChainPxFactory";
15
+ import PolyMktsPxFeed from "./polyMktsPxFeed";
16
+ import { sleep } from "./utils";
15
17
  /**
16
18
  * This class communicates with the REST API that provides price-data that is
17
19
  * to be submitted to the smart contracts for certain functions such as
@@ -34,10 +36,12 @@ export default class PriceFeeds {
34
36
  // api formatting constants
35
37
  private PYTH = { endpoint: "/v2/updates/price/latest?encoding=base64&ids[]=", separator: "&ids[]=", suffix: "" };
36
38
 
39
+ private polyMktsPxFeed: PolyMktsPxFeed;
40
+
37
41
  constructor(dataHandler: PerpetualDataHandler, priceFeedConfigNetwork: string) {
38
42
  let configs = require("./config/priceFeedConfig.json") as PriceFeedConfig[];
39
43
  this.config = PriceFeeds._selectConfig(configs, priceFeedConfigNetwork);
40
-
44
+ this.polyMktsPxFeed = new PolyMktsPxFeed(this.config);
41
45
  // if SDK config contains custom price feed endpoints, these override the
42
46
  // public/default ones
43
47
  if (dataHandler.config.priceFeedEndpoints && dataHandler.config.priceFeedEndpoints.length > 0) {
@@ -51,7 +55,7 @@ export default class PriceFeeds {
51
55
  for (let k = 0; k < this.config.ids.length; k++) {
52
56
  if (this.config.ids[k].type == "onchain") {
53
57
  let sym = this.config.ids[k].symbol;
54
- this.onChainPxFeeds[sym] = OnChainPxFactory.createFeed(sym);
58
+ this.onChainPxFeeds.set(sym, OnChainPxFactory.createFeed(sym)!);
55
59
  }
56
60
  }
57
61
  [this.feedInfo, this.feedEndpoints, this.writeFeedEndpoints] = PriceFeeds._constructFeedInfo(this.config, false);
@@ -244,6 +248,7 @@ export default class PriceFeeds {
244
248
  symbolsOfEndpoint.push([]);
245
249
  }
246
250
  let onChainSyms: string[] = [];
251
+ let polyMktSyms: string[] = [];
247
252
  for (let k = 0; k < this.config.ids.length; k++) {
248
253
  let currFeed = this.config.ids[k];
249
254
  if (symbols != undefined && !symbols.includes(currFeed.symbol)) {
@@ -253,6 +258,10 @@ export default class PriceFeeds {
253
258
  onChainSyms.push(currFeed.symbol);
254
259
  continue;
255
260
  }
261
+ if (currFeed.type == "polymarket") {
262
+ polyMktSyms.push(currFeed.symbol);
263
+ continue;
264
+ }
256
265
  const apiFormat = { pyth: this.PYTH, odin: this.PYTH }[currFeed.type];
257
266
  if (apiFormat === undefined) {
258
267
  throw new Error(`API format for ${currFeed} unknown.`);
@@ -270,6 +279,7 @@ export default class PriceFeeds {
270
279
  }
271
280
  }
272
281
  let onChainPromise = this.queryOnChainPxFeeds(onChainSyms);
282
+ let polyMktsPromise = this.queryPolyMktsPxFeeds(polyMktSyms);
273
283
  let resultPrices = new Map<string, [number, boolean]>();
274
284
  for (let k = 0; k < queries.length; k++) {
275
285
  if (queries[k] == undefined) {
@@ -288,6 +298,14 @@ export default class PriceFeeds {
288
298
  let sym = onChainSyms[k];
289
299
  resultPrices.set(sym, [onChPxs[k], false]);
290
300
  }
301
+ let polyPxs = await polyMktsPromise;
302
+ for (let k = 0; k < polyPxs.length; k++) {
303
+ let sym = polyMktSyms[k];
304
+ if (polyPxs[k] == -1) {
305
+ continue;
306
+ }
307
+ resultPrices.set(sym, [polyPxs[k], false]);
308
+ }
291
309
  return resultPrices;
292
310
  }
293
311
 
@@ -295,12 +313,30 @@ export default class PriceFeeds {
295
313
  let prices: number[] = new Array<number>();
296
314
  for (let k = 0; k < symbols.length; k++) {
297
315
  let sym = symbols[k];
298
- let price = await this.onChainPxFeeds[sym].getPrice();
316
+ const feed = this.onChainPxFeeds.get(sym);
317
+ let price = await feed!.getPrice();
299
318
  prices.push(price);
300
319
  }
301
320
  return prices;
302
321
  }
303
322
 
323
+ private async queryPolyMktsPxFeeds(symbols: string[]) {
324
+ let prices: number[] = new Array<number>();
325
+ for (let k = 0; k < symbols.length; k++) {
326
+ try {
327
+ let price = await this.polyMktsPxFeed.fetchPriceForSym(symbols[k]);
328
+ prices.push(price);
329
+ } catch (error) {
330
+ console.log("fetchPriceForSym failed for " + symbols[k]);
331
+ prices.push(-1);
332
+ }
333
+ if (k > 0) {
334
+ await sleep(0.25);
335
+ }
336
+ }
337
+ return prices;
338
+ }
339
+
304
340
  /**
305
341
  * Get all configured feed prices via "latest_price_feeds".
306
342
  * @returns map of feed-price symbol to price/isMarketClosed
@@ -327,16 +363,17 @@ export default class PriceFeeds {
327
363
  throw new Error(`priceFeeds: config for symbol ${symbol} insufficient`);
328
364
  }
329
365
  // we use the first endpoint for a given symbol even if there is another symbol with the same id
330
- // and another
331
366
  let idx = info[0].endpointId;
332
367
  let feedId = feedIds[k];
333
368
  queries.push(this.writeFeedEndpoints[idx] + "/v2/updates/price/latest?encoding=base64&ids[]=" + feedId);
334
369
 
335
370
  for (let j = 0; j < info.length; j++) {
336
371
  if (symbols.has(feedId)) {
337
- symbols[feedId].append(info[j].symbol);
372
+ let v = symbols.get(feedId);
373
+ v!.push(info[j].symbol);
374
+ symbols.set(feedId, v!);
338
375
  } else {
339
- symbols[feedId] = [info[j].symbol];
376
+ symbols.set(feedId, [info[j].symbol]);
340
377
  }
341
378
  }
342
379
  }
@@ -403,7 +440,7 @@ export default class PriceFeeds {
403
440
  public calculateTriangulatedPricesFromFeedInfo(symbols: string[], feeds: PriceFeedSubmission): [number[], boolean[]] {
404
441
  let priceMap = new Map<string, [number, boolean]>();
405
442
  for (let j = 0; j < feeds.prices.length; j++) {
406
- const syms = feeds.symbols[feeds.ids[j]];
443
+ const syms = feeds.symbols.get(feeds.ids[j]);
407
444
  if (syms == undefined) {
408
445
  console.log("calculateTriangulatedPricesFromFeedInfo: could not find symbol for id ", feeds.ids[j]);
409
446
  continue;
@@ -1,10 +1,11 @@
1
1
  import { Contract, ContractTransactionResponse, Overrides, Signer } from "ethers";
2
- import { ZERO_ORDER_ID } from "./constants";
3
- import { ABK64x64ToFloat, floatToDec18, floatToDecN } from "./d8XMath";
2
+ import { MASK_PREDICTIVE_MARKET, ZERO_ORDER_ID } from "./constants";
3
+ import { ABK64x64ToFloat, floatToDec18, floatToDecN, priceToProb, probToPrice } from "./d8XMath";
4
4
  import MarketData from "./marketData";
5
5
  import type { ClientOrder, NodeSDKConfig, Order, SmartContractOrder } from "./nodeSDKTypes";
6
6
  import PerpetualDataHandler from "./perpetualDataHandler";
7
7
  import TraderDigests from "./traderDigests";
8
+ import { containsFlag } from "./utils";
8
9
  /**
9
10
  * Interface that can be used by front-end that wraps all private functions
10
11
  * so that signatures can be handled in frontend via wallet
@@ -161,6 +162,19 @@ export default class TraderInterface extends MarketData {
161
162
  * @returns Smart contract type order struct
162
163
  */
163
164
  public createSmartContractOrder(order: Order, traderAddr: string): SmartContractOrder {
165
+ const sInfo = this.symbolToPerpStaticInfo.get(order.symbol);
166
+ if (!sInfo) {
167
+ throw new Error(`No perpetual static info found for symbol ${order.symbol}`);
168
+ }
169
+ if (containsFlag(BigInt(sInfo.perpFlags), MASK_PREDICTIVE_MARKET)) {
170
+ // convert prob to actual price
171
+ if (order.limitPrice !== undefined) {
172
+ order.limitPrice = probToPrice(order.limitPrice);
173
+ }
174
+ if (order.stopPrice !== undefined) {
175
+ order.stopPrice = probToPrice(order.stopPrice);
176
+ }
177
+ }
164
178
  let scOrder = TraderInterface.toSmartContractOrder(order, traderAddr, this.symbolToPerpStaticInfo);
165
179
  return scOrder;
166
180
  }
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const D8X_SDK_VERSION = "2.0.0-alpha";
1
+ export const D8X_SDK_VERSION = "2.0.2-alpha";
@@ -1,71 +0,0 @@
1
- [
2
- {
3
- "inputs": [
4
- {
5
- "internalType": "address",
6
- "name": "beacon",
7
- "type": "address"
8
- },
9
- {
10
- "internalType": "bytes",
11
- "name": "data",
12
- "type": "bytes"
13
- }
14
- ],
15
- "stateMutability": "payable",
16
- "type": "constructor"
17
- },
18
- {
19
- "anonymous": false,
20
- "inputs": [
21
- {
22
- "indexed": false,
23
- "internalType": "address",
24
- "name": "previousAdmin",
25
- "type": "address"
26
- },
27
- {
28
- "indexed": false,
29
- "internalType": "address",
30
- "name": "newAdmin",
31
- "type": "address"
32
- }
33
- ],
34
- "name": "AdminChanged",
35
- "type": "event"
36
- },
37
- {
38
- "anonymous": false,
39
- "inputs": [
40
- {
41
- "indexed": true,
42
- "internalType": "address",
43
- "name": "beacon",
44
- "type": "address"
45
- }
46
- ],
47
- "name": "BeaconUpgraded",
48
- "type": "event"
49
- },
50
- {
51
- "anonymous": false,
52
- "inputs": [
53
- {
54
- "indexed": true,
55
- "internalType": "address",
56
- "name": "implementation",
57
- "type": "address"
58
- }
59
- ],
60
- "name": "Upgraded",
61
- "type": "event"
62
- },
63
- {
64
- "stateMutability": "payable",
65
- "type": "fallback"
66
- },
67
- {
68
- "stateMutability": "payable",
69
- "type": "receive"
70
- }
71
- ]