@lifi/perps-sdk-provider-ondo 0.0.0-preview-7ff840c

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 (280) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +38 -0
  3. package/dist/cjs/OndoProvider.d.ts +8 -0
  4. package/dist/cjs/OndoProvider.d.ts.map +1 -0
  5. package/dist/cjs/OndoProvider.js +338 -0
  6. package/dist/cjs/OndoProvider.js.map +1 -0
  7. package/dist/cjs/accountConfig.d.ts +3 -0
  8. package/dist/cjs/accountConfig.d.ts.map +1 -0
  9. package/dist/cjs/accountConfig.js +59 -0
  10. package/dist/cjs/accountConfig.js.map +1 -0
  11. package/dist/cjs/accountSummary.d.ts +3 -0
  12. package/dist/cjs/accountSummary.d.ts.map +1 -0
  13. package/dist/cjs/accountSummary.js +8 -0
  14. package/dist/cjs/accountSummary.js.map +1 -0
  15. package/dist/cjs/auth/OndoTokenStore.d.ts +13 -0
  16. package/dist/cjs/auth/OndoTokenStore.d.ts.map +1 -0
  17. package/dist/cjs/auth/OndoTokenStore.js +53 -0
  18. package/dist/cjs/auth/OndoTokenStore.js.map +1 -0
  19. package/dist/cjs/auth/completeSiweLogin.d.ts +13 -0
  20. package/dist/cjs/auth/completeSiweLogin.d.ts.map +1 -0
  21. package/dist/cjs/auth/completeSiweLogin.js +15 -0
  22. package/dist/cjs/auth/completeSiweLogin.js.map +1 -0
  23. package/dist/cjs/auth/index.d.ts +4 -0
  24. package/dist/cjs/auth/index.d.ts.map +1 -0
  25. package/dist/cjs/auth/index.js +11 -0
  26. package/dist/cjs/auth/index.js.map +1 -0
  27. package/dist/cjs/auth/signActions.d.ts +13 -0
  28. package/dist/cjs/auth/signActions.d.ts.map +1 -0
  29. package/dist/cjs/auth/signActions.js +86 -0
  30. package/dist/cjs/auth/signActions.js.map +1 -0
  31. package/dist/cjs/constants.d.ts +9 -0
  32. package/dist/cjs/constants.d.ts.map +1 -0
  33. package/dist/cjs/constants.js +12 -0
  34. package/dist/cjs/constants.js.map +1 -0
  35. package/dist/cjs/index.d.ts +9 -0
  36. package/dist/cjs/index.d.ts.map +1 -0
  37. package/dist/cjs/index.js +37 -0
  38. package/dist/cjs/index.js.map +1 -0
  39. package/dist/cjs/package.json +1 -0
  40. package/dist/cjs/types/auth.d.ts +16 -0
  41. package/dist/cjs/types/auth.d.ts.map +1 -0
  42. package/dist/cjs/types/auth.js +3 -0
  43. package/dist/cjs/types/auth.js.map +1 -0
  44. package/dist/cjs/types/index.d.ts +4 -0
  45. package/dist/cjs/types/index.d.ts.map +1 -0
  46. package/dist/cjs/types/index.js +3 -0
  47. package/dist/cjs/types/index.js.map +1 -0
  48. package/dist/cjs/types/wire.d.ts +154 -0
  49. package/dist/cjs/types/wire.d.ts.map +1 -0
  50. package/dist/cjs/types/wire.js +3 -0
  51. package/dist/cjs/types/wire.js.map +1 -0
  52. package/dist/cjs/types/ws.d.ts +92 -0
  53. package/dist/cjs/types/ws.d.ts.map +1 -0
  54. package/dist/cjs/types/ws.js +3 -0
  55. package/dist/cjs/types/ws.js.map +1 -0
  56. package/dist/cjs/utils/activityCursor.d.ts +9 -0
  57. package/dist/cjs/utils/activityCursor.d.ts.map +1 -0
  58. package/dist/cjs/utils/activityCursor.js +79 -0
  59. package/dist/cjs/utils/activityCursor.js.map +1 -0
  60. package/dist/cjs/utils/apiClient.d.ts +43 -0
  61. package/dist/cjs/utils/apiClient.d.ts.map +1 -0
  62. package/dist/cjs/utils/apiClient.js +134 -0
  63. package/dist/cjs/utils/apiClient.js.map +1 -0
  64. package/dist/cjs/utils/index.d.ts +11 -0
  65. package/dist/cjs/utils/index.d.ts.map +1 -0
  66. package/dist/cjs/utils/index.js +39 -0
  67. package/dist/cjs/utils/index.js.map +1 -0
  68. package/dist/cjs/utils/liquidation.d.ts +4 -0
  69. package/dist/cjs/utils/liquidation.d.ts.map +1 -0
  70. package/dist/cjs/utils/liquidation.js +16 -0
  71. package/dist/cjs/utils/liquidation.js.map +1 -0
  72. package/dist/cjs/utils/mapActivity.d.ts +5 -0
  73. package/dist/cjs/utils/mapActivity.d.ts.map +1 -0
  74. package/dist/cjs/utils/mapActivity.js +34 -0
  75. package/dist/cjs/utils/mapActivity.js.map +1 -0
  76. package/dist/cjs/utils/mapFill.d.ts +4 -0
  77. package/dist/cjs/utils/mapFill.d.ts.map +1 -0
  78. package/dist/cjs/utils/mapFill.js +36 -0
  79. package/dist/cjs/utils/mapFill.js.map +1 -0
  80. package/dist/cjs/utils/mapOrder.d.ts +16 -0
  81. package/dist/cjs/utils/mapOrder.d.ts.map +1 -0
  82. package/dist/cjs/utils/mapOrder.js +135 -0
  83. package/dist/cjs/utils/mapOrder.js.map +1 -0
  84. package/dist/cjs/utils/mapPosition.d.ts +5 -0
  85. package/dist/cjs/utils/mapPosition.d.ts.map +1 -0
  86. package/dist/cjs/utils/mapPosition.js +26 -0
  87. package/dist/cjs/utils/mapPosition.js.map +1 -0
  88. package/dist/cjs/utils/ohlcvInterval.d.ts +4 -0
  89. package/dist/cjs/utils/ohlcvInterval.d.ts.map +1 -0
  90. package/dist/cjs/utils/ohlcvInterval.js +49 -0
  91. package/dist/cjs/utils/ohlcvInterval.js.map +1 -0
  92. package/dist/cjs/utils/ondoAsset.d.ts +3 -0
  93. package/dist/cjs/utils/ondoAsset.d.ts.map +1 -0
  94. package/dist/cjs/utils/ondoAsset.js +12 -0
  95. package/dist/cjs/utils/ondoAsset.js.map +1 -0
  96. package/dist/cjs/utils/orderFormatting.d.ts +4 -0
  97. package/dist/cjs/utils/orderFormatting.d.ts.map +1 -0
  98. package/dist/cjs/utils/orderFormatting.js +40 -0
  99. package/dist/cjs/utils/orderFormatting.js.map +1 -0
  100. package/dist/cjs/websocket/OndoWsProvider.d.ts +56 -0
  101. package/dist/cjs/websocket/OndoWsProvider.d.ts.map +1 -0
  102. package/dist/cjs/websocket/OndoWsProvider.js +515 -0
  103. package/dist/cjs/websocket/OndoWsProvider.js.map +1 -0
  104. package/dist/esm/OndoProvider.d.ts +39 -0
  105. package/dist/esm/OndoProvider.d.ts.map +1 -0
  106. package/dist/esm/OndoProvider.js +366 -0
  107. package/dist/esm/OndoProvider.js.map +1 -0
  108. package/dist/esm/accountConfig.d.ts +13 -0
  109. package/dist/esm/accountConfig.d.ts.map +1 -0
  110. package/dist/esm/accountConfig.js +77 -0
  111. package/dist/esm/accountConfig.js.map +1 -0
  112. package/dist/esm/accountSummary.d.ts +12 -0
  113. package/dist/esm/accountSummary.d.ts.map +1 -0
  114. package/dist/esm/accountSummary.js +14 -0
  115. package/dist/esm/accountSummary.js.map +1 -0
  116. package/dist/esm/auth/OndoTokenStore.d.ts +20 -0
  117. package/dist/esm/auth/OndoTokenStore.d.ts.map +1 -0
  118. package/dist/esm/auth/OndoTokenStore.js +61 -0
  119. package/dist/esm/auth/OndoTokenStore.js.map +1 -0
  120. package/dist/esm/auth/completeSiweLogin.d.ts +28 -0
  121. package/dist/esm/auth/completeSiweLogin.d.ts.map +1 -0
  122. package/dist/esm/auth/completeSiweLogin.js +21 -0
  123. package/dist/esm/auth/completeSiweLogin.js.map +1 -0
  124. package/dist/esm/auth/index.d.ts +4 -0
  125. package/dist/esm/auth/index.d.ts.map +1 -0
  126. package/dist/esm/auth/index.js +5 -0
  127. package/dist/esm/auth/index.js.map +1 -0
  128. package/dist/esm/auth/signActions.d.ts +35 -0
  129. package/dist/esm/auth/signActions.d.ts.map +1 -0
  130. package/dist/esm/auth/signActions.js +103 -0
  131. package/dist/esm/auth/signActions.js.map +1 -0
  132. package/dist/esm/constants.d.ts +35 -0
  133. package/dist/esm/constants.d.ts.map +1 -0
  134. package/dist/esm/constants.js +35 -0
  135. package/dist/esm/constants.js.map +1 -0
  136. package/dist/esm/index.d.ts +19 -0
  137. package/dist/esm/index.d.ts.map +1 -0
  138. package/dist/esm/index.js +21 -0
  139. package/dist/esm/index.js.map +1 -0
  140. package/dist/esm/package.json +1 -0
  141. package/dist/esm/types/auth.d.ts +32 -0
  142. package/dist/esm/types/auth.d.ts.map +1 -0
  143. package/dist/esm/types/auth.js +2 -0
  144. package/dist/esm/types/auth.js.map +1 -0
  145. package/dist/esm/types/index.d.ts +4 -0
  146. package/dist/esm/types/index.d.ts.map +1 -0
  147. package/dist/esm/types/index.js +3 -0
  148. package/dist/esm/types/index.js.map +1 -0
  149. package/dist/esm/types/wire.d.ts +195 -0
  150. package/dist/esm/types/wire.d.ts.map +1 -0
  151. package/dist/esm/types/wire.js +7 -0
  152. package/dist/esm/types/wire.js.map +1 -0
  153. package/dist/esm/types/ws.d.ts +108 -0
  154. package/dist/esm/types/ws.d.ts.map +1 -0
  155. package/dist/esm/types/ws.js +7 -0
  156. package/dist/esm/types/ws.js.map +1 -0
  157. package/dist/esm/utils/activityCursor.d.ts +47 -0
  158. package/dist/esm/utils/activityCursor.d.ts.map +1 -0
  159. package/dist/esm/utils/activityCursor.js +93 -0
  160. package/dist/esm/utils/activityCursor.js.map +1 -0
  161. package/dist/esm/utils/apiClient.d.ts +90 -0
  162. package/dist/esm/utils/apiClient.d.ts.map +1 -0
  163. package/dist/esm/utils/apiClient.js +169 -0
  164. package/dist/esm/utils/apiClient.js.map +1 -0
  165. package/dist/esm/utils/index.d.ts +11 -0
  166. package/dist/esm/utils/index.d.ts.map +1 -0
  167. package/dist/esm/utils/index.js +12 -0
  168. package/dist/esm/utils/index.js.map +1 -0
  169. package/dist/esm/utils/liquidation.d.ts +20 -0
  170. package/dist/esm/utils/liquidation.d.ts.map +1 -0
  171. package/dist/esm/utils/liquidation.js +29 -0
  172. package/dist/esm/utils/liquidation.js.map +1 -0
  173. package/dist/esm/utils/mapActivity.d.ts +21 -0
  174. package/dist/esm/utils/mapActivity.d.ts.map +1 -0
  175. package/dist/esm/utils/mapActivity.js +45 -0
  176. package/dist/esm/utils/mapActivity.js.map +1 -0
  177. package/dist/esm/utils/mapFill.d.ts +12 -0
  178. package/dist/esm/utils/mapFill.d.ts.map +1 -0
  179. package/dist/esm/utils/mapFill.js +37 -0
  180. package/dist/esm/utils/mapFill.js.map +1 -0
  181. package/dist/esm/utils/mapOrder.d.ts +50 -0
  182. package/dist/esm/utils/mapOrder.d.ts.map +1 -0
  183. package/dist/esm/utils/mapOrder.js +155 -0
  184. package/dist/esm/utils/mapOrder.js.map +1 -0
  185. package/dist/esm/utils/mapPosition.d.ts +19 -0
  186. package/dist/esm/utils/mapPosition.d.ts.map +1 -0
  187. package/dist/esm/utils/mapPosition.js +32 -0
  188. package/dist/esm/utils/mapPosition.js.map +1 -0
  189. package/dist/esm/utils/ohlcvInterval.d.ts +11 -0
  190. package/dist/esm/utils/ohlcvInterval.d.ts.map +1 -0
  191. package/dist/esm/utils/ohlcvInterval.js +59 -0
  192. package/dist/esm/utils/ohlcvInterval.js.map +1 -0
  193. package/dist/esm/utils/ondoAsset.d.ts +4 -0
  194. package/dist/esm/utils/ondoAsset.d.ts.map +1 -0
  195. package/dist/esm/utils/ondoAsset.js +9 -0
  196. package/dist/esm/utils/ondoAsset.js.map +1 -0
  197. package/dist/esm/utils/orderFormatting.d.ts +33 -0
  198. package/dist/esm/utils/orderFormatting.d.ts.map +1 -0
  199. package/dist/esm/utils/orderFormatting.js +62 -0
  200. package/dist/esm/utils/orderFormatting.js.map +1 -0
  201. package/dist/esm/websocket/OndoWsProvider.d.ts +122 -0
  202. package/dist/esm/websocket/OndoWsProvider.d.ts.map +1 -0
  203. package/dist/esm/websocket/OndoWsProvider.js +591 -0
  204. package/dist/esm/websocket/OndoWsProvider.js.map +1 -0
  205. package/dist/types/OndoProvider.d.ts +39 -0
  206. package/dist/types/OndoProvider.d.ts.map +1 -0
  207. package/dist/types/accountConfig.d.ts +13 -0
  208. package/dist/types/accountConfig.d.ts.map +1 -0
  209. package/dist/types/accountSummary.d.ts +12 -0
  210. package/dist/types/accountSummary.d.ts.map +1 -0
  211. package/dist/types/auth/OndoTokenStore.d.ts +20 -0
  212. package/dist/types/auth/OndoTokenStore.d.ts.map +1 -0
  213. package/dist/types/auth/completeSiweLogin.d.ts +28 -0
  214. package/dist/types/auth/completeSiweLogin.d.ts.map +1 -0
  215. package/dist/types/auth/index.d.ts +4 -0
  216. package/dist/types/auth/index.d.ts.map +1 -0
  217. package/dist/types/auth/signActions.d.ts +35 -0
  218. package/dist/types/auth/signActions.d.ts.map +1 -0
  219. package/dist/types/constants.d.ts +35 -0
  220. package/dist/types/constants.d.ts.map +1 -0
  221. package/dist/types/index.d.ts +19 -0
  222. package/dist/types/index.d.ts.map +1 -0
  223. package/dist/types/types/auth.d.ts +32 -0
  224. package/dist/types/types/auth.d.ts.map +1 -0
  225. package/dist/types/types/index.d.ts +4 -0
  226. package/dist/types/types/index.d.ts.map +1 -0
  227. package/dist/types/types/wire.d.ts +195 -0
  228. package/dist/types/types/wire.d.ts.map +1 -0
  229. package/dist/types/types/ws.d.ts +108 -0
  230. package/dist/types/types/ws.d.ts.map +1 -0
  231. package/dist/types/utils/activityCursor.d.ts +47 -0
  232. package/dist/types/utils/activityCursor.d.ts.map +1 -0
  233. package/dist/types/utils/apiClient.d.ts +90 -0
  234. package/dist/types/utils/apiClient.d.ts.map +1 -0
  235. package/dist/types/utils/index.d.ts +11 -0
  236. package/dist/types/utils/index.d.ts.map +1 -0
  237. package/dist/types/utils/liquidation.d.ts +20 -0
  238. package/dist/types/utils/liquidation.d.ts.map +1 -0
  239. package/dist/types/utils/mapActivity.d.ts +21 -0
  240. package/dist/types/utils/mapActivity.d.ts.map +1 -0
  241. package/dist/types/utils/mapFill.d.ts +12 -0
  242. package/dist/types/utils/mapFill.d.ts.map +1 -0
  243. package/dist/types/utils/mapOrder.d.ts +50 -0
  244. package/dist/types/utils/mapOrder.d.ts.map +1 -0
  245. package/dist/types/utils/mapPosition.d.ts +19 -0
  246. package/dist/types/utils/mapPosition.d.ts.map +1 -0
  247. package/dist/types/utils/ohlcvInterval.d.ts +11 -0
  248. package/dist/types/utils/ohlcvInterval.d.ts.map +1 -0
  249. package/dist/types/utils/ondoAsset.d.ts +4 -0
  250. package/dist/types/utils/ondoAsset.d.ts.map +1 -0
  251. package/dist/types/utils/orderFormatting.d.ts +33 -0
  252. package/dist/types/utils/orderFormatting.d.ts.map +1 -0
  253. package/dist/types/websocket/OndoWsProvider.d.ts +122 -0
  254. package/dist/types/websocket/OndoWsProvider.d.ts.map +1 -0
  255. package/package.json +64 -0
  256. package/src/OndoProvider.ts +635 -0
  257. package/src/accountConfig.ts +105 -0
  258. package/src/accountSummary.ts +22 -0
  259. package/src/auth/OndoTokenStore.ts +83 -0
  260. package/src/auth/completeSiweLogin.ts +43 -0
  261. package/src/auth/index.ts +12 -0
  262. package/src/auth/signActions.ts +160 -0
  263. package/src/constants.ts +38 -0
  264. package/src/index.ts +36 -0
  265. package/src/types/auth.ts +32 -0
  266. package/src/types/index.ts +5 -0
  267. package/src/types/wire.ts +228 -0
  268. package/src/types/ws.ts +79 -0
  269. package/src/utils/activityCursor.ts +140 -0
  270. package/src/utils/apiClient.ts +257 -0
  271. package/src/utils/index.ts +35 -0
  272. package/src/utils/liquidation.ts +37 -0
  273. package/src/utils/mapActivity.ts +61 -0
  274. package/src/utils/mapFill.ts +47 -0
  275. package/src/utils/mapOrder.ts +201 -0
  276. package/src/utils/mapPosition.ts +44 -0
  277. package/src/utils/ohlcvInterval.ts +69 -0
  278. package/src/utils/ondoAsset.ts +10 -0
  279. package/src/utils/orderFormatting.ts +70 -0
  280. package/src/websocket/OndoWsProvider.ts +752 -0
@@ -0,0 +1,228 @@
1
+ /**
2
+ * Ondo REST wire types (`Ondo*`), mirroring the Ondo Perps OpenAPI schemas.
3
+ * All numeric quantities arrive as strings; timestamps are ISO 8601 strings
4
+ * unless a field says otherwise.
5
+ */
6
+
7
+ /** Cursor pair Ondo returns as a sibling of `result` on paginated endpoints. */
8
+ export interface OndoPageInfo {
9
+ prevCursor?: string
10
+ nextCursor?: string
11
+ }
12
+
13
+ /** @public */
14
+ export type OndoPositionDirection = 'long' | 'short' | 'neutral'
15
+
16
+ /** Mirrors Ondo's `ApiPosition`. @public */
17
+ export interface OndoPosition {
18
+ market: string
19
+ direction: OndoPositionDirection
20
+ /** Position size in base currency (unsigned magnitude). */
21
+ netQuantity: string
22
+ averageEntryPrice: string
23
+ usedMargin: string
24
+ unrealizedPnl: string
25
+ markPrice: string
26
+ liquidationPrice: string
27
+ bankruptcyPrice: string
28
+ maintenanceMargin: string
29
+ notionalValue: string
30
+ leverage: string
31
+ netFundingSinceNeutral: string
32
+ returnOnEquity: string
33
+ stopLossTriggerPrice?: string
34
+ takeProfitTriggerPrice?: string
35
+ }
36
+
37
+ /** @public */
38
+ export type OndoOrderSide = 'buy' | 'sell'
39
+
40
+ /** @public */
41
+ export type OndoOrderStatus =
42
+ | 'open'
43
+ | 'fullyfilled'
44
+ | 'canceled'
45
+ | 'pending'
46
+ | 'untriggered'
47
+
48
+ /** @public */
49
+ export type OndoOrderType =
50
+ | 'limit'
51
+ | 'market'
52
+ | 'stopMarket'
53
+ | 'takeProfitMarket'
54
+
55
+ /** @public */
56
+ export type OndoTimeInForce = 'GTC' | 'IOC'
57
+
58
+ /** @public */
59
+ export type OndoStopOrderType = 'stopLoss' | 'takeProfit'
60
+
61
+ /** Mirrors Ondo's `ApiOrder`. @public */
62
+ export interface OndoOrder {
63
+ orderId: string
64
+ side: OndoOrderSide
65
+ price: string
66
+ size: string
67
+ market: string
68
+ filledSize: string
69
+ lastFillSize: string
70
+ filledCost: string
71
+ fee: string
72
+ status: OndoOrderStatus
73
+ createdAt: string
74
+ type: OndoOrderType
75
+ clientOrderId?: string
76
+ parentOrderId?: string
77
+ realizedPnl?: string
78
+ feeRebate?: string
79
+ filledAt?: string
80
+ canceledAt?: string
81
+ cancelReason?: string
82
+ /** Not returned for market orders. */
83
+ timeInForce?: OndoTimeInForce
84
+ reduceOnly?: boolean
85
+ liquidationId?: string
86
+ /** Position-level TP/SL flag. */
87
+ closePosition?: boolean
88
+ stopOrderType?: OndoStopOrderType
89
+ triggerPrice?: string
90
+ }
91
+
92
+ /** @public */
93
+ export type OndoFillDirection =
94
+ | 'openLong'
95
+ | 'openShort'
96
+ | 'closeLong'
97
+ | 'closeShort'
98
+ | 'flipLongToShort'
99
+ | 'flipShortToLong'
100
+
101
+ /** Mirrors Ondo's `ApiFill`. @public */
102
+ export interface OndoFill {
103
+ id: string
104
+ orderId: string
105
+ market: string
106
+ price: string
107
+ size: string
108
+ side: OndoOrderSide
109
+ filledCost: string
110
+ fee: string
111
+ time: string
112
+ isMaker: boolean
113
+ clientOrderId?: string
114
+ parentOrderID?: string
115
+ direction?: OndoFillDirection
116
+ feeRebate?: string
117
+ pnl?: string
118
+ isADL?: boolean
119
+ }
120
+
121
+ /**
122
+ * Mirrors Ondo's `MarginAccountBalanceSummary`. Invariants per the docs:
123
+ * `marginBalance = walletBalance + unrealizedPnl`,
124
+ * `availableMargin = marginBalance − usedMargin`.
125
+ * @public
126
+ */
127
+ export interface OndoBalanceSummary {
128
+ walletBalance: string
129
+ realizedPnl: string
130
+ unrealizedPnl: string
131
+ marginBalance: string
132
+ usedMargin: string
133
+ availableMargin: string
134
+ withdrawableMargin: string
135
+ maintenanceMarginRequirement: string
136
+ totalMaintenanceMargin: string
137
+ marginRatio: string
138
+ leverage: string
139
+ underLiquidation: boolean
140
+ totalFundingPayments: string
141
+ totalTradingFees: string
142
+ totalPnL: string
143
+ }
144
+
145
+ /**
146
+ * `GET /v1/account/referral` result: the referral applied to the account.
147
+ * The endpoint is absent from Ondo's published OpenAPI spec; shape mirrors the
148
+ * venue web app. `result` is `null` when no referral is applied.
149
+ * @public
150
+ */
151
+ export interface OndoAccountReferral {
152
+ /** The referrer's code applied to this account. */
153
+ code: string
154
+ /** Rebate share of trading fees returned to the referred account. */
155
+ rebate?: number
156
+ }
157
+
158
+ /** Mirrors Ondo's `Contract` (perps contract ticker row). @public */
159
+ export interface OndoContract {
160
+ market: string
161
+ productType: string
162
+ contractType: string
163
+ baseCurrency: string
164
+ quoteCurrency: string
165
+ disabled: boolean
166
+ displayName?: string
167
+ lastPrice?: string
168
+ indexPrice?: string
169
+ fundingRate?: string
170
+ nextFundingRate?: string
171
+ nextFundingRateTimestamp?: string
172
+ makerFee?: string
173
+ takerFee?: string
174
+ openInterest?: string
175
+ openInterestUsd?: string
176
+ priceChangePercent?: string
177
+ isClosed?: boolean
178
+ }
179
+
180
+ /** Mirrors Ondo's `FundingFeeTransfer`. Carries no id — callers synthesize one. @public */
181
+ export interface OndoFundingFeeTransfer {
182
+ market: string
183
+ time: string
184
+ markPrice: string
185
+ positionSize: string
186
+ positionDirection: OndoPositionDirection
187
+ rate: string
188
+ /** Which side paid this interval. */
189
+ payer: OndoPositionDirection
190
+ /** Signed: positive = earned, negative = paid. */
191
+ amount: string
192
+ }
193
+
194
+ /** @public */
195
+ export type OndoLiquidationStatus = 'queued' | 'start' | 'retry' | 'stop'
196
+
197
+ /** Mirrors Ondo's `LiquidationEvent`. @public */
198
+ export interface OndoLiquidationEvent {
199
+ id: string
200
+ time: string
201
+ initiatedAt: string
202
+ accountId: string
203
+ status: OndoLiquidationStatus
204
+ insuranceFundUsed: string
205
+ adl: boolean
206
+ retryCount: number
207
+ triggeringPositions?: OndoPosition[]
208
+ filledQuoteSize?: string
209
+ filledQuantity?: string
210
+ reclaimOrderMargin?: boolean
211
+ }
212
+
213
+ /** @public */
214
+ export type OndoAccountState = 'open' | 'disabled' | 'offboarding' | 'closed'
215
+
216
+ /** Mirrors Ondo's `AccountInfo` (the `/v1/account` result). @public */
217
+ export interface OndoAccountInfo {
218
+ accountID: string
219
+ identifier: string
220
+ authType: string
221
+ accountState: OndoAccountState
222
+ withdrawalFeeUSD: string
223
+ termsVersion: number
224
+ termsUnixSecs: number
225
+ privacyVersion: number
226
+ privacyUnixSecs: number
227
+ marketingConsent: string
228
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Ondo WebSocket wire types. Client ops are `{op, ...args}` envelopes (only
3
+ * `login` nests its arguments); server data frames are
4
+ * `{type: 'update', channel, data}`.
5
+ */
6
+
7
+ import type { OndoFill, OndoOrder, OndoPosition } from './wire.js'
8
+
9
+ /** Level tuple as streamed: `[price, size]`, both decimal strings. @public */
10
+ export type OndoBookLevel = [string, string]
11
+
12
+ /** Streamed order-book snapshot (`depthBooksPerps`/`topOfBooksPerps`). @public */
13
+ export interface OndoBookSnapshot {
14
+ market: string
15
+ time: string
16
+ asks: OndoBookLevel[]
17
+ bids: OndoBookLevel[]
18
+ depthLevels?: string
19
+ }
20
+
21
+ /** Streamed public trade (`tradesPerps`). @public */
22
+ export interface OndoWsTrade {
23
+ market: string
24
+ price: string
25
+ size: string
26
+ cost: string
27
+ aggressor_side: 'buy' | 'sell'
28
+ time: string
29
+ id: string
30
+ }
31
+
32
+ /**
33
+ * Streamed candlestick (`kLinePerps`). Prices and volume arrive as numbers,
34
+ * unlike the string-typed REST shapes; `s`/`e`/`t` are Unix seconds.
35
+ * @public
36
+ */
37
+ export interface OndoKline {
38
+ m: string
39
+ t: number
40
+ s: number
41
+ e: number
42
+ o: number
43
+ h: number
44
+ l: number
45
+ c: number
46
+ v: number
47
+ x: boolean
48
+ }
49
+
50
+ /** Streamed mark price (`markPricesPerps`). @public */
51
+ export interface OndoMarkPrice {
52
+ market: string
53
+ markPrice: string
54
+ }
55
+
56
+ /** Streamed funding rate (`fundingRatesPerps`). @public */
57
+ export interface OndoFundingRate {
58
+ market: string
59
+ rate: string
60
+ intervalEnds: string
61
+ premiums?: unknown[]
62
+ }
63
+
64
+ /** Server frame envelope. Non-`update` types are acks or errors. @public */
65
+ export type OndoWsMessage =
66
+ | { type: 'update'; channel: 'depthBooksPerps'; data: OndoBookSnapshot[] }
67
+ | { type: 'update'; channel: 'tradesPerps'; data: OndoWsTrade[] }
68
+ | { type: 'update'; channel: 'kLinePerps'; data: OndoKline }
69
+ | { type: 'update'; channel: 'markPricesPerps'; data: OndoMarkPrice[] }
70
+ | { type: 'update'; channel: 'fundingRatesPerps'; data: OndoFundingRate[] }
71
+ | { type: 'update'; channel: 'ordersPerps'; data: OndoOrder[] }
72
+ | { type: 'update'; channel: 'fillsPerps'; data: OndoFill[] }
73
+ | { type: 'update'; channel: 'positionsPerps'; data: OndoPosition[] }
74
+ | { type: 'update'; channel: string; data: unknown }
75
+ | { type: 'pong' }
76
+ | { type: 'loggedIn'; msg?: string }
77
+ | { type: 'subscribed'; channel?: string }
78
+ | { type: 'unsubscribed'; channel?: string }
79
+ | { type: 'error'; msg?: string }
@@ -0,0 +1,140 @@
1
+ import { PerpsError } from '@lifi/perps-sdk'
2
+ import { type ActivityItem, PerpsErrorCode } from '@lifi/perps-types'
3
+
4
+ /**
5
+ * Per-endpoint cursor envelope for Ondo activity pagination.
6
+ *
7
+ * Each key holds the `pageInfo.nextCursor` returned by that endpoint on the
8
+ * previous call. When a key is **present** with a non-empty string the
9
+ * corresponding endpoint will be re-fetched at that cursor on the next call;
10
+ * when a key is **absent** the endpoint is treated as exhausted (or never
11
+ * paged because the type filter excluded it) and skipped.
12
+ *
13
+ * The envelope is round-tripped through `cursor` as base64url JSON so callers
14
+ * don't need to know the per-endpoint shape.
15
+ * @public
16
+ */
17
+ export interface OndoActivityCursor {
18
+ fundings?: string
19
+ liquidations?: string
20
+ /**
21
+ * Already-fetched, merged-and-sorted rows that did not fit under the page
22
+ * `limit`. The upstream cursors above have advanced past these rows, so they
23
+ * are replayed (prepended) on the next page before any fresh fetch — without
24
+ * them the tail would be lost forever.
25
+ */
26
+ overflow?: ActivityItem[]
27
+ }
28
+
29
+ const CURSOR_KEYS = ['fundings', 'liquidations'] as const
30
+
31
+ const isNonEmpty = (v: string | undefined): v is string =>
32
+ typeof v === 'string' && v.length > 0
33
+
34
+ /**
35
+ * Encode an `OndoActivityCursor` as the base64url-of-JSON cursor string
36
+ * persisted between activity pages. Returns `undefined` when every
37
+ * per-endpoint key is empty and no `overflow` rows remain — the caller
38
+ * should report `hasMore: false` and omit `cursor` from `Pagination` then.
39
+ *
40
+ * Browser-direct: `Buffer` is Node-only. We use `btoa` over a Latin-1
41
+ * encoding of the UTF-8 bytes and then rewrite `+/=` to base64url. This is
42
+ * the same byte sequence Node's `Buffer.from(json, 'utf8').toString('base64url')`
43
+ * produces, so cursors round-trip across environments.
44
+ * @public
45
+ */
46
+ export const encodeActivityCursor = (
47
+ env: OndoActivityCursor
48
+ ): string | undefined => {
49
+ const compact: OndoActivityCursor = {}
50
+ for (const key of CURSOR_KEYS) {
51
+ if (isNonEmpty(env[key])) {
52
+ compact[key] = env[key]
53
+ }
54
+ }
55
+ if (env.overflow !== undefined && env.overflow.length > 0) {
56
+ compact.overflow = env.overflow
57
+ }
58
+ if (Object.keys(compact).length === 0) {
59
+ return undefined
60
+ }
61
+ return toBase64Url(JSON.stringify(compact))
62
+ }
63
+
64
+ /**
65
+ * Decode a previously-encoded activity cursor. Returns `undefined` for an
66
+ * absent cursor (first page) and throws {@link PerpsError} with
67
+ * `ValidationError` if the string is malformed — we'd rather fail loudly than
68
+ * silently re-page from page 1 and re-deliver already-paginated rows.
69
+ * @public
70
+ */
71
+ export const decodeActivityCursor = (
72
+ cursor: string | undefined
73
+ ): OndoActivityCursor | undefined => {
74
+ if (cursor === undefined) {
75
+ return undefined
76
+ }
77
+ let parsed: unknown
78
+ try {
79
+ parsed = JSON.parse(fromBase64Url(cursor))
80
+ } catch {
81
+ throw new PerpsError(
82
+ PerpsErrorCode.ValidationError,
83
+ 'Invalid Ondo activity cursor: not base64url-encoded JSON'
84
+ )
85
+ }
86
+ if (parsed === null || typeof parsed !== 'object') {
87
+ throw new PerpsError(
88
+ PerpsErrorCode.ValidationError,
89
+ 'Invalid Ondo activity cursor: expected JSON object'
90
+ )
91
+ }
92
+ const cursorRecord = parsed as Record<string, unknown>
93
+ const env: OndoActivityCursor = {}
94
+ for (const key of CURSOR_KEYS) {
95
+ const v = cursorRecord[key]
96
+ if (v === undefined) {
97
+ continue
98
+ }
99
+ if (typeof v !== 'string') {
100
+ throw new PerpsError(
101
+ PerpsErrorCode.ValidationError,
102
+ `Invalid Ondo activity cursor: ${key} must be a string`
103
+ )
104
+ }
105
+ env[key] = v
106
+ }
107
+ const overflow = cursorRecord.overflow
108
+ if (overflow !== undefined) {
109
+ if (!Array.isArray(overflow)) {
110
+ throw new PerpsError(
111
+ PerpsErrorCode.ValidationError,
112
+ 'Invalid Ondo activity cursor: overflow must be an array'
113
+ )
114
+ }
115
+ env.overflow = overflow as ActivityItem[]
116
+ }
117
+ return env
118
+ }
119
+
120
+ const toBase64Url = (s: string): string => {
121
+ if (typeof Buffer !== 'undefined') {
122
+ return Buffer.from(s, 'utf8').toString('base64url')
123
+ }
124
+ const utf8 = unescape(encodeURIComponent(s))
125
+ return btoa(utf8).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')
126
+ }
127
+
128
+ const fromBase64Url = (s: string): string => {
129
+ if (typeof Buffer !== 'undefined') {
130
+ return Buffer.from(s, 'base64url').toString('utf8')
131
+ }
132
+ const padded = s.replace(/-/g, '+').replace(/_/g, '/') + padFor(s)
133
+ const decoded = atob(padded)
134
+ return decodeURIComponent(escape(decoded))
135
+ }
136
+
137
+ const padFor = (s: string): string => {
138
+ const rem = s.length % 4
139
+ return rem === 0 ? '' : '='.repeat(4 - rem)
140
+ }
@@ -0,0 +1,257 @@
1
+ import {
2
+ DISABLED_RETRY,
3
+ fetchWithRetry,
4
+ PerpsError,
5
+ type ResolvedRetryPolicy,
6
+ } from '@lifi/perps-sdk'
7
+ import { PerpsErrorCode } from '@lifi/perps-types'
8
+ import type { OndoGenericResponse } from '../types/auth.js'
9
+ import type { OndoPageInfo } from '../types/wire.js'
10
+
11
+ /** @internal */
12
+ export type ApiParams = Record<string, string | number | boolean>
13
+
14
+ /** One page of a paginated Ondo response: `pageInfo` is a SIBLING of `result`. @public */
15
+ export interface OndoPage<T> {
16
+ result: T[]
17
+ pageInfo: OndoPageInfo | undefined
18
+ }
19
+
20
+ /** @internal */
21
+ export type OndoHttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE'
22
+
23
+ /**
24
+ * Ondo request failure — a non-2xx HTTP status, a `success: false` envelope,
25
+ * or a body that is not a `GenericResponse` envelope at all. `errorCode`
26
+ * carries the wire `error_code` when the envelope advertised one.
27
+ *
28
+ * @public
29
+ */
30
+ export class OndoApiError extends PerpsError {
31
+ readonly errorCode: string | undefined
32
+
33
+ constructor(message: string, errorCode?: string) {
34
+ super(PerpsErrorCode.ThirdPartyError, message)
35
+ this.errorCode = errorCode
36
+ }
37
+ }
38
+
39
+ /**
40
+ * The Ondo session JWT was rejected (HTTP 401). Distinct from
41
+ * {@link OndoApiError} so callers can evict the stored token and re-run the
42
+ * SIWE login instead of surfacing a generic venue failure.
43
+ *
44
+ * @public
45
+ */
46
+ export class OndoSessionExpiredError extends PerpsError {
47
+ constructor(message: string) {
48
+ super(PerpsErrorCode.Unauthorized, message)
49
+ }
50
+ }
51
+
52
+ /** @internal */
53
+ export const ONDO_RETRY_DEFAULTS: ResolvedRetryPolicy = {
54
+ enabled: true,
55
+ maxAttempts: 2,
56
+ baseDelayMs: 1_000,
57
+ maxDelayMs: 30_000,
58
+ respectRetryAfter: true,
59
+ classify: ({ response }) => {
60
+ if (response.status === 429) {
61
+ return 'retry-rate-limit'
62
+ }
63
+ if (
64
+ response.status === 502 ||
65
+ response.status === 503 ||
66
+ response.status === 504
67
+ ) {
68
+ return 'retry-server'
69
+ }
70
+ return 'fail'
71
+ },
72
+ }
73
+
74
+ /** @internal */
75
+ export interface OndoApiClientOptions {
76
+ signal?: AbortSignal
77
+ policy?: ResolvedRetryPolicy
78
+ fetchImpl?: typeof fetch
79
+ }
80
+
81
+ /** @internal */
82
+ export interface OndoRequestOptions {
83
+ params?: ApiParams
84
+ /** Ondo session JWT, sent as `Authorization: Bearer <token>`. */
85
+ authToken?: string
86
+ }
87
+
88
+ const isGenericResponse = (
89
+ data: unknown
90
+ ): data is OndoGenericResponse<unknown> =>
91
+ typeof data === 'object' &&
92
+ data !== null &&
93
+ typeof (data as { success?: unknown }).success === 'boolean'
94
+
95
+ /**
96
+ * HTTP boundary against Ondo's REST API.
97
+ *
98
+ * Browser-direct by design: the session JWT lives client-side only, so
99
+ * credentialed calls (`authToken` option) go straight to Ondo — never through
100
+ * the LI.FI backend. Every response is an `OndoGenericResponse` envelope; the
101
+ * client unwraps `result` on success and throws {@link OndoApiError} (carrying
102
+ * the wire `error_code`) otherwise. An HTTP 401 throws
103
+ * {@link OndoSessionExpiredError} so callers can re-run the SIWE login.
104
+ * @public
105
+ */
106
+ export class OndoApiClient {
107
+ private readonly baseUrl: string
108
+ private readonly signal: AbortSignal | undefined
109
+ private readonly policy: ResolvedRetryPolicy
110
+ private readonly fetchImpl: typeof fetch | undefined
111
+
112
+ constructor(baseUrl: string, options?: OndoApiClientOptions) {
113
+ this.baseUrl = baseUrl.replace(/\/$/, '')
114
+ this.signal = options?.signal
115
+ this.policy = options?.policy ?? ONDO_RETRY_DEFAULTS
116
+ this.fetchImpl = options?.fetchImpl
117
+ }
118
+
119
+ async get<T>(path: string, options?: OndoRequestOptions): Promise<T> {
120
+ const { status, data } = await this.perform(path, {
121
+ method: 'GET',
122
+ params: options?.params,
123
+ authToken: options?.authToken,
124
+ policy: this.policy,
125
+ })
126
+ return this.unwrap<T>(path, status, data)
127
+ }
128
+
129
+ /**
130
+ * GET a paginated endpoint, preserving the `pageInfo` sibling that
131
+ * {@link get}'s envelope unwrap would otherwise drop.
132
+ */
133
+ async getPage<T>(
134
+ path: string,
135
+ options?: OndoRequestOptions
136
+ ): Promise<OndoPage<T>> {
137
+ const { status, data } = await this.perform(path, {
138
+ method: 'GET',
139
+ params: options?.params,
140
+ authToken: options?.authToken,
141
+ policy: this.policy,
142
+ })
143
+ const result = this.unwrap<T[] | null>(path, status, data)
144
+ const pageInfo = (data as { pageInfo?: OndoPageInfo }).pageInfo
145
+ return { result: result ?? [], pageInfo }
146
+ }
147
+
148
+ /**
149
+ * Arbitrary-method request with caller-prebuilt headers — the execution
150
+ * surface for credential-bearing `RestCallSignedActionStep`s, whose
151
+ * `Authorization` header is attached by `signActions` from the token store.
152
+ * Only GET is ever retried; writes are not idempotent.
153
+ */
154
+ async send<T>(
155
+ method: OndoHttpMethod,
156
+ path: string,
157
+ options?: { body?: unknown; headers?: Record<string, string> }
158
+ ): Promise<T> {
159
+ const { status, data } = await this.perform(path, {
160
+ method,
161
+ body: options?.body,
162
+ headers: options?.headers,
163
+ policy: method === 'GET' ? this.policy : DISABLED_RETRY,
164
+ })
165
+ return this.unwrap<T>(path, status, data)
166
+ }
167
+
168
+ /**
169
+ * POSTs are never auto-retried regardless of policy: Ondo writes (order
170
+ * placement, login completion) are not idempotent, and a retried request
171
+ * whose first attempt landed would double-submit.
172
+ */
173
+ async post<T>(
174
+ path: string,
175
+ body?: unknown,
176
+ options?: Pick<OndoRequestOptions, 'authToken'>
177
+ ): Promise<T> {
178
+ const { status, data } = await this.perform(path, {
179
+ method: 'POST',
180
+ body,
181
+ authToken: options?.authToken,
182
+ policy: DISABLED_RETRY,
183
+ })
184
+ return this.unwrap<T>(path, status, data)
185
+ }
186
+
187
+ private buildUrl(path: string, params?: ApiParams): string {
188
+ const url = `${this.baseUrl}${path}`
189
+ if (!params || Object.keys(params).length === 0) {
190
+ return url
191
+ }
192
+ const qs = Object.entries(params)
193
+ .map(
194
+ ([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`
195
+ )
196
+ .join('&')
197
+ return `${url}?${qs}`
198
+ }
199
+
200
+ private async perform(
201
+ path: string,
202
+ options: {
203
+ method: OndoHttpMethod
204
+ params?: ApiParams
205
+ body?: unknown
206
+ authToken?: string
207
+ headers?: Record<string, string>
208
+ policy: ResolvedRetryPolicy
209
+ }
210
+ ): Promise<{ status: number; data: unknown }> {
211
+ const headers: Record<string, string> = {
212
+ Accept: 'application/json',
213
+ ...options.headers,
214
+ }
215
+ if (options.authToken) {
216
+ headers.Authorization = `Bearer ${options.authToken}`
217
+ }
218
+ const init: RequestInit = { method: options.method, headers }
219
+ if (options.method !== 'GET' && options.method !== 'DELETE') {
220
+ headers['Content-Type'] = 'application/json'
221
+ init.body = JSON.stringify(options.body ?? {})
222
+ }
223
+ const response = await fetchWithRetry(
224
+ this.buildUrl(path, options.params),
225
+ init,
226
+ { policy: options.policy, fetchImpl: this.fetchImpl, signal: this.signal }
227
+ )
228
+ const data: unknown = await response.json().catch(() => undefined)
229
+ return { status: response.status, data }
230
+ }
231
+
232
+ private unwrap<T>(path: string, status: number, data: unknown): T {
233
+ if (status === 401) {
234
+ throw new OndoSessionExpiredError(
235
+ `Ondo rejected the session token for ${path}`
236
+ )
237
+ }
238
+ if (status < 200 || status >= 300) {
239
+ throw new OndoApiError(
240
+ `Ondo API request failed: ${status} — ${JSON.stringify(data).slice(0, 200)}`,
241
+ isGenericResponse(data) ? data.error_code : undefined
242
+ )
243
+ }
244
+ if (!isGenericResponse(data)) {
245
+ throw new OndoApiError(
246
+ `Ondo API returned an unexpected body for ${path}: ${JSON.stringify(data).slice(0, 200)}`
247
+ )
248
+ }
249
+ if (!data.success) {
250
+ throw new OndoApiError(
251
+ `Ondo API error for ${path}: ${data.error_code ?? 'unknown'} — ${data.error ?? 'no error message'}`,
252
+ data.error_code
253
+ )
254
+ }
255
+ return data.result as T
256
+ }
257
+ }