@lifi/perps-sdk-provider-hyperliquid 26.0.0 → 27.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.
- package/dist/cjs/services/getAccount.d.ts.map +1 -1
- package/dist/cjs/services/getAccount.js +2 -3
- package/dist/cjs/services/getAccount.js.map +1 -1
- package/dist/cjs/services/getOrders.d.ts.map +1 -1
- package/dist/cjs/services/getOrders.js +5 -27
- package/dist/cjs/services/getOrders.js.map +1 -1
- package/dist/cjs/services/getPortfolioHistory.d.ts.map +1 -1
- package/dist/cjs/services/getPortfolioHistory.js +3 -1
- package/dist/cjs/services/getPortfolioHistory.js.map +1 -1
- package/dist/cjs/utils/index.d.ts +1 -1
- package/dist/cjs/utils/index.d.ts.map +1 -1
- package/dist/cjs/utils/index.js +3 -1
- package/dist/cjs/utils/index.js.map +1 -1
- package/dist/cjs/utils/liquidation.d.ts +5 -2
- package/dist/cjs/utils/liquidation.d.ts.map +1 -1
- package/dist/cjs/utils/liquidation.js +9 -8
- package/dist/cjs/utils/liquidation.js.map +1 -1
- package/dist/cjs/utils/mapActivity.d.ts.map +1 -1
- package/dist/cjs/utils/mapActivity.js +9 -3
- package/dist/cjs/utils/mapActivity.js.map +1 -1
- package/dist/cjs/utils/mapFill.d.ts.map +1 -1
- package/dist/cjs/utils/mapFill.js +4 -1
- package/dist/cjs/utils/mapFill.js.map +1 -1
- package/dist/cjs/utils/mapMarket.d.ts.map +1 -1
- package/dist/cjs/utils/mapMarket.js +1 -1
- package/dist/cjs/utils/mapMarket.js.map +1 -1
- package/dist/cjs/utils/mapOrder.d.ts +2 -0
- package/dist/cjs/utils/mapOrder.d.ts.map +1 -1
- package/dist/cjs/utils/mapOrder.js +31 -19
- package/dist/cjs/utils/mapOrder.js.map +1 -1
- package/dist/cjs/utils/mapPosition.d.ts.map +1 -1
- package/dist/cjs/utils/mapPosition.js +4 -4
- package/dist/cjs/utils/mapPosition.js.map +1 -1
- package/dist/cjs/utils/transferMargin.js +1 -1
- package/dist/cjs/utils/transferMargin.js.map +1 -1
- package/dist/cjs/utils/venueTotals.d.ts +0 -1
- package/dist/cjs/utils/venueTotals.d.ts.map +1 -1
- package/dist/cjs/utils/venueTotals.js +13 -4
- package/dist/cjs/utils/venueTotals.js.map +1 -1
- package/dist/cjs/websocket/HyperliquidWsProvider.d.ts +1 -0
- package/dist/cjs/websocket/HyperliquidWsProvider.d.ts.map +1 -1
- package/dist/cjs/websocket/HyperliquidWsProvider.js +60 -51
- package/dist/cjs/websocket/HyperliquidWsProvider.js.map +1 -1
- package/dist/esm/services/getAccount.d.ts.map +1 -1
- package/dist/esm/services/getAccount.js +3 -4
- package/dist/esm/services/getAccount.js.map +1 -1
- package/dist/esm/services/getOrders.d.ts.map +1 -1
- package/dist/esm/services/getOrders.js +7 -35
- package/dist/esm/services/getOrders.js.map +1 -1
- package/dist/esm/services/getPortfolioHistory.d.ts.map +1 -1
- package/dist/esm/services/getPortfolioHistory.js +3 -1
- package/dist/esm/services/getPortfolioHistory.js.map +1 -1
- package/dist/esm/utils/index.d.ts +1 -1
- package/dist/esm/utils/index.d.ts.map +1 -1
- package/dist/esm/utils/index.js +1 -1
- package/dist/esm/utils/index.js.map +1 -1
- package/dist/esm/utils/liquidation.d.ts +23 -24
- package/dist/esm/utils/liquidation.d.ts.map +1 -1
- package/dist/esm/utils/liquidation.js +27 -31
- package/dist/esm/utils/liquidation.js.map +1 -1
- package/dist/esm/utils/mapActivity.d.ts.map +1 -1
- package/dist/esm/utils/mapActivity.js +9 -3
- package/dist/esm/utils/mapActivity.js.map +1 -1
- package/dist/esm/utils/mapFill.d.ts.map +1 -1
- package/dist/esm/utils/mapFill.js +4 -1
- package/dist/esm/utils/mapFill.js.map +1 -1
- package/dist/esm/utils/mapMarket.d.ts.map +1 -1
- package/dist/esm/utils/mapMarket.js +2 -2
- package/dist/esm/utils/mapMarket.js.map +1 -1
- package/dist/esm/utils/mapOrder.d.ts +7 -0
- package/dist/esm/utils/mapOrder.d.ts.map +1 -1
- package/dist/esm/utils/mapOrder.js +35 -19
- package/dist/esm/utils/mapOrder.js.map +1 -1
- package/dist/esm/utils/mapPosition.d.ts.map +1 -1
- package/dist/esm/utils/mapPosition.js +4 -4
- package/dist/esm/utils/mapPosition.js.map +1 -1
- package/dist/esm/utils/transferMargin.js +1 -1
- package/dist/esm/utils/transferMargin.js.map +1 -1
- package/dist/esm/utils/venueTotals.d.ts +2 -6
- package/dist/esm/utils/venueTotals.d.ts.map +1 -1
- package/dist/esm/utils/venueTotals.js +15 -8
- package/dist/esm/utils/venueTotals.js.map +1 -1
- package/dist/esm/utils/withdrawableBalances.d.ts +2 -2
- package/dist/esm/utils/withdrawableBalances.js +2 -2
- package/dist/esm/websocket/HyperliquidWsProvider.d.ts +2 -1
- package/dist/esm/websocket/HyperliquidWsProvider.d.ts.map +1 -1
- package/dist/esm/websocket/HyperliquidWsProvider.js +63 -54
- package/dist/esm/websocket/HyperliquidWsProvider.js.map +1 -1
- package/dist/types/services/getAccount.d.ts.map +1 -1
- package/dist/types/services/getOrders.d.ts.map +1 -1
- package/dist/types/services/getPortfolioHistory.d.ts.map +1 -1
- package/dist/types/utils/index.d.ts +1 -1
- package/dist/types/utils/index.d.ts.map +1 -1
- package/dist/types/utils/liquidation.d.ts +23 -24
- package/dist/types/utils/liquidation.d.ts.map +1 -1
- package/dist/types/utils/mapActivity.d.ts.map +1 -1
- package/dist/types/utils/mapFill.d.ts.map +1 -1
- package/dist/types/utils/mapMarket.d.ts.map +1 -1
- package/dist/types/utils/mapOrder.d.ts +7 -0
- package/dist/types/utils/mapOrder.d.ts.map +1 -1
- package/dist/types/utils/mapPosition.d.ts.map +1 -1
- package/dist/types/utils/venueTotals.d.ts +2 -6
- package/dist/types/utils/venueTotals.d.ts.map +1 -1
- package/dist/types/utils/withdrawableBalances.d.ts +2 -2
- package/dist/types/websocket/HyperliquidWsProvider.d.ts +2 -1
- package/dist/types/websocket/HyperliquidWsProvider.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/services/getAccount.ts +3 -3
- package/src/services/getOrders.ts +9 -44
- package/src/services/getPortfolioHistory.ts +3 -7
- package/src/utils/index.ts +2 -0
- package/src/utils/liquidation.ts +41 -35
- package/src/utils/mapActivity.ts +9 -3
- package/src/utils/mapFill.ts +4 -1
- package/src/utils/mapMarket.ts +4 -2
- package/src/utils/mapOrder.ts +46 -20
- package/src/utils/mapPosition.ts +8 -4
- package/src/utils/transferMargin.ts +1 -1
- package/src/utils/venueTotals.ts +21 -28
- package/src/utils/withdrawableBalances.ts +2 -2
- package/src/websocket/HyperliquidWsProvider.ts +95 -71
package/src/utils/venueTotals.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
addDecimalString,
|
|
3
|
-
|
|
3
|
+
addDecimalStrings,
|
|
4
|
+
createWarnOnce,
|
|
5
|
+
isDecimalString,
|
|
4
6
|
unknownToDecimalString,
|
|
5
7
|
} from '@lifi/perps-sdk'
|
|
6
8
|
import type {
|
|
@@ -55,35 +57,26 @@ export const perpsTotals = (
|
|
|
55
57
|
return { accountValue, marginUsed }
|
|
56
58
|
}
|
|
57
59
|
|
|
60
|
+
const warnSkippedTermOnce = createWarnOnce()
|
|
61
|
+
|
|
58
62
|
/**
|
|
59
|
-
* Sum the unrealized PnL of every position, in quote-asset units.
|
|
63
|
+
* Sum the unrealized PnL of every position, in quote-asset units. A term that
|
|
64
|
+
* does not match the decimal pattern adds nothing and warns once.
|
|
60
65
|
* @public
|
|
61
66
|
*/
|
|
62
67
|
export const sumUnrealizedPnl = (
|
|
63
68
|
positions: readonly Position[]
|
|
64
|
-
): DecimalString =>
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Sum every term, or `undefined` with a warning when any term is not a
|
|
80
|
-
* decimal string. A bad term never gives a partial sum.
|
|
81
|
-
*/
|
|
82
|
-
export const safeSumDecimalStrings = (
|
|
83
|
-
terms: readonly string[]
|
|
84
|
-
): DecimalString | undefined =>
|
|
85
|
-
terms.reduce<DecimalString | undefined>(
|
|
86
|
-
(sum, term) =>
|
|
87
|
-
sum === undefined ? undefined : safeAddDecimalString(sum, term),
|
|
88
|
-
'0'
|
|
89
|
-
)
|
|
69
|
+
): DecimalString => {
|
|
70
|
+
const terms: DecimalString[] = []
|
|
71
|
+
for (const { unrealizedPnl } of positions) {
|
|
72
|
+
if (isDecimalString(unrealizedPnl)) {
|
|
73
|
+
terms.push(unrealizedPnl)
|
|
74
|
+
continue
|
|
75
|
+
}
|
|
76
|
+
warnSkippedTermOnce(
|
|
77
|
+
`${PROVIDER_KEY}|position.unrealizedPnl`,
|
|
78
|
+
`[${PROVIDER_KEY}] skipping a \`position.unrealizedPnl\` term that does not match the decimal pattern: '${String(unrealizedPnl).slice(0, 64)}'`
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
return addDecimalStrings(terms)
|
|
82
|
+
}
|
|
@@ -25,8 +25,8 @@ import { assetIsOutcome } from './assetId.js'
|
|
|
25
25
|
* @param withdrawalFee - Flat venue fee in quote-asset units, set on every
|
|
26
26
|
* quote-asset row. Hyperliquid deducts it from the requested amount. Absent
|
|
27
27
|
* leaves every row without a fee.
|
|
28
|
-
* @throws {PerpsError} `SDKError` when the fee or a venue figure
|
|
29
|
-
* decimal.
|
|
28
|
+
* @throws {PerpsError} `SDKError` when the fee or a venue figure does not match the
|
|
29
|
+
* decimal pattern.
|
|
30
30
|
* @public
|
|
31
31
|
*/
|
|
32
32
|
export const hyperliquidWithdrawableBalances = (
|
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
isActiveMarket,
|
|
8
8
|
isActiveOrderStatus,
|
|
9
9
|
isDecimalString,
|
|
10
|
-
isDecimalStringGreaterThan,
|
|
11
10
|
isDecimalStringZero,
|
|
12
11
|
type MarketRegistry,
|
|
13
12
|
PerpsError,
|
|
@@ -24,6 +23,7 @@ import {
|
|
|
24
23
|
safeIsDecimalStringZero,
|
|
25
24
|
safeMultiplyDecimalString,
|
|
26
25
|
safeNumberToDecimalString,
|
|
26
|
+
safeSubtractDecimalString,
|
|
27
27
|
subtractDecimalString,
|
|
28
28
|
toAssetDisplay,
|
|
29
29
|
toPerpsMarketDisplay,
|
|
@@ -100,6 +100,7 @@ import {
|
|
|
100
100
|
spotPriceById,
|
|
101
101
|
sumUnrealizedPnl,
|
|
102
102
|
} from '../utils/index.js'
|
|
103
|
+
import { mapOrderRow } from '../utils/mapOrder.js'
|
|
103
104
|
|
|
104
105
|
/** HL's compact `l2` snapshot carries 20 levels per side. */
|
|
105
106
|
const HL_L2_BOOK_MAX_LEVELS_PER_SIDE = 20
|
|
@@ -973,7 +974,7 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
|
|
|
973
974
|
|
|
974
975
|
/** Latest mid per `Market.id` across asset-context and fast feeds. */
|
|
975
976
|
/** Latest mid per `Market.id` across asset-context and fast feeds; a mid
|
|
976
|
-
* that
|
|
977
|
+
* that does not match the decimal pattern is left out. */
|
|
977
978
|
private mergedMids(): Map<string, DecimalString> {
|
|
978
979
|
const map = new Map<string, DecimalString>()
|
|
979
980
|
const setMid = (id: string, mid: string | number | null | undefined) => {
|
|
@@ -1017,10 +1018,10 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
|
|
|
1017
1018
|
provider: this.providerKey,
|
|
1018
1019
|
marketId: data.coin,
|
|
1019
1020
|
bids: data.levels[0]
|
|
1020
|
-
.flatMap((l) => toOrderbookLevel(l.px, l.sz))
|
|
1021
|
+
.flatMap((l) => toOrderbookLevel(data.coin, l.px, l.sz))
|
|
1021
1022
|
.slice(0, HL_L2_BOOK_MAX_LEVELS_PER_SIDE),
|
|
1022
1023
|
asks: data.levels[1]
|
|
1023
|
-
.flatMap((l) => toOrderbookLevel(l.px, l.sz))
|
|
1024
|
+
.flatMap((l) => toOrderbookLevel(data.coin, l.px, l.sz))
|
|
1024
1025
|
.slice(0, HL_L2_BOOK_MAX_LEVELS_PER_SIDE),
|
|
1025
1026
|
timestamp: data.time,
|
|
1026
1027
|
}
|
|
@@ -1064,12 +1065,14 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
|
|
|
1064
1065
|
provider: this.providerKey,
|
|
1065
1066
|
marketId: delta.c,
|
|
1066
1067
|
bids: applyCompressedL2Side(
|
|
1068
|
+
delta.c,
|
|
1067
1069
|
previous.bids,
|
|
1068
1070
|
delta.l[0],
|
|
1069
1071
|
delta.r?.[0] ?? [],
|
|
1070
1072
|
'bid'
|
|
1071
1073
|
),
|
|
1072
1074
|
asks: applyCompressedL2Side(
|
|
1075
|
+
delta.c,
|
|
1073
1076
|
previous.asks,
|
|
1074
1077
|
delta.l[1],
|
|
1075
1078
|
delta.r?.[1] ?? [],
|
|
@@ -1141,48 +1144,33 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
|
|
|
1141
1144
|
if (epoch !== this.orderUpdatesEpoch || key !== this.orderUpdatesKey) {
|
|
1142
1145
|
return
|
|
1143
1146
|
}
|
|
1147
|
+
const user = key.slice('orderUpdates:'.length)
|
|
1144
1148
|
const mapped = await Promise.all(
|
|
1145
1149
|
data.map(async (update) => {
|
|
1146
1150
|
const basic = update.order
|
|
1147
|
-
if (
|
|
1151
|
+
if (
|
|
1152
|
+
assetIsOutcome(basic.coin) ||
|
|
1153
|
+
this.registry?.get(basic.coin) === undefined
|
|
1154
|
+
) {
|
|
1148
1155
|
return undefined
|
|
1149
1156
|
}
|
|
1150
|
-
|
|
1151
|
-
|
|
1157
|
+
let detail: HlOrderDetail
|
|
1158
|
+
try {
|
|
1159
|
+
detail = await this.readOrderDetail(user, client, update)
|
|
1160
|
+
} catch (error) {
|
|
1161
|
+
if (!(error instanceof PerpsError)) {
|
|
1162
|
+
throw error
|
|
1163
|
+
}
|
|
1164
|
+
wsLog.droppedRow(
|
|
1165
|
+
this.providerKey,
|
|
1166
|
+
'order',
|
|
1167
|
+
`${basic.oid}: ${error.message}`
|
|
1168
|
+
)
|
|
1152
1169
|
return undefined
|
|
1153
1170
|
}
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
{
|
|
1157
|
-
type: 'orderStatus',
|
|
1158
|
-
user: key.slice('orderUpdates:'.length),
|
|
1159
|
-
oid: basic.oid,
|
|
1160
|
-
},
|
|
1161
|
-
hlInfoOptions(client)
|
|
1171
|
+
return mapOrderRow(basic.coin, this.registry, (resolved) =>
|
|
1172
|
+
mapOrder(detail, resolved)
|
|
1162
1173
|
)
|
|
1163
|
-
if (response.status !== 'order') {
|
|
1164
|
-
throw new PerpsError(
|
|
1165
|
-
PerpsErrorCode.OrderNotFound,
|
|
1166
|
-
`Hyperliquid order metadata not found: ${basic.oid}`
|
|
1167
|
-
)
|
|
1168
|
-
}
|
|
1169
|
-
// REST supplies execution metadata; the stream owns this event's lifecycle and quantities.
|
|
1170
|
-
const detail: HlOrderDetail = {
|
|
1171
|
-
status: update.status,
|
|
1172
|
-
statusTimestamp: update.statusTimestamp,
|
|
1173
|
-
order: {
|
|
1174
|
-
...response.order.order,
|
|
1175
|
-
coin: basic.coin,
|
|
1176
|
-
side: basic.side,
|
|
1177
|
-
limitPx: basic.limitPx,
|
|
1178
|
-
sz: basic.sz,
|
|
1179
|
-
oid: basic.oid,
|
|
1180
|
-
timestamp: basic.timestamp,
|
|
1181
|
-
origSz: basic.origSz,
|
|
1182
|
-
cloid: basic.cloid ?? response.order.order.cloid,
|
|
1183
|
-
},
|
|
1184
|
-
}
|
|
1185
|
-
return mapOrder(detail, market)
|
|
1186
1174
|
})
|
|
1187
1175
|
)
|
|
1188
1176
|
if (epoch !== this.orderUpdatesEpoch || key !== this.orderUpdatesKey) {
|
|
@@ -1203,6 +1191,41 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
|
|
|
1203
1191
|
})
|
|
1204
1192
|
}
|
|
1205
1193
|
|
|
1194
|
+
// REST supplies execution metadata; the stream owns this event's lifecycle and quantities.
|
|
1195
|
+
private async readOrderDetail(
|
|
1196
|
+
user: string,
|
|
1197
|
+
client: PerpsSDKClient,
|
|
1198
|
+
update: HlWsOrder
|
|
1199
|
+
): Promise<HlOrderDetail> {
|
|
1200
|
+
const basic = update.order
|
|
1201
|
+
const response = await infoRequest<HlOrderStatusResponse>(
|
|
1202
|
+
this.orderApiUrl,
|
|
1203
|
+
{ type: 'orderStatus', user, oid: basic.oid },
|
|
1204
|
+
hlInfoOptions(client)
|
|
1205
|
+
)
|
|
1206
|
+
if (response.status !== 'order') {
|
|
1207
|
+
throw new PerpsError(
|
|
1208
|
+
PerpsErrorCode.OrderNotFound,
|
|
1209
|
+
`Hyperliquid order metadata not found: ${basic.oid}`
|
|
1210
|
+
)
|
|
1211
|
+
}
|
|
1212
|
+
return {
|
|
1213
|
+
status: update.status,
|
|
1214
|
+
statusTimestamp: update.statusTimestamp,
|
|
1215
|
+
order: {
|
|
1216
|
+
...response.order.order,
|
|
1217
|
+
coin: basic.coin,
|
|
1218
|
+
side: basic.side,
|
|
1219
|
+
limitPx: basic.limitPx,
|
|
1220
|
+
sz: basic.sz,
|
|
1221
|
+
oid: basic.oid,
|
|
1222
|
+
timestamp: basic.timestamp,
|
|
1223
|
+
origSz: basic.origSz,
|
|
1224
|
+
cloid: basic.cloid ?? response.order.order.cloid,
|
|
1225
|
+
},
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1206
1229
|
private handleUserFills(data: HlWsUserFillsData) {
|
|
1207
1230
|
// The snapshot frame carries up to ~2000 historical fills and is replayed
|
|
1208
1231
|
// on every reconnect via `replaySubs`; emitting them would surface old
|
|
@@ -1552,15 +1575,10 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
|
|
|
1552
1575
|
const priceById = spotPriceById(markets, this.mergedMids())
|
|
1553
1576
|
const balances = data.spotState.balances
|
|
1554
1577
|
.filter((balance) => !assetIsOutcome(balance.coin))
|
|
1555
|
-
.
|
|
1556
|
-
balance,
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
'spotState.balances.total',
|
|
1560
|
-
this.providerKey
|
|
1561
|
-
),
|
|
1562
|
-
}))
|
|
1563
|
-
.filter(({ total }) => isDecimalStringGreaterThan(total, '0'))
|
|
1578
|
+
.filter(
|
|
1579
|
+
(balance) => safeIsDecimalStringGreaterThan(balance.total, '0') === true
|
|
1580
|
+
)
|
|
1581
|
+
.map((balance) => ({ balance, total: balance.total }))
|
|
1564
1582
|
const pipeline = this.unifiedSummaryByUser.get(user)
|
|
1565
1583
|
// Known spot markets await a price; unlisted tokens keep their unpriced balance.
|
|
1566
1584
|
if (
|
|
@@ -1574,21 +1592,15 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
|
|
|
1574
1592
|
}
|
|
1575
1593
|
return
|
|
1576
1594
|
}
|
|
1577
|
-
const rows = balances.map(({ balance, total }) =>
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
this.providerKey
|
|
1587
|
-
)
|
|
1588
|
-
),
|
|
1589
|
-
total
|
|
1590
|
-
),
|
|
1591
|
-
}))
|
|
1595
|
+
const rows = balances.map(({ balance, total }) => {
|
|
1596
|
+
const free = safeSubtractDecimalString(total, balance.hold)
|
|
1597
|
+
return {
|
|
1598
|
+
...spotBalance(spotAssetFromToken(balance), total, priceById),
|
|
1599
|
+
locked: balance.hold,
|
|
1600
|
+
transferable:
|
|
1601
|
+
free === undefined ? '0' : calculateTransferable(free, total),
|
|
1602
|
+
}
|
|
1603
|
+
})
|
|
1592
1604
|
this.emit(`spotState:${user}`, {
|
|
1593
1605
|
channel: 'spotBalances',
|
|
1594
1606
|
data: rows,
|
|
@@ -1776,27 +1788,38 @@ function mapSpotMarketContext(
|
|
|
1776
1788
|
const BOOK_LEVEL_ROW = 'order book level'
|
|
1777
1789
|
|
|
1778
1790
|
/** The venue price when it is a decimal string, or `undefined` after a logged skip. */
|
|
1779
|
-
function bookLevelPrice(
|
|
1791
|
+
function bookLevelPrice(
|
|
1792
|
+
marketId: string,
|
|
1793
|
+
price: string
|
|
1794
|
+
): DecimalString | undefined {
|
|
1780
1795
|
if (!isDecimalString(price)) {
|
|
1781
|
-
wsLog.skippedRow(PROVIDER_KEY, BOOK_LEVEL_ROW, 'price', price)
|
|
1796
|
+
wsLog.skippedRow(PROVIDER_KEY, BOOK_LEVEL_ROW, 'price', price, marketId)
|
|
1782
1797
|
return undefined
|
|
1783
1798
|
}
|
|
1784
1799
|
return price
|
|
1785
1800
|
}
|
|
1786
1801
|
|
|
1787
1802
|
/** The venue size when it is a decimal string, or `undefined` after a logged skip. */
|
|
1788
|
-
function bookLevelSize(
|
|
1803
|
+
function bookLevelSize(
|
|
1804
|
+
marketId: string,
|
|
1805
|
+
size: string
|
|
1806
|
+
): DecimalString | undefined {
|
|
1789
1807
|
if (!isDecimalString(size)) {
|
|
1790
|
-
wsLog.skippedRow(PROVIDER_KEY, BOOK_LEVEL_ROW, 'size', size)
|
|
1808
|
+
wsLog.skippedRow(PROVIDER_KEY, BOOK_LEVEL_ROW, 'size', size, marketId)
|
|
1791
1809
|
return undefined
|
|
1792
1810
|
}
|
|
1793
1811
|
return size
|
|
1794
1812
|
}
|
|
1795
1813
|
|
|
1796
1814
|
/** One order-book level, or none when the venue price or size is invalid. */
|
|
1797
|
-
function toOrderbookLevel(
|
|
1798
|
-
|
|
1799
|
-
|
|
1815
|
+
function toOrderbookLevel(
|
|
1816
|
+
marketId: string,
|
|
1817
|
+
price: string,
|
|
1818
|
+
size: string
|
|
1819
|
+
): OrderbookLevel[] {
|
|
1820
|
+
const levelPrice = bookLevelPrice(marketId, price)
|
|
1821
|
+
const levelSize =
|
|
1822
|
+
levelPrice === undefined ? undefined : bookLevelSize(marketId, size)
|
|
1800
1823
|
return levelPrice === undefined || levelSize === undefined
|
|
1801
1824
|
? []
|
|
1802
1825
|
: [{ price: levelPrice, size: levelSize }]
|
|
@@ -1813,6 +1836,7 @@ function compactRemovalPrice(
|
|
|
1813
1836
|
}
|
|
1814
1837
|
|
|
1815
1838
|
function applyCompressedL2Side(
|
|
1839
|
+
marketId: string,
|
|
1816
1840
|
previous: OrderbookLevel[],
|
|
1817
1841
|
updates: HlWsCompressedL2Data['l'][number],
|
|
1818
1842
|
removals: NonNullable<HlWsCompressedL2Data['r']>[number],
|
|
@@ -1826,11 +1850,11 @@ function applyCompressedL2Side(
|
|
|
1826
1850
|
}
|
|
1827
1851
|
}
|
|
1828
1852
|
for (const update of updates) {
|
|
1829
|
-
const price = bookLevelPrice(update.p)
|
|
1853
|
+
const price = bookLevelPrice(marketId, update.p)
|
|
1830
1854
|
if (price === undefined) {
|
|
1831
1855
|
continue
|
|
1832
1856
|
}
|
|
1833
|
-
const size = bookLevelSize(update.s)
|
|
1857
|
+
const size = bookLevelSize(marketId, update.s)
|
|
1834
1858
|
// A level whose new size is unknown must not keep its old size.
|
|
1835
1859
|
if (size === undefined || safeIsDecimalStringZero(size) !== false) {
|
|
1836
1860
|
byPrice.delete(price)
|