@lifi/perps-sdk-provider-lighter 35.0.0 → 36.0.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 (248) hide show
  1. package/dist/cjs/LighterProvider.d.ts.map +1 -1
  2. package/dist/cjs/LighterProvider.js +101 -58
  3. package/dist/cjs/LighterProvider.js.map +1 -1
  4. package/dist/cjs/accountSummary.d.ts +1 -2
  5. package/dist/cjs/accountSummary.d.ts.map +1 -1
  6. package/dist/cjs/accountSummary.js +9 -16
  7. package/dist/cjs/accountSummary.js.map +1 -1
  8. package/dist/cjs/availableToTrade.d.ts +1 -2
  9. package/dist/cjs/availableToTrade.d.ts.map +1 -1
  10. package/dist/cjs/availableToTrade.js +8 -12
  11. package/dist/cjs/availableToTrade.js.map +1 -1
  12. package/dist/cjs/constants.d.ts +1 -0
  13. package/dist/cjs/constants.d.ts.map +1 -1
  14. package/dist/cjs/constants.js +2 -1
  15. package/dist/cjs/constants.js.map +1 -1
  16. package/dist/cjs/index.d.ts +1 -1
  17. package/dist/cjs/index.d.ts.map +1 -1
  18. package/dist/cjs/index.js +2 -1
  19. package/dist/cjs/index.js.map +1 -1
  20. package/dist/cjs/signers/LighterSigner.d.ts.map +1 -1
  21. package/dist/cjs/signers/LighterSigner.js +2 -6
  22. package/dist/cjs/signers/LighterSigner.js.map +1 -1
  23. package/dist/cjs/types/submit.d.ts +5 -0
  24. package/dist/cjs/types/submit.d.ts.map +1 -1
  25. package/dist/cjs/utils/index.d.ts +3 -3
  26. package/dist/cjs/utils/index.d.ts.map +1 -1
  27. package/dist/cjs/utils/index.js +5 -6
  28. package/dist/cjs/utils/index.js.map +1 -1
  29. package/dist/cjs/utils/mapFill.d.ts +1 -1
  30. package/dist/cjs/utils/mapFill.d.ts.map +1 -1
  31. package/dist/cjs/utils/mapFill.js +44 -31
  32. package/dist/cjs/utils/mapFill.js.map +1 -1
  33. package/dist/cjs/utils/mapOpenPositions.d.ts +3 -1
  34. package/dist/cjs/utils/mapOpenPositions.d.ts.map +1 -1
  35. package/dist/cjs/utils/mapOpenPositions.js +20 -4
  36. package/dist/cjs/utils/mapOpenPositions.js.map +1 -1
  37. package/dist/cjs/utils/mapOrder.d.ts +1 -1
  38. package/dist/cjs/utils/mapOrder.d.ts.map +1 -1
  39. package/dist/cjs/utils/mapOrder.js +64 -26
  40. package/dist/cjs/utils/mapOrder.js.map +1 -1
  41. package/dist/cjs/utils/mapPortfolioHistory.d.ts +1 -2
  42. package/dist/cjs/utils/mapPortfolioHistory.d.ts.map +1 -1
  43. package/dist/cjs/utils/mapPortfolioHistory.js +29 -21
  44. package/dist/cjs/utils/mapPortfolioHistory.js.map +1 -1
  45. package/dist/cjs/utils/mapPosition.d.ts +3 -3
  46. package/dist/cjs/utils/mapPosition.d.ts.map +1 -1
  47. package/dist/cjs/utils/mapPosition.js +35 -35
  48. package/dist/cjs/utils/mapPosition.js.map +1 -1
  49. package/dist/cjs/utils/rowTimestamp.d.ts +2 -0
  50. package/dist/cjs/utils/rowTimestamp.d.ts.map +1 -0
  51. package/dist/cjs/utils/rowTimestamp.js +14 -0
  52. package/dist/cjs/utils/rowTimestamp.js.map +1 -0
  53. package/dist/cjs/utils/settlementPool.d.ts +2 -3
  54. package/dist/cjs/utils/settlementPool.d.ts.map +1 -1
  55. package/dist/cjs/utils/settlementPool.js +8 -7
  56. package/dist/cjs/utils/settlementPool.js.map +1 -1
  57. package/dist/cjs/utils/spotPrice.d.ts +3 -4
  58. package/dist/cjs/utils/spotPrice.d.ts.map +1 -1
  59. package/dist/cjs/utils/spotPrice.js +6 -11
  60. package/dist/cjs/utils/spotPrice.js.map +1 -1
  61. package/dist/cjs/utils/time.d.ts.map +1 -1
  62. package/dist/cjs/utils/time.js +3 -2
  63. package/dist/cjs/utils/time.js.map +1 -1
  64. package/dist/cjs/utils/transferMargin.d.ts.map +1 -1
  65. package/dist/cjs/utils/transferMargin.js +7 -15
  66. package/dist/cjs/utils/transferMargin.js.map +1 -1
  67. package/dist/cjs/utils/withdrawableBalances.d.ts +1 -1
  68. package/dist/cjs/utils/withdrawableBalances.d.ts.map +1 -1
  69. package/dist/cjs/utils/withdrawableBalances.js +12 -17
  70. package/dist/cjs/utils/withdrawableBalances.js.map +1 -1
  71. package/dist/cjs/utils/withdrawalTypes.d.ts +17 -0
  72. package/dist/cjs/utils/withdrawalTypes.d.ts.map +1 -0
  73. package/dist/cjs/utils/withdrawalTypes.js +58 -0
  74. package/dist/cjs/utils/withdrawalTypes.js.map +1 -0
  75. package/dist/cjs/websocket/LighterWsProvider.d.ts.map +1 -1
  76. package/dist/cjs/websocket/LighterWsProvider.js +46 -58
  77. package/dist/cjs/websocket/LighterWsProvider.js.map +1 -1
  78. package/dist/cjs/websocket/orderBookSide.d.ts +19 -0
  79. package/dist/cjs/websocket/orderBookSide.d.ts.map +1 -0
  80. package/dist/cjs/websocket/orderBookSide.js +71 -0
  81. package/dist/cjs/websocket/orderBookSide.js.map +1 -0
  82. package/dist/esm/LighterProvider.d.ts.map +1 -1
  83. package/dist/esm/LighterProvider.js +116 -62
  84. package/dist/esm/LighterProvider.js.map +1 -1
  85. package/dist/esm/accountSummary.d.ts +1 -2
  86. package/dist/esm/accountSummary.d.ts.map +1 -1
  87. package/dist/esm/accountSummary.js +10 -14
  88. package/dist/esm/accountSummary.js.map +1 -1
  89. package/dist/esm/availableToTrade.d.ts +1 -2
  90. package/dist/esm/availableToTrade.d.ts.map +1 -1
  91. package/dist/esm/availableToTrade.js +9 -10
  92. package/dist/esm/availableToTrade.js.map +1 -1
  93. package/dist/esm/constants.d.ts +8 -0
  94. package/dist/esm/constants.d.ts.map +1 -1
  95. package/dist/esm/constants.js +8 -0
  96. package/dist/esm/constants.js.map +1 -1
  97. package/dist/esm/index.d.ts +1 -1
  98. package/dist/esm/index.d.ts.map +1 -1
  99. package/dist/esm/index.js +1 -1
  100. package/dist/esm/index.js.map +1 -1
  101. package/dist/esm/signers/LighterSigner.d.ts.map +1 -1
  102. package/dist/esm/signers/LighterSigner.js +3 -4
  103. package/dist/esm/signers/LighterSigner.js.map +1 -1
  104. package/dist/esm/types/submit.d.ts +14 -0
  105. package/dist/esm/types/submit.d.ts.map +1 -1
  106. package/dist/esm/utils/index.d.ts +3 -3
  107. package/dist/esm/utils/index.d.ts.map +1 -1
  108. package/dist/esm/utils/index.js +2 -3
  109. package/dist/esm/utils/index.js.map +1 -1
  110. package/dist/esm/utils/mapFill.d.ts +1 -1
  111. package/dist/esm/utils/mapFill.d.ts.map +1 -1
  112. package/dist/esm/utils/mapFill.js +51 -35
  113. package/dist/esm/utils/mapFill.js.map +1 -1
  114. package/dist/esm/utils/mapOpenPositions.d.ts +17 -3
  115. package/dist/esm/utils/mapOpenPositions.d.ts.map +1 -1
  116. package/dist/esm/utils/mapOpenPositions.js +31 -5
  117. package/dist/esm/utils/mapOpenPositions.js.map +1 -1
  118. package/dist/esm/utils/mapOrder.d.ts +6 -2
  119. package/dist/esm/utils/mapOrder.d.ts.map +1 -1
  120. package/dist/esm/utils/mapOrder.js +70 -25
  121. package/dist/esm/utils/mapOrder.js.map +1 -1
  122. package/dist/esm/utils/mapPortfolioHistory.d.ts +6 -3
  123. package/dist/esm/utils/mapPortfolioHistory.d.ts.map +1 -1
  124. package/dist/esm/utils/mapPortfolioHistory.js +34 -19
  125. package/dist/esm/utils/mapPortfolioHistory.js.map +1 -1
  126. package/dist/esm/utils/mapPosition.d.ts +12 -8
  127. package/dist/esm/utils/mapPosition.d.ts.map +1 -1
  128. package/dist/esm/utils/mapPosition.js +45 -38
  129. package/dist/esm/utils/mapPosition.js.map +1 -1
  130. package/dist/esm/utils/rowTimestamp.d.ts +6 -0
  131. package/dist/esm/utils/rowTimestamp.d.ts.map +1 -0
  132. package/dist/esm/utils/rowTimestamp.js +14 -0
  133. package/dist/esm/utils/rowTimestamp.js.map +1 -0
  134. package/dist/esm/utils/settlementPool.d.ts +2 -3
  135. package/dist/esm/utils/settlementPool.d.ts.map +1 -1
  136. package/dist/esm/utils/settlementPool.js +8 -7
  137. package/dist/esm/utils/settlementPool.js.map +1 -1
  138. package/dist/esm/utils/spotPrice.d.ts +3 -4
  139. package/dist/esm/utils/spotPrice.d.ts.map +1 -1
  140. package/dist/esm/utils/spotPrice.js +6 -8
  141. package/dist/esm/utils/spotPrice.js.map +1 -1
  142. package/dist/esm/utils/time.d.ts +10 -2
  143. package/dist/esm/utils/time.d.ts.map +1 -1
  144. package/dist/esm/utils/time.js +13 -4
  145. package/dist/esm/utils/time.js.map +1 -1
  146. package/dist/esm/utils/transferMargin.d.ts.map +1 -1
  147. package/dist/esm/utils/transferMargin.js +8 -13
  148. package/dist/esm/utils/transferMargin.js.map +1 -1
  149. package/dist/esm/utils/withdrawableBalances.d.ts +5 -3
  150. package/dist/esm/utils/withdrawableBalances.d.ts.map +1 -1
  151. package/dist/esm/utils/withdrawableBalances.js +17 -17
  152. package/dist/esm/utils/withdrawableBalances.js.map +1 -1
  153. package/dist/esm/utils/withdrawalTypes.d.ts +45 -0
  154. package/dist/esm/utils/withdrawalTypes.d.ts.map +1 -0
  155. package/dist/esm/utils/withdrawalTypes.js +68 -0
  156. package/dist/esm/utils/withdrawalTypes.js.map +1 -0
  157. package/dist/esm/websocket/LighterWsProvider.d.ts.map +1 -1
  158. package/dist/esm/websocket/LighterWsProvider.js +48 -57
  159. package/dist/esm/websocket/LighterWsProvider.js.map +1 -1
  160. package/dist/esm/websocket/orderBookSide.d.ts +33 -0
  161. package/dist/esm/websocket/orderBookSide.d.ts.map +1 -0
  162. package/dist/esm/websocket/orderBookSide.js +76 -0
  163. package/dist/esm/websocket/orderBookSide.js.map +1 -0
  164. package/dist/types/LighterProvider.d.ts.map +1 -1
  165. package/dist/types/accountSummary.d.ts +1 -2
  166. package/dist/types/accountSummary.d.ts.map +1 -1
  167. package/dist/types/availableToTrade.d.ts +1 -2
  168. package/dist/types/availableToTrade.d.ts.map +1 -1
  169. package/dist/types/constants.d.ts +8 -0
  170. package/dist/types/constants.d.ts.map +1 -1
  171. package/dist/types/index.d.ts +1 -1
  172. package/dist/types/index.d.ts.map +1 -1
  173. package/dist/types/signers/LighterSigner.d.ts.map +1 -1
  174. package/dist/types/types/submit.d.ts +14 -0
  175. package/dist/types/types/submit.d.ts.map +1 -1
  176. package/dist/types/utils/index.d.ts +3 -3
  177. package/dist/types/utils/index.d.ts.map +1 -1
  178. package/dist/types/utils/mapFill.d.ts +1 -1
  179. package/dist/types/utils/mapFill.d.ts.map +1 -1
  180. package/dist/types/utils/mapOpenPositions.d.ts +17 -3
  181. package/dist/types/utils/mapOpenPositions.d.ts.map +1 -1
  182. package/dist/types/utils/mapOrder.d.ts +6 -2
  183. package/dist/types/utils/mapOrder.d.ts.map +1 -1
  184. package/dist/types/utils/mapPortfolioHistory.d.ts +6 -3
  185. package/dist/types/utils/mapPortfolioHistory.d.ts.map +1 -1
  186. package/dist/types/utils/mapPosition.d.ts +12 -8
  187. package/dist/types/utils/mapPosition.d.ts.map +1 -1
  188. package/dist/types/utils/rowTimestamp.d.ts +6 -0
  189. package/dist/types/utils/rowTimestamp.d.ts.map +1 -0
  190. package/dist/types/utils/settlementPool.d.ts +2 -3
  191. package/dist/types/utils/settlementPool.d.ts.map +1 -1
  192. package/dist/types/utils/spotPrice.d.ts +3 -4
  193. package/dist/types/utils/spotPrice.d.ts.map +1 -1
  194. package/dist/types/utils/time.d.ts +10 -2
  195. package/dist/types/utils/time.d.ts.map +1 -1
  196. package/dist/types/utils/transferMargin.d.ts.map +1 -1
  197. package/dist/types/utils/withdrawableBalances.d.ts +5 -3
  198. package/dist/types/utils/withdrawableBalances.d.ts.map +1 -1
  199. package/dist/types/utils/withdrawalTypes.d.ts +45 -0
  200. package/dist/types/utils/withdrawalTypes.d.ts.map +1 -0
  201. package/dist/types/websocket/LighterWsProvider.d.ts.map +1 -1
  202. package/dist/types/websocket/orderBookSide.d.ts +33 -0
  203. package/dist/types/websocket/orderBookSide.d.ts.map +1 -0
  204. package/package.json +3 -3
  205. package/src/LighterProvider.ts +236 -100
  206. package/src/accountSummary.ts +41 -22
  207. package/src/availableToTrade.ts +38 -15
  208. package/src/constants.ts +9 -0
  209. package/src/index.ts +1 -0
  210. package/src/signers/LighterSigner.ts +11 -4
  211. package/src/types/submit.ts +15 -0
  212. package/src/utils/index.ts +9 -3
  213. package/src/utils/mapFill.ts +82 -43
  214. package/src/utils/mapOpenPositions.ts +45 -6
  215. package/src/utils/mapOrder.ts +99 -28
  216. package/src/utils/mapPortfolioHistory.ts +78 -24
  217. package/src/utils/mapPosition.ts +67 -44
  218. package/src/utils/rowTimestamp.ts +15 -0
  219. package/src/utils/settlementPool.ts +36 -12
  220. package/src/utils/spotPrice.ts +18 -12
  221. package/src/utils/time.ts +14 -4
  222. package/src/utils/transferMargin.ts +28 -17
  223. package/src/utils/withdrawableBalances.ts +34 -20
  224. package/src/utils/withdrawalTypes.ts +125 -0
  225. package/src/websocket/LighterWsProvider.ts +75 -92
  226. package/src/websocket/orderBookSide.ts +106 -0
  227. package/dist/cjs/utils/decimal.d.ts +0 -5
  228. package/dist/cjs/utils/decimal.d.ts.map +0 -1
  229. package/dist/cjs/utils/decimal.js +0 -38
  230. package/dist/cjs/utils/decimal.js.map +0 -1
  231. package/dist/cjs/utils/liquidation.d.ts +0 -4
  232. package/dist/cjs/utils/liquidation.d.ts.map +0 -1
  233. package/dist/cjs/utils/liquidation.js +0 -16
  234. package/dist/cjs/utils/liquidation.js.map +0 -1
  235. package/dist/esm/utils/decimal.d.ts +0 -15
  236. package/dist/esm/utils/decimal.d.ts.map +0 -1
  237. package/dist/esm/utils/decimal.js +0 -39
  238. package/dist/esm/utils/decimal.js.map +0 -1
  239. package/dist/esm/utils/liquidation.d.ts +0 -22
  240. package/dist/esm/utils/liquidation.d.ts.map +0 -1
  241. package/dist/esm/utils/liquidation.js +0 -31
  242. package/dist/esm/utils/liquidation.js.map +0 -1
  243. package/dist/types/utils/decimal.d.ts +0 -15
  244. package/dist/types/utils/decimal.d.ts.map +0 -1
  245. package/dist/types/utils/liquidation.d.ts +0 -22
  246. package/dist/types/utils/liquidation.d.ts.map +0 -1
  247. package/src/utils/decimal.ts +0 -52
  248. package/src/utils/liquidation.ts +0 -39
@@ -1,4 +1,9 @@
1
- import { PerpsError } from '@lifi/perps-sdk'
1
+ import {
2
+ addDecimalString,
3
+ PerpsError,
4
+ subtractDecimalString,
5
+ unknownToDecimalString,
6
+ } from '@lifi/perps-sdk'
2
7
  import type {
3
8
  AccountResponse,
4
9
  AccountSummary,
@@ -6,14 +11,12 @@ import type {
6
11
  Position,
7
12
  } from '@lifi/perps-types'
8
13
  import { PerpsErrorCode } from '@lifi/perps-types'
9
- import Big from 'big.js'
10
14
  import { atLeastZero } from './availableToTrade.js'
11
15
  import {
12
16
  LIGHTER_COLLATERAL_ASSETS,
13
17
  LIGHTER_PROVIDER_KEY,
14
18
  LIGHTER_RH_PROVIDER_KEY,
15
19
  } from './constants.js'
16
- import { toRequiredBig } from './utils/decimal.js'
17
20
 
18
21
  /**
19
22
  * The Lighter arm of `account.config`.
@@ -40,11 +43,15 @@ export const lighterConfig = (
40
43
  * Add marked holdings excluded from Lighter's settlement equity.
41
44
  */
42
45
  export const lighterPortfolioValue = (
43
- perpsEquity: Big,
46
+ perpsEquity: string,
44
47
  holdingValuesUsd: readonly string[]
45
- ): Big =>
48
+ ): string =>
46
49
  holdingValuesUsd.reduce(
47
- (sum, valueUsd) => sum.plus(toRequiredBig(valueUsd, 'valueUsd')),
50
+ (sum, valueUsd) =>
51
+ addDecimalString(
52
+ sum,
53
+ unknownToDecimalString(valueUsd, 'valueUsd', LIGHTER_PROVIDER_KEY)
54
+ ),
48
55
  perpsEquity
49
56
  )
50
57
 
@@ -68,29 +75,41 @@ export function getAccountSummary(
68
75
  asset.id !== settlement.displaySymbol
69
76
  )
70
77
 
71
- let marginUsed = new Big(0)
72
- let unrealizedPnl = new Big(0)
73
- for (const position of positions) {
74
- marginUsed = marginUsed.plus(position.marginUsed)
75
- unrealizedPnl = unrealizedPnl.plus(position.unrealizedPnl)
76
- }
77
-
78
78
  return {
79
79
  portfolioValue: lighterPortfolioValue(
80
- toRequiredBig(config.totalAssetValue, 'totalAssetValue').plus(
81
- toRequiredBig(config.collateralSpotBalance, 'collateralSpotBalance')
80
+ addDecimalString(
81
+ unknownToDecimalString(
82
+ config.totalAssetValue,
83
+ 'totalAssetValue',
84
+ LIGHTER_PROVIDER_KEY
85
+ ),
86
+ unknownToDecimalString(
87
+ config.collateralSpotBalance,
88
+ 'collateralSpotBalance',
89
+ LIGHTER_PROVIDER_KEY
90
+ )
82
91
  ),
83
92
  holdings.map((balance) => balance.valueUsd)
84
- ).toFixed(),
93
+ ),
85
94
  availableMargin: atLeastZero(
86
- toRequiredBig(config.crossAssetValue, 'crossAssetValue').minus(
87
- toRequiredBig(
95
+ subtractDecimalString(
96
+ unknownToDecimalString(
97
+ config.crossAssetValue,
98
+ 'crossAssetValue',
99
+ LIGHTER_PROVIDER_KEY
100
+ ),
101
+ unknownToDecimalString(
88
102
  config.crossInitialMarginRequirement,
89
- 'crossInitialMarginRequirement'
103
+ 'crossInitialMarginRequirement',
104
+ LIGHTER_PROVIDER_KEY
90
105
  )
91
106
  )
92
- ).toFixed(),
93
- marginUsed: marginUsed.toFixed(),
94
- unrealizedPnl: unrealizedPnl.toFixed(),
107
+ ),
108
+ marginUsed: positions
109
+ .map((p) => p.marginUsed)
110
+ .reduce(addDecimalString, '0'),
111
+ unrealizedPnl: positions
112
+ .map((p) => p.unrealizedPnl)
113
+ .reduce(addDecimalString, '0'),
95
114
  }
96
115
  }
@@ -1,21 +1,36 @@
1
- import { toAssetDisplay } from '@lifi/perps-sdk'
1
+ import {
2
+ addDecimalString,
3
+ isDecimalStringGreaterThan,
4
+ toAssetDisplay,
5
+ unknownToDecimalString,
6
+ } from '@lifi/perps-sdk'
2
7
  import type { AvailableToTrade, Market, Position } from '@lifi/perps-types'
3
8
  import { MarginMode, PositionSide } from '@lifi/perps-types'
4
- import Big from 'big.js'
5
- import { toRequiredBig } from './utils/decimal.js'
9
+ import { LIGHTER_PROVIDER_KEY } from './constants.js'
6
10
 
7
- export const atLeastZero = (value: Big): Big =>
8
- value.lt(0) ? new Big(0) : value
11
+ export const atLeastZero = (value: string): string =>
12
+ isDecimalStringGreaterThan('0', value) ? '0' : value
9
13
 
10
14
  // `availableMargin` is the cross free collateral and holds nothing of an
11
15
  // isolated position, so closing one releases its whole equity.
12
- const releasedOnClose = (position: Position): Big => {
13
- const marginUsed = toRequiredBig(position.marginUsed, 'marginUsed')
16
+ const releasedOnClose = (position: Position): string => {
17
+ const marginUsed = unknownToDecimalString(
18
+ position.marginUsed,
19
+ 'marginUsed',
20
+ LIGHTER_PROVIDER_KEY
21
+ )
14
22
  if (position.marginMode !== MarginMode.ISOLATED) {
15
23
  return marginUsed
16
24
  }
17
25
  return atLeastZero(
18
- marginUsed.plus(toRequiredBig(position.unrealizedPnl, 'unrealizedPnl'))
26
+ addDecimalString(
27
+ marginUsed,
28
+ unknownToDecimalString(
29
+ position.unrealizedPnl,
30
+ 'unrealizedPnl',
31
+ LIGHTER_PROVIDER_KEY
32
+ )
33
+ )
19
34
  )
20
35
  }
21
36
 
@@ -36,22 +51,30 @@ export const lighterAvailableToTrade = (
36
51
  availableMargin: string,
37
52
  positions: readonly Position[]
38
53
  ): AvailableToTrade => {
39
- const available = toRequiredBig(availableMargin, 'availableMargin')
54
+ const available = unknownToDecimalString(
55
+ availableMargin,
56
+ 'availableMargin',
57
+ LIGHTER_PROVIDER_KEY
58
+ )
40
59
  const adding = atLeastZero(available)
41
60
  const position = positions.find((p) => p.market.id === market.id)
42
61
  const reducing =
43
62
  position === undefined
44
63
  ? adding
45
- : toRequiredBig(
46
- position.initialMarginRequirement,
47
- 'initialMarginRequirement'
48
- ).plus(atLeastZero(available.plus(releasedOnClose(position))))
64
+ : addDecimalString(
65
+ unknownToDecimalString(
66
+ position.initialMarginRequirement,
67
+ 'initialMarginRequirement',
68
+ LIGHTER_PROVIDER_KEY
69
+ ),
70
+ atLeastZero(addDecimalString(available, releasedOnClose(position)))
71
+ )
49
72
  const isShort = position?.side === PositionSide.SHORT
50
73
  return {
51
74
  providerId: market.providerId,
52
75
  marketId: market.id,
53
76
  asset: toAssetDisplay(market.quoteAsset),
54
- buy: (isShort ? reducing : adding).toFixed(),
55
- sell: (isShort ? adding : reducing).toFixed(),
77
+ buy: isShort ? reducing : adding,
78
+ sell: isShort ? adding : reducing,
56
79
  }
57
80
  }
package/src/constants.ts CHANGED
@@ -193,6 +193,15 @@ export const DEFAULT_TRADES_LIMIT = 50
193
193
  */
194
194
  export const LIGHTER_FEE_TICK_SCALE = 1_000_000
195
195
 
196
+ /**
197
+ * Decimal places a client may use for Lighter leverage. Lighter stores
198
+ * leverage as an integer basis-point IMF (`round(10000 / leverage)`), and at
199
+ * this precision a read-back leverage always re-saves the same IMF.
200
+ *
201
+ * @public
202
+ */
203
+ export const LIGHTER_LEVERAGE_PRECISION = 2
204
+
196
205
  /**
197
206
  * Scale of the integer `initial_margin_fraction` values Lighter publishes on
198
207
  * trade rows and order-book details: the integer is a percent times 100, so
package/src/index.ts CHANGED
@@ -25,6 +25,7 @@ export {
25
25
  DEFAULT_LIGHTER_WS_URL,
26
26
  LIGHTER_CLIENT_ORDER_INDEX_ID_PREFIX,
27
27
  LIGHTER_COLLATERAL_ASSETS,
28
+ LIGHTER_LEVERAGE_PRECISION,
28
29
  LIGHTER_MAINNET_DEPLOYMENT,
29
30
  LIGHTER_MAINNET_SIGNER_CHAIN_ID,
30
31
  LIGHTER_PROVIDER_KEY,
@@ -1,6 +1,9 @@
1
- import { decimalToBaseUnits, PerpsError } from '@lifi/perps-sdk'
1
+ import {
2
+ decimalStringToScaledInteger,
3
+ isDecimalStringGreaterThan,
4
+ PerpsError,
5
+ } from '@lifi/perps-sdk'
2
6
  import { ActionType, PerpsErrorCode } from '@lifi/perps-types'
3
- import Big from 'big.js'
4
7
  import { LT_ROUTE_PERP, LT_ROUTE_SPOT } from '../types/action.js'
5
8
  import { assetMarginModeInt } from '../utils/assetCollateral.js'
6
9
  import {
@@ -622,7 +625,7 @@ export class LighterSigner {
622
625
  const symbol = stringField(p, 'symbol')
623
626
  const amount = stringField(p, 'amount')
624
627
  const minimum = stringField(p, 'min_withdrawal_amount')
625
- if (new Big(amount).lt(new Big(minimum))) {
628
+ if (isDecimalStringGreaterThan(minimum, amount)) {
626
629
  throw new PerpsError(
627
630
  PerpsErrorCode.ValidationError,
628
631
  `Lighter WITHDRAWAL of ${amount} ${symbol} is below the venue ` +
@@ -632,7 +635,11 @@ export class LighterSigner {
632
635
  return wasm.SignWithdraw(
633
636
  numberField(p, 'asset_index'),
634
637
  routeType,
635
- decimalToBaseUnits(amount, numberField(p, 'decimals'), 'truncate'),
638
+ decimalStringToScaledInteger(
639
+ amount,
640
+ numberField(p, 'decimals'),
641
+ 'truncate'
642
+ ),
636
643
  SKIP_NONCE_DISABLED,
637
644
  nonce,
638
645
  ctx.apiKeyIndex,
@@ -85,6 +85,21 @@ export interface LtFastwithdrawInfoResponse {
85
85
  max_withdrawal_amount: string
86
86
  }
87
87
 
88
+ /**
89
+ * `GET /api/v1/transferFeeInfo` (Lighter `TransferFeeInfo`).
90
+ *
91
+ * `transfer_fee_usdc` is the fee for an L2 transfer from `account_index` to
92
+ * `to_account_index`, in the same L2 6-decimal integer scale as
93
+ * {@link LtFastwithdrawInfoResponse}.
94
+ *
95
+ * @public
96
+ */
97
+ export interface LtTransferFeeInfoResponse {
98
+ code: number
99
+ message?: string
100
+ transfer_fee_usdc: number
101
+ }
102
+
88
103
  /**
89
104
  * `POST /api/v1/fastwithdraw` (Lighter `ResultCode`).
90
105
  *
@@ -9,13 +9,11 @@ export {
9
9
  } from './activityCursor.js'
10
10
  export { LighterApiClient } from './apiClient.js'
11
11
  export { assetMarginModeInt, isAssetMarginEnabled } from './assetCollateral.js'
12
- export { toBigOrNull, toRequiredBig } from './decimal.js'
13
12
  export { fetchDetailedAccount } from './fetchDetailedAccount.js'
14
13
  export { lighterAsset } from './lighterAsset.js'
15
- export { estimateLiquidationPrice } from './liquidation.js'
16
14
  export { mapFill } from './mapFill.js'
17
15
  export { mapMarketContext } from './mapMarketContext.js'
18
- export { mapOpenPositions } from './mapOpenPositions.js'
16
+ export { isOpenPosition, mapOpenPositions } from './mapOpenPositions.js'
19
17
  export { mapOrder, mapOrderUpdates } from './mapOrder.js'
20
18
  export { mapPortfolioHistory } from './mapPortfolioHistory.js'
21
19
  export { leverageFromImf, mapPosition } from './mapPosition.js'
@@ -33,3 +31,11 @@ export {
33
31
  resolveTimeInForce,
34
32
  } from './wireEncoding.js'
35
33
  export { lighterWithdrawableBalances } from './withdrawableBalances.js'
34
+ export type {
35
+ LighterFastWithdrawal,
36
+ LighterWithdrawalOptions,
37
+ } from './withdrawalTypes.js'
38
+ export {
39
+ lighterFastWithdrawal,
40
+ lighterWithdrawalTypes,
41
+ } from './withdrawalTypes.js'
@@ -1,14 +1,24 @@
1
1
  import {
2
+ absDecimalString,
3
+ calculateRealizedPnl,
2
4
  classifyFillFromPosition,
5
+ divideDecimalString,
3
6
  ExplorerChainId,
4
7
  explorerTxUrl,
8
+ isDecimalString,
9
+ isDecimalStringGreaterThan,
10
+ isDecimalStringZero,
11
+ safeAddDecimalString,
12
+ safeDivideDecimalString,
13
+ safeMultiplyDecimalString,
14
+ warnSkippedVenueRow,
5
15
  } from '@lifi/perps-sdk'
6
16
  import type { Fill, MarketDisplay } from '@lifi/perps-types'
7
17
  import { LiquidityRole, OrderSide, OrderType } from '@lifi/perps-types'
8
- import Big from 'big.js'
9
- import { LIGHTER_FEE_TICK_SCALE } from '../constants.js'
18
+ import { LIGHTER_FEE_TICK_SCALE, LIGHTER_PROVIDER_KEY } from '../constants.js'
10
19
  import type { LtTrade } from '../types/index.js'
11
20
  import { leverageFromScaledImf } from './mapPosition.js'
21
+ import { rowTimestampToIsoStringOrUndefined } from './rowTimestamp.js'
12
22
  import { isPlaceholderTxHash } from './txHash.js'
13
23
 
14
24
  /**
@@ -20,31 +30,44 @@ import { isPlaceholderTxHash } from './txHash.js'
20
30
  * The product keeps the sign of both inputs. A rebate tick therefore maps to a
21
31
  * negative amount, which `Fee.amount` permits and the Ondo mapper already emits
22
32
  * when a rebate exceeds the fee, so this helper never clamps the sign. A zero
23
- * notional charges a zero fee at every tick.
33
+ * notional charges a zero fee at every tick. A malformed notional gives
34
+ * `undefined`.
24
35
  */
25
36
  const tickToFeeAmount = (
26
37
  notional: string,
27
38
  ownTick: number,
28
39
  integratorTick: number | undefined
29
- ): string =>
30
- new Big(notional)
31
- .times(new Big(ownTick).plus(integratorTick ?? 0))
32
- .div(LIGHTER_FEE_TICK_SCALE)
33
- .toFixed()
40
+ ): string | undefined => {
41
+ if (!isDecimalString(notional)) {
42
+ return undefined
43
+ }
44
+ const tickSum = safeAddDecimalString(
45
+ String(ownTick),
46
+ String(integratorTick ?? 0)
47
+ )
48
+ const scaledFee =
49
+ tickSum === undefined
50
+ ? undefined
51
+ : safeMultiplyDecimalString(notional, tickSum)
52
+ return scaledFee === undefined
53
+ ? undefined
54
+ : safeDivideDecimalString(scaledFee, String(LIGHTER_FEE_TICK_SCALE))
55
+ }
34
56
 
35
57
  /**
36
58
  * Display leverage the viewer had set on the market when the trade executed,
37
59
  * from the pre-trade initial margin fraction. Returns `undefined` when the
38
60
  * row omits the fraction.
39
61
  */
40
- const leverageFromTradeImf = (imf: number | undefined): number | undefined =>
62
+ const leverageFromTradeImf = (imf: number | undefined): string | undefined =>
41
63
  imf === undefined ? undefined : leverageFromScaledImf(imf)
42
64
 
43
65
  /**
44
66
  * Realized PnL on a position-reducing fill, derived from the pre-trade entry
45
67
  * basis. Returns `undefined` for opens/increases (nothing closes) or when the
46
- * entry-quote snapshot is absent, and `null` when the closed portion realizes
47
- * exactly zero — mirroring the Hyperliquid mapper's `null`-for-zero convention.
68
+ * entry-quote snapshot is absent or an input is malformed, and `null` when the
69
+ * closed portion realizes exactly zero — mirroring the Hyperliquid mapper's
70
+ * `null`-for-zero convention.
48
71
  */
49
72
  const deriveRealizedPnl = (
50
73
  startPosition: string,
@@ -53,30 +76,39 @@ const deriveRealizedPnl = (
53
76
  fillPrice: string,
54
77
  isBuyer: boolean
55
78
  ): string | null | undefined => {
56
- if (entryQuoteBefore === undefined) {
79
+ if (
80
+ entryQuoteBefore === undefined ||
81
+ ![startPosition, entryQuoteBefore, fillSize, fillPrice].every(
82
+ isDecimalString
83
+ )
84
+ ) {
57
85
  return undefined
58
86
  }
59
- const start = new Big(startPosition)
60
- if (start.eq(0)) {
87
+ if (isDecimalStringZero(startPosition)) {
61
88
  return undefined
62
89
  }
63
- const isLong = start.gt(0)
90
+ const isLong = isDecimalStringGreaterThan(startPosition, '0')
64
91
  const reducing = isLong ? !isBuyer : isBuyer
65
92
  if (!reducing) {
66
93
  return undefined
67
94
  }
68
95
 
69
- const absStart = start.abs()
70
- const fill = new Big(fillSize)
96
+ const absStart = absDecimalString(startPosition)
71
97
  // A fill larger than the open size flips the position; only the portion that
72
98
  // unwinds the existing position realizes PnL.
73
- const closedSize = fill.gt(absStart) ? absStart : fill
74
- const avgEntry = new Big(entryQuoteBefore).abs().div(absStart)
75
- const price = new Big(fillPrice)
76
- const pnl = isLong
77
- ? price.minus(avgEntry).times(closedSize)
78
- : avgEntry.minus(price).times(closedSize)
79
- return pnl.eq(0) ? null : pnl.toFixed()
99
+ const closedSize = isDecimalStringGreaterThan(fillSize, absStart)
100
+ ? absStart
101
+ : fillSize
102
+ const pnl = calculateRealizedPnl({
103
+ entryPrice: divideDecimalString(
104
+ absDecimalString(entryQuoteBefore),
105
+ absStart
106
+ ),
107
+ closePrice: fillPrice,
108
+ closeSize: closedSize,
109
+ isLong,
110
+ })
111
+ return isDecimalStringZero(pnl) ? null : pnl
80
112
  }
81
113
 
82
114
  /**
@@ -89,7 +121,19 @@ export const mapFill = (
89
121
  trade: LtTrade,
90
122
  accountIndex: number,
91
123
  market: MarketDisplay
92
- ): Fill => {
124
+ ): Fill | undefined => {
125
+ const { size, price } = trade
126
+ const createdAt = rowTimestampToIsoStringOrUndefined(trade.timestamp)
127
+ if (createdAt === undefined) {
128
+ warnSkippedVenueRow(
129
+ LIGHTER_PROVIDER_KEY,
130
+ 'fill',
131
+ 'timestamp',
132
+ trade.timestamp,
133
+ 'timestamp'
134
+ )
135
+ return undefined
136
+ }
93
137
  const isBuyer = trade.bid_account_id === accountIndex
94
138
  const isMaker =
95
139
  (trade.is_maker_ask && !isBuyer) || (!trade.is_maker_ask && isBuyer)
@@ -111,6 +155,10 @@ export const mapFill = (
111
155
  const imfBefore = isMaker
112
156
  ? trade.maker_initial_margin_fraction_before
113
157
  : trade.taker_initial_margin_fraction_before
158
+ const feeAmount =
159
+ feeTick === undefined
160
+ ? undefined
161
+ : tickToFeeAmount(trade.usd_amount, feeTick, integratorFeeTick)
114
162
 
115
163
  return {
116
164
  id: trade.trade_id.toString(),
@@ -118,38 +166,29 @@ export const mapFill = (
118
166
  market,
119
167
  side: isBuyer ? OrderSide.BUY : OrderSide.SELL,
120
168
  type: OrderType.LIMIT,
121
- size: trade.size,
122
- price: trade.price,
169
+ size,
170
+ price,
123
171
  liquidity: isMaker ? LiquidityRole.MAKER : LiquidityRole.TAKER,
124
172
  // Lighter charges the fill fee in the market's quote asset.
125
173
  fee:
126
- feeTick === undefined
174
+ feeAmount === undefined
127
175
  ? undefined
128
- : {
129
- amount: tickToFeeAmount(
130
- trade.usd_amount,
131
- feeTick,
132
- integratorFeeTick
133
- ),
134
- asset: market.quoteAsset.displaySymbol,
135
- },
176
+ : { amount: feeAmount, asset: market.quoteAsset.displaySymbol },
136
177
  leverage: leverageFromTradeImf(imfBefore),
137
178
  realizedPnl: deriveRealizedPnl(
138
179
  startPosition,
139
180
  entryQuoteBefore,
140
- trade.size,
141
- trade.price,
181
+ size,
182
+ price,
142
183
  isBuyer
143
184
  ),
144
185
  startPosition,
145
- // `classifyFillFromPosition` takes an HL-encoded side: `'B'` for buy,
146
- // anything else for sell.
147
186
  classification: classifyFillFromPosition(
148
187
  startPosition,
149
- isBuyer ? 'B' : 'A',
150
- trade.size
188
+ isBuyer ? OrderSide.BUY : OrderSide.SELL,
189
+ size
151
190
  ),
152
- createdAt: new Date(trade.timestamp).toISOString(),
191
+ createdAt,
153
192
  explorerLink: isPlaceholderTxHash(trade.tx_hash)
154
193
  ? undefined
155
194
  : explorerTxUrl(ExplorerChainId.LIGHTER, trade.tx_hash),
@@ -1,11 +1,26 @@
1
- import type { PerpsMarketDisplay, Position } from '@lifi/perps-types'
1
+ import { PerpsError, safeIsDecimalStringZero } from '@lifi/perps-sdk'
2
+ import {
3
+ PerpsErrorCode,
4
+ type PerpsMarketDisplay,
5
+ type Position,
6
+ } from '@lifi/perps-types'
7
+ import { LIGHTER_PROVIDER_KEY } from '../constants.js'
2
8
  import type { LtAccountPosition } from '../types/index.js'
3
9
  import { mapPosition } from './mapPosition.js'
4
10
 
11
+ /**
12
+ * True when the Lighter position row has a non-zero size. A malformed size
13
+ * keeps the row.
14
+ * @public
15
+ */
16
+ export const isOpenPosition = (p: LtAccountPosition): boolean =>
17
+ safeIsDecimalStringZero(p.position) !== true
18
+
5
19
  /**
6
20
  * Map raw Lighter account positions to open {@link Position}s, dropping
7
- * zero-size rows. Only valid for payloads carrying the full position set —
8
- * dropping zeros from a partial frame would make closes unobservable.
21
+ * zero-size rows and rows that `mapPosition` skips. Only valid for payloads
22
+ * carrying the full position set — dropping zeros from a partial frame would
23
+ * make closes unobservable.
9
24
  *
10
25
  * @public
11
26
  */
@@ -13,6 +28,30 @@ export const mapOpenPositions = (
13
28
  positions: LtAccountPosition[],
14
29
  resolveMarket: (marketId: number) => PerpsMarketDisplay
15
30
  ): Position[] =>
16
- positions
17
- .filter((p) => Number.parseFloat(p.position) !== 0)
18
- .map((p) => mapPosition(p, resolveMarket(p.market_id)))
31
+ positions.filter(isOpenPosition).flatMap((p) => {
32
+ const position = mapPosition(p, resolveMarket(p.market_id))
33
+ return position === undefined ? [] : [position]
34
+ })
35
+
36
+ /**
37
+ * Map every open Lighter position for account totals, which must not leave a
38
+ * position out.
39
+ *
40
+ * @throws {PerpsError} `SDKError` when `mapPosition` skips an open row.
41
+ */
42
+ export const requireOpenPositions = (
43
+ positions: LtAccountPosition[],
44
+ resolveMarket: (marketId: number) => PerpsMarketDisplay
45
+ ): Position[] =>
46
+ positions.filter(isOpenPosition).map((p) => {
47
+ const position = mapPosition(p, resolveMarket(p.market_id))
48
+ if (position !== undefined) {
49
+ return position
50
+ }
51
+ const error = new PerpsError(
52
+ PerpsErrorCode.SDKError,
53
+ `${LIGHTER_PROVIDER_KEY} position for market ${p.market_id} is not valid, so the account totals are unknown.`
54
+ )
55
+ error.tool = LIGHTER_PROVIDER_KEY
56
+ throw error
57
+ })