@pear-protocol/symmio-client 0.2.28 → 0.2.30
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/react/index.d.mts +6 -2
- package/dist/react/index.d.ts +6 -2
- package/dist/react/index.js +121 -137
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +121 -137
- package/dist/react/index.mjs.map +1 -1
- package/dist/react/provider.js +61 -15
- package/dist/react/provider.js.map +1 -1
- package/dist/react/provider.mjs +61 -15
- package/dist/react/provider.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react/index.d.mts
CHANGED
|
@@ -8706,8 +8706,6 @@ interface SymmTokenSelectionMarket extends MarketItem {
|
|
|
8706
8706
|
priceChange24hPercent: number | null;
|
|
8707
8707
|
}
|
|
8708
8708
|
interface UseSymmTokenSelectionMarketsReturn {
|
|
8709
|
-
query: ReturnType<typeof useSymmHedgerMarkets>;
|
|
8710
|
-
priceQuery: ReturnType<typeof useQuery>;
|
|
8711
8709
|
markets: SymmTokenSelectionMarket[];
|
|
8712
8710
|
marketsBySymbol: Map<string, SymmTokenSelectionMarket>;
|
|
8713
8711
|
marketsById: Map<number, SymmTokenSelectionMarket>;
|
|
@@ -8875,6 +8873,8 @@ interface SymmTokenMetadata {
|
|
|
8875
8873
|
priceChange24hPercent: number;
|
|
8876
8874
|
netFunding: number;
|
|
8877
8875
|
markPrice: number;
|
|
8876
|
+
fundingRate: number;
|
|
8877
|
+
nextFundingTime: number;
|
|
8878
8878
|
}
|
|
8879
8879
|
interface UseSymmTokenSelectionMetadataReturn {
|
|
8880
8880
|
query: ReturnType<typeof useQuery>;
|
|
@@ -9099,8 +9099,12 @@ type SymmWsState = {
|
|
|
9099
9099
|
declare const useSymmWsStore: zustand.UseBoundStore<zustand.StoreApi<SymmWsState>>;
|
|
9100
9100
|
|
|
9101
9101
|
type MarkPrices = Record<string, number>;
|
|
9102
|
+
type FundingRates = Record<string, number>;
|
|
9103
|
+
type NextFundingTimes = Record<string, number>;
|
|
9102
9104
|
type BinanceMarkPriceState = {
|
|
9103
9105
|
markPrices: MarkPrices;
|
|
9106
|
+
fundingRates: FundingRates;
|
|
9107
|
+
nextFundingTimes: NextFundingTimes;
|
|
9104
9108
|
subscribeSymbol: (symmSymbol: string, binanceSymbol: string) => void;
|
|
9105
9109
|
unsubscribeSymbol: (symmSymbol: string, binanceSymbol: string) => void;
|
|
9106
9110
|
};
|
package/dist/react/index.d.ts
CHANGED
|
@@ -8706,8 +8706,6 @@ interface SymmTokenSelectionMarket extends MarketItem {
|
|
|
8706
8706
|
priceChange24hPercent: number | null;
|
|
8707
8707
|
}
|
|
8708
8708
|
interface UseSymmTokenSelectionMarketsReturn {
|
|
8709
|
-
query: ReturnType<typeof useSymmHedgerMarkets>;
|
|
8710
|
-
priceQuery: ReturnType<typeof useQuery>;
|
|
8711
8709
|
markets: SymmTokenSelectionMarket[];
|
|
8712
8710
|
marketsBySymbol: Map<string, SymmTokenSelectionMarket>;
|
|
8713
8711
|
marketsById: Map<number, SymmTokenSelectionMarket>;
|
|
@@ -8875,6 +8873,8 @@ interface SymmTokenMetadata {
|
|
|
8875
8873
|
priceChange24hPercent: number;
|
|
8876
8874
|
netFunding: number;
|
|
8877
8875
|
markPrice: number;
|
|
8876
|
+
fundingRate: number;
|
|
8877
|
+
nextFundingTime: number;
|
|
8878
8878
|
}
|
|
8879
8879
|
interface UseSymmTokenSelectionMetadataReturn {
|
|
8880
8880
|
query: ReturnType<typeof useQuery>;
|
|
@@ -9099,8 +9099,12 @@ type SymmWsState = {
|
|
|
9099
9099
|
declare const useSymmWsStore: zustand.UseBoundStore<zustand.StoreApi<SymmWsState>>;
|
|
9100
9100
|
|
|
9101
9101
|
type MarkPrices = Record<string, number>;
|
|
9102
|
+
type FundingRates = Record<string, number>;
|
|
9103
|
+
type NextFundingTimes = Record<string, number>;
|
|
9102
9104
|
type BinanceMarkPriceState = {
|
|
9103
9105
|
markPrices: MarkPrices;
|
|
9106
|
+
fundingRates: FundingRates;
|
|
9107
|
+
nextFundingTimes: NextFundingTimes;
|
|
9104
9108
|
subscribeSymbol: (symmSymbol: string, binanceSymbol: string) => void;
|
|
9105
9109
|
unsubscribeSymbol: (symmSymbol: string, binanceSymbol: string) => void;
|
|
9106
9110
|
};
|
package/dist/react/index.js
CHANGED
|
@@ -71,7 +71,7 @@ function toBinanceSymbol(symmSymbol) {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
// src/utils/binance-ws.ts
|
|
74
|
-
var BINANCE_WS_URL = "wss://fstream.binance.com/ws";
|
|
74
|
+
var BINANCE_WS_URL = "wss://fstream.binance.com/market/ws";
|
|
75
75
|
var RECONNECT_DELAYS = [1e3, 2e3, 4e3, 8e3, 16e3, 3e4];
|
|
76
76
|
var STABLE_QUOTES = ["USDT0", "USDT", "USDC", "USDE", "USDH", "USD"];
|
|
77
77
|
function normalizeBaseSymbol(symbol) {
|
|
@@ -101,6 +101,22 @@ function extractTickers(payload) {
|
|
|
101
101
|
}
|
|
102
102
|
return [];
|
|
103
103
|
}
|
|
104
|
+
function extractWsPayload(payload) {
|
|
105
|
+
if (payload && typeof payload === "object" && "data" in payload) {
|
|
106
|
+
return payload.data ?? payload;
|
|
107
|
+
}
|
|
108
|
+
return payload;
|
|
109
|
+
}
|
|
110
|
+
function isKlinePayload(payload) {
|
|
111
|
+
return Boolean(
|
|
112
|
+
payload && typeof payload === "object" && payload.e === "kline" && typeof payload.s === "string" && payload.k && typeof payload.k.i === "string"
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
function isMarkPricePayload(payload) {
|
|
116
|
+
return Boolean(
|
|
117
|
+
payload && typeof payload === "object" && payload.e === "markPriceUpdate" && typeof payload.s === "string"
|
|
118
|
+
);
|
|
119
|
+
}
|
|
104
120
|
var BinanceWsManager = class {
|
|
105
121
|
ws = null;
|
|
106
122
|
streams = /* @__PURE__ */ new Map();
|
|
@@ -145,7 +161,9 @@ var BinanceWsManager = class {
|
|
|
145
161
|
symbol: normalizeBaseSymbol(raw.s),
|
|
146
162
|
markPrice: parseFloat(raw.p),
|
|
147
163
|
indexPrice: parseFloat(raw.i),
|
|
148
|
-
time: raw.E
|
|
164
|
+
time: raw.E,
|
|
165
|
+
fundingRate: parseFloat(raw.r ?? "0"),
|
|
166
|
+
nextFundingTime: Number(raw.T ?? 0)
|
|
149
167
|
});
|
|
150
168
|
};
|
|
151
169
|
this.addStreamCallback(streamName, id, wrappedCb);
|
|
@@ -164,7 +182,9 @@ var BinanceWsManager = class {
|
|
|
164
182
|
symbol: normalizeBaseSymbol(entry.s),
|
|
165
183
|
markPrice: parseFloat(entry.p),
|
|
166
184
|
indexPrice: parseFloat(entry.i),
|
|
167
|
-
time: entry.E
|
|
185
|
+
time: entry.E,
|
|
186
|
+
fundingRate: parseFloat(entry.r ?? "0"),
|
|
187
|
+
nextFundingTime: Number(entry.T ?? 0)
|
|
168
188
|
}))
|
|
169
189
|
);
|
|
170
190
|
};
|
|
@@ -254,17 +274,18 @@ var BinanceWsManager = class {
|
|
|
254
274
|
};
|
|
255
275
|
}
|
|
256
276
|
handleMessage(data) {
|
|
257
|
-
|
|
258
|
-
|
|
277
|
+
const payload = extractWsPayload(data);
|
|
278
|
+
if (Array.isArray(payload)) {
|
|
279
|
+
this.dispatchToStream("!markPrice@arr@1s", payload);
|
|
259
280
|
return;
|
|
260
281
|
}
|
|
261
|
-
if (
|
|
262
|
-
const k =
|
|
263
|
-
const streamName = `${
|
|
264
|
-
this.dispatchToStream(streamName,
|
|
265
|
-
} else if (
|
|
266
|
-
const streamName = `${
|
|
267
|
-
this.dispatchToStream(streamName,
|
|
282
|
+
if (isKlinePayload(payload)) {
|
|
283
|
+
const k = payload.k;
|
|
284
|
+
const streamName = `${payload.s.toLowerCase()}@kline_${k.i}`;
|
|
285
|
+
this.dispatchToStream(streamName, payload);
|
|
286
|
+
} else if (isMarkPricePayload(payload)) {
|
|
287
|
+
const streamName = `${payload.s.toLowerCase()}@markPrice@1s`;
|
|
288
|
+
this.dispatchToStream(streamName, payload);
|
|
268
289
|
}
|
|
269
290
|
}
|
|
270
291
|
dispatchToStream(streamName, data) {
|
|
@@ -343,6 +364,8 @@ function getPrevRefCount(binanceSymbol) {
|
|
|
343
364
|
}
|
|
344
365
|
var useBinanceMarkPriceStore = zustand.create((set) => ({
|
|
345
366
|
markPrices: {},
|
|
367
|
+
fundingRates: {},
|
|
368
|
+
nextFundingTimes: {},
|
|
346
369
|
subscribeSymbol: (symmSymbol, rawBinanceSymbol) => {
|
|
347
370
|
const binanceSymbol = normalizeBinanceSymbol(rawBinanceSymbol);
|
|
348
371
|
const nextRefCount = getNextRefCount(binanceSymbol);
|
|
@@ -355,16 +378,29 @@ var useBinanceMarkPriceStore = zustand.create((set) => ({
|
|
|
355
378
|
allMarkPricesUnsubscribe = wsManager.subscribeAllMarkPrices((entries) => {
|
|
356
379
|
set((state) => {
|
|
357
380
|
let nextMarkPrices = null;
|
|
381
|
+
let nextFundingRates = null;
|
|
382
|
+
let nextFundingTimes = null;
|
|
358
383
|
entries.forEach((entry) => {
|
|
359
384
|
const canonicalSymbol = normalizeBinanceSymbol(entry.symbol);
|
|
360
385
|
const mappedSymbols = streamSymbols.get(canonicalSymbol);
|
|
361
386
|
if (!mappedSymbols || mappedSymbols.size === 0) return;
|
|
362
387
|
nextMarkPrices ??= { ...state.markPrices };
|
|
388
|
+
nextFundingRates ??= { ...state.fundingRates };
|
|
389
|
+
nextFundingTimes ??= { ...state.nextFundingTimes };
|
|
363
390
|
mappedSymbols.forEach((mappedSymbol) => {
|
|
364
391
|
nextMarkPrices[mappedSymbol] = entry.markPrice;
|
|
392
|
+
nextFundingRates[mappedSymbol] = entry.fundingRate;
|
|
393
|
+
nextFundingTimes[mappedSymbol] = entry.nextFundingTime;
|
|
365
394
|
});
|
|
366
395
|
});
|
|
367
|
-
|
|
396
|
+
if (!nextMarkPrices || !nextFundingRates || !nextFundingTimes) {
|
|
397
|
+
return state;
|
|
398
|
+
}
|
|
399
|
+
return {
|
|
400
|
+
markPrices: nextMarkPrices,
|
|
401
|
+
fundingRates: nextFundingRates,
|
|
402
|
+
nextFundingTimes
|
|
403
|
+
};
|
|
368
404
|
});
|
|
369
405
|
});
|
|
370
406
|
}
|
|
@@ -393,10 +429,20 @@ var useBinanceMarkPriceStore = zustand.create((set) => ({
|
|
|
393
429
|
allMarkPricesUnsubscribe = null;
|
|
394
430
|
}
|
|
395
431
|
set((state) => {
|
|
396
|
-
if (state.markPrices[symmSymbol] == null
|
|
432
|
+
if (state.markPrices[symmSymbol] == null && state.fundingRates[symmSymbol] == null && state.nextFundingTimes[symmSymbol] == null) {
|
|
433
|
+
return state;
|
|
434
|
+
}
|
|
397
435
|
const nextMarkPrices = { ...state.markPrices };
|
|
436
|
+
const nextFundingRates = { ...state.fundingRates };
|
|
437
|
+
const nextFundingTimes = { ...state.nextFundingTimes };
|
|
398
438
|
delete nextMarkPrices[symmSymbol];
|
|
399
|
-
|
|
439
|
+
delete nextFundingRates[symmSymbol];
|
|
440
|
+
delete nextFundingTimes[symmSymbol];
|
|
441
|
+
return {
|
|
442
|
+
markPrices: nextMarkPrices,
|
|
443
|
+
fundingRates: nextFundingRates,
|
|
444
|
+
nextFundingTimes
|
|
445
|
+
};
|
|
400
446
|
});
|
|
401
447
|
}
|
|
402
448
|
}));
|
|
@@ -25437,7 +25483,7 @@ function useSymmHedgerMarkets(params) {
|
|
|
25437
25483
|
|
|
25438
25484
|
// src/utils/binance-api.ts
|
|
25439
25485
|
var BINANCE_FAPI_BASE = "https://fapi.binance.com";
|
|
25440
|
-
async function
|
|
25486
|
+
async function fetchKlines(symbol, interval, startTime, endTime, limit = 1500) {
|
|
25441
25487
|
const params = new URLSearchParams({
|
|
25442
25488
|
symbol,
|
|
25443
25489
|
interval,
|
|
@@ -25445,9 +25491,9 @@ async function fetchMarkPriceKlines(symbol, interval, startTime, endTime, limit
|
|
|
25445
25491
|
endTime: String(endTime),
|
|
25446
25492
|
limit: String(Math.min(limit, 1500))
|
|
25447
25493
|
});
|
|
25448
|
-
const response = await fetch(`${BINANCE_FAPI_BASE}/fapi/v1/
|
|
25494
|
+
const response = await fetch(`${BINANCE_FAPI_BASE}/fapi/v1/klines?${params}`);
|
|
25449
25495
|
if (!response.ok) {
|
|
25450
|
-
throw new Error(`Binance
|
|
25496
|
+
throw new Error(`Binance klines failed: ${response.status}`);
|
|
25451
25497
|
}
|
|
25452
25498
|
const data = await response.json();
|
|
25453
25499
|
return data.map((k) => ({
|
|
@@ -25467,7 +25513,7 @@ async function fetch24hrTicker(symbol) {
|
|
|
25467
25513
|
const data = await response.json();
|
|
25468
25514
|
return {
|
|
25469
25515
|
lastPrice: parseFloat(data.lastPrice),
|
|
25470
|
-
|
|
25516
|
+
openPrice: parseFloat(data.openPrice),
|
|
25471
25517
|
priceChangePercent: parseFloat(data.priceChangePercent)
|
|
25472
25518
|
};
|
|
25473
25519
|
}
|
|
@@ -25481,7 +25527,7 @@ async function fetch24hrTickers() {
|
|
|
25481
25527
|
for (const item of data) {
|
|
25482
25528
|
result[item.symbol] = {
|
|
25483
25529
|
lastPrice: parseFloat(item.lastPrice),
|
|
25484
|
-
|
|
25530
|
+
openPrice: parseFloat(item.openPrice),
|
|
25485
25531
|
priceChangePercent: parseFloat(item.priceChangePercent)
|
|
25486
25532
|
};
|
|
25487
25533
|
}
|
|
@@ -25517,7 +25563,7 @@ function useSymmTokenSelectionMarkets(params) {
|
|
|
25517
25563
|
return;
|
|
25518
25564
|
}
|
|
25519
25565
|
const ticker = allTickers[binanceSymbol];
|
|
25520
|
-
tickerSnapshots[symbol] = ticker ? {
|
|
25566
|
+
tickerSnapshots[symbol] = ticker ? { openPrice: ticker.openPrice } : null;
|
|
25521
25567
|
});
|
|
25522
25568
|
return { tickerSnapshots };
|
|
25523
25569
|
},
|
|
@@ -25530,7 +25576,7 @@ function useSymmTokenSelectionMarkets(params) {
|
|
|
25530
25576
|
return baseMarkets.map((market) => {
|
|
25531
25577
|
const symbol = market.symbol ?? "";
|
|
25532
25578
|
const markPrice = symbol ? liveMarkPrices[symbol] ?? null : null;
|
|
25533
|
-
const prevDayPrice = symbol ? snapshots[symbol]?.
|
|
25579
|
+
const prevDayPrice = symbol ? snapshots[symbol]?.openPrice ?? null : null;
|
|
25534
25580
|
const priceChange24h = markPrice != null && prevDayPrice != null ? markPrice - prevDayPrice : null;
|
|
25535
25581
|
const priceChange24hPercent = markPrice != null && prevDayPrice != null && prevDayPrice !== 0 ? (markPrice - prevDayPrice) / prevDayPrice * 100 : null;
|
|
25536
25582
|
return {
|
|
@@ -25545,7 +25591,9 @@ function useSymmTokenSelectionMarkets(params) {
|
|
|
25545
25591
|
}, [baseMarkets, liveMarkPrices, priceQuery.data]);
|
|
25546
25592
|
const marketsBySymbol = react.useMemo(
|
|
25547
25593
|
() => new Map(
|
|
25548
|
-
markets.filter(
|
|
25594
|
+
markets.filter(
|
|
25595
|
+
(m) => !!m.symbol
|
|
25596
|
+
).map((m) => [m.symbol, m])
|
|
25549
25597
|
),
|
|
25550
25598
|
[markets]
|
|
25551
25599
|
);
|
|
@@ -25553,64 +25601,7 @@ function useSymmTokenSelectionMarkets(params) {
|
|
|
25553
25601
|
() => new Map(markets.map((market) => [market.id, market])),
|
|
25554
25602
|
[markets]
|
|
25555
25603
|
);
|
|
25556
|
-
react.useEffect(() => {
|
|
25557
|
-
console.debug("[useSymmTokenSelectionMarkets] data flow", {
|
|
25558
|
-
params,
|
|
25559
|
-
query: {
|
|
25560
|
-
status: query.status,
|
|
25561
|
-
fetchStatus: query.fetchStatus,
|
|
25562
|
-
isLoading: query.isLoading,
|
|
25563
|
-
isSuccess: query.isSuccess,
|
|
25564
|
-
isError: query.isError,
|
|
25565
|
-
error: query.error
|
|
25566
|
-
},
|
|
25567
|
-
priceQuery: {
|
|
25568
|
-
status: priceQuery.status,
|
|
25569
|
-
fetchStatus: priceQuery.fetchStatus,
|
|
25570
|
-
isLoading: priceQuery.isLoading,
|
|
25571
|
-
isSuccess: priceQuery.isSuccess,
|
|
25572
|
-
isError: priceQuery.isError,
|
|
25573
|
-
error: priceQuery.error
|
|
25574
|
-
},
|
|
25575
|
-
marketSymbols,
|
|
25576
|
-
symbolsKey,
|
|
25577
|
-
liveMarkPrices,
|
|
25578
|
-
tickerSnapshots: priceQuery.data?.tickerSnapshots ?? {},
|
|
25579
|
-
result: {
|
|
25580
|
-
marketCount: markets.length,
|
|
25581
|
-
markets: markets.map((market) => ({
|
|
25582
|
-
id: market.id,
|
|
25583
|
-
symbol: market.symbol,
|
|
25584
|
-
markPrice: market.markPrice,
|
|
25585
|
-
prevDayPrice: market.prevDayPrice,
|
|
25586
|
-
priceChange24h: market.priceChange24h,
|
|
25587
|
-
priceChange24hPercent: market.priceChange24hPercent
|
|
25588
|
-
}))
|
|
25589
|
-
}
|
|
25590
|
-
});
|
|
25591
|
-
}, [
|
|
25592
|
-
liveMarkPrices,
|
|
25593
|
-
marketSymbols,
|
|
25594
|
-
markets,
|
|
25595
|
-
params,
|
|
25596
|
-
priceQuery.data,
|
|
25597
|
-
priceQuery.error,
|
|
25598
|
-
priceQuery.fetchStatus,
|
|
25599
|
-
priceQuery.isError,
|
|
25600
|
-
priceQuery.isLoading,
|
|
25601
|
-
priceQuery.isSuccess,
|
|
25602
|
-
priceQuery.status,
|
|
25603
|
-
query.error,
|
|
25604
|
-
query.fetchStatus,
|
|
25605
|
-
query.isError,
|
|
25606
|
-
query.isLoading,
|
|
25607
|
-
query.isSuccess,
|
|
25608
|
-
query.status,
|
|
25609
|
-
symbolsKey
|
|
25610
|
-
]);
|
|
25611
25604
|
return {
|
|
25612
|
-
query,
|
|
25613
|
-
priceQuery,
|
|
25614
25605
|
markets,
|
|
25615
25606
|
marketsBySymbol,
|
|
25616
25607
|
marketsById,
|
|
@@ -26148,10 +26139,10 @@ async function fetchTickerSnapshot(symbol) {
|
|
|
26148
26139
|
const ticker = await fetch24hrTicker(resolution.binanceSymbol);
|
|
26149
26140
|
if (!ticker) return null;
|
|
26150
26141
|
return {
|
|
26151
|
-
|
|
26142
|
+
openPrice: ticker.openPrice
|
|
26152
26143
|
};
|
|
26153
26144
|
}
|
|
26154
|
-
function toSymmTokenMetadata(currentPrice, prevDayPrice) {
|
|
26145
|
+
function toSymmTokenMetadata(currentPrice, prevDayPrice, fundingRate, nextFundingTime) {
|
|
26155
26146
|
const priceChange24h = currentPrice - prevDayPrice;
|
|
26156
26147
|
const priceChange24hPercent = prevDayPrice !== 0 ? (currentPrice - prevDayPrice) / prevDayPrice * 100 : 0;
|
|
26157
26148
|
return {
|
|
@@ -26159,9 +26150,10 @@ function toSymmTokenMetadata(currentPrice, prevDayPrice) {
|
|
|
26159
26150
|
prevDayPrice,
|
|
26160
26151
|
priceChange24h,
|
|
26161
26152
|
priceChange24hPercent,
|
|
26162
|
-
netFunding:
|
|
26163
|
-
|
|
26164
|
-
|
|
26153
|
+
netFunding: fundingRate,
|
|
26154
|
+
markPrice: currentPrice,
|
|
26155
|
+
fundingRate,
|
|
26156
|
+
nextFundingTime
|
|
26165
26157
|
};
|
|
26166
26158
|
}
|
|
26167
26159
|
function useSymmTokenSelectionMetadata(selection, options = {}) {
|
|
@@ -26175,6 +26167,12 @@ function useSymmTokenSelectionMetadata(selection, options = {}) {
|
|
|
26175
26167
|
const unavailableReason = isUnsupported ? `Binance market data is unavailable for ${unsupportedSymbols.join(", ")}.` : null;
|
|
26176
26168
|
const symbolsKey = [...selectedSymbols].sort().join(",");
|
|
26177
26169
|
const liveMarkPrices = useBinanceMarkPriceStore((state) => state.markPrices);
|
|
26170
|
+
const liveFundingRates = useBinanceMarkPriceStore(
|
|
26171
|
+
(state) => state.fundingRates
|
|
26172
|
+
);
|
|
26173
|
+
const liveNextFundingTimes = useBinanceMarkPriceStore(
|
|
26174
|
+
(state) => state.nextFundingTimes
|
|
26175
|
+
);
|
|
26178
26176
|
const query = reactQuery.useQuery({
|
|
26179
26177
|
queryKey: ["symm", "chart-metadata", symbolsKey],
|
|
26180
26178
|
queryFn: async () => {
|
|
@@ -26207,13 +26205,27 @@ function useSymmTokenSelectionMetadata(selection, options = {}) {
|
|
|
26207
26205
|
const isLoading = query.isLoading;
|
|
26208
26206
|
for (const token of longTokens) {
|
|
26209
26207
|
const currentPrice = liveMarkPrices[token.symbol];
|
|
26208
|
+
const fundingRate = liveFundingRates[token.symbol];
|
|
26209
|
+
const nextFundingTime = liveNextFundingTimes[token.symbol];
|
|
26210
26210
|
const ticker = tickerSnapshots[token.symbol];
|
|
26211
|
-
longMeta[token.symbol] = currentPrice != null && ticker ? toSymmTokenMetadata(
|
|
26211
|
+
longMeta[token.symbol] = currentPrice != null && ticker ? toSymmTokenMetadata(
|
|
26212
|
+
currentPrice,
|
|
26213
|
+
ticker.openPrice,
|
|
26214
|
+
fundingRate ?? 0,
|
|
26215
|
+
nextFundingTime ?? 0
|
|
26216
|
+
) : null;
|
|
26212
26217
|
}
|
|
26213
26218
|
for (const token of shortTokens) {
|
|
26214
26219
|
const currentPrice = liveMarkPrices[token.symbol];
|
|
26220
|
+
const fundingRate = liveFundingRates[token.symbol];
|
|
26221
|
+
const nextFundingTime = liveNextFundingTimes[token.symbol];
|
|
26215
26222
|
const ticker = tickerSnapshots[token.symbol];
|
|
26216
|
-
shortMeta[token.symbol] = currentPrice != null && ticker ? toSymmTokenMetadata(
|
|
26223
|
+
shortMeta[token.symbol] = currentPrice != null && ticker ? toSymmTokenMetadata(
|
|
26224
|
+
currentPrice,
|
|
26225
|
+
ticker.openPrice,
|
|
26226
|
+
fundingRate ?? 0,
|
|
26227
|
+
nextFundingTime ?? 0
|
|
26228
|
+
) : null;
|
|
26217
26229
|
}
|
|
26218
26230
|
const allLongReady = longTokens.every(
|
|
26219
26231
|
(t) => longMeta[t.symbol]?.currentPrice != null
|
|
@@ -26251,60 +26263,17 @@ function useSymmTokenSelectionMetadata(selection, options = {}) {
|
|
|
26251
26263
|
}, [
|
|
26252
26264
|
isUnsupported,
|
|
26253
26265
|
longTokens,
|
|
26266
|
+
query,
|
|
26254
26267
|
query.data,
|
|
26255
26268
|
query.isLoading,
|
|
26256
26269
|
shortTokens,
|
|
26257
26270
|
unavailableReason,
|
|
26258
26271
|
unsupportedSymbols,
|
|
26259
26272
|
selectedSymbols.length,
|
|
26273
|
+
liveFundingRates,
|
|
26274
|
+
liveNextFundingTimes,
|
|
26260
26275
|
liveMarkPrices
|
|
26261
26276
|
]);
|
|
26262
|
-
react.useEffect(() => {
|
|
26263
|
-
console.debug("[useSymmTokenSelectionMetadata] data flow", {
|
|
26264
|
-
selection,
|
|
26265
|
-
options,
|
|
26266
|
-
query: {
|
|
26267
|
-
status: query.status,
|
|
26268
|
-
fetchStatus: query.fetchStatus,
|
|
26269
|
-
isLoading: query.isLoading,
|
|
26270
|
-
isSuccess: query.isSuccess,
|
|
26271
|
-
isError: query.isError,
|
|
26272
|
-
error: query.error
|
|
26273
|
-
},
|
|
26274
|
-
selectedSymbols,
|
|
26275
|
-
unsupportedSymbols,
|
|
26276
|
-
unavailableReason,
|
|
26277
|
-
liveMarkPrices,
|
|
26278
|
-
tickerSnapshots: query.data?.tickerSnapshots ?? {},
|
|
26279
|
-
result: {
|
|
26280
|
-
isLoading: result.isLoading,
|
|
26281
|
-
isPriceDataReady: result.isPriceDataReady,
|
|
26282
|
-
isUnsupported: result.isUnsupported,
|
|
26283
|
-
longTokensMetadata: result.longTokensMetadata,
|
|
26284
|
-
shortTokensMetadata: result.shortTokensMetadata,
|
|
26285
|
-
weightedRatio: result.weightedRatio,
|
|
26286
|
-
weightedRatio24h: result.weightedRatio24h,
|
|
26287
|
-
priceRatio: result.priceRatio,
|
|
26288
|
-
priceRatio24h: result.priceRatio24h,
|
|
26289
|
-
sumNetFunding: result.sumNetFunding
|
|
26290
|
-
}
|
|
26291
|
-
});
|
|
26292
|
-
}, [
|
|
26293
|
-
liveMarkPrices,
|
|
26294
|
-
options,
|
|
26295
|
-
query.data,
|
|
26296
|
-
query.error,
|
|
26297
|
-
query.fetchStatus,
|
|
26298
|
-
query.isError,
|
|
26299
|
-
query.isLoading,
|
|
26300
|
-
query.isSuccess,
|
|
26301
|
-
query.status,
|
|
26302
|
-
result,
|
|
26303
|
-
selectedSymbols,
|
|
26304
|
-
selection,
|
|
26305
|
-
unavailableReason,
|
|
26306
|
-
unsupportedSymbols
|
|
26307
|
-
]);
|
|
26308
26277
|
return result;
|
|
26309
26278
|
}
|
|
26310
26279
|
|
|
@@ -26334,10 +26303,13 @@ function toBinanceInterval(interval) {
|
|
|
26334
26303
|
}
|
|
26335
26304
|
|
|
26336
26305
|
// src/react/hooks/use-symm-chart-candles.ts
|
|
26306
|
+
function areIntervalsEqual(currentInterval, nextInterval) {
|
|
26307
|
+
return currentInterval === toBinanceInterval(nextInterval);
|
|
26308
|
+
}
|
|
26337
26309
|
async function fetchSymbolKlines(symbol, interval, start, end) {
|
|
26338
26310
|
const binanceSymbol = toBinanceSymbol(symbol);
|
|
26339
26311
|
if (!binanceSymbol) return [];
|
|
26340
|
-
const klines = await
|
|
26312
|
+
const klines = await fetchKlines(
|
|
26341
26313
|
binanceSymbol,
|
|
26342
26314
|
toBinanceInterval(interval),
|
|
26343
26315
|
start,
|
|
@@ -26498,6 +26470,15 @@ function useSymmChartCandles(selection) {
|
|
|
26498
26470
|
wsUnsubsRef.current.push(unsub);
|
|
26499
26471
|
}
|
|
26500
26472
|
}, [emitRealtimeBar, isUnsupported, selectedSymbols]);
|
|
26473
|
+
const setRealtimeInterval = react.useCallback((interval) => {
|
|
26474
|
+
if (areIntervalsEqual(activeIntervalRef.current, interval)) {
|
|
26475
|
+
return;
|
|
26476
|
+
}
|
|
26477
|
+
activeIntervalRef.current = toBinanceInterval(interval);
|
|
26478
|
+
if (listenersRef.current.size > 0) {
|
|
26479
|
+
setupWsSubscriptions();
|
|
26480
|
+
}
|
|
26481
|
+
}, [setupWsSubscriptions]);
|
|
26501
26482
|
react.useEffect(() => {
|
|
26502
26483
|
if (listenersRef.current.size > 0) {
|
|
26503
26484
|
setupWsSubscriptions();
|
|
@@ -26509,6 +26490,7 @@ function useSymmChartCandles(selection) {
|
|
|
26509
26490
|
}, [setupWsSubscriptions]);
|
|
26510
26491
|
const fetchBasketCandles = react.useCallback(
|
|
26511
26492
|
async (start, end, interval) => {
|
|
26493
|
+
setRealtimeInterval(interval);
|
|
26512
26494
|
const longSymbol = longTokens[0]?.symbol;
|
|
26513
26495
|
const shortSymbol = shortTokens[0]?.symbol;
|
|
26514
26496
|
if (isUnsupported) {
|
|
@@ -26534,18 +26516,20 @@ function useSymmChartCandles(selection) {
|
|
|
26534
26516
|
Object.fromEntries(entries)
|
|
26535
26517
|
);
|
|
26536
26518
|
},
|
|
26537
|
-
[isUnsupported, longTokens, shortTokens]
|
|
26519
|
+
[isUnsupported, longTokens, setRealtimeInterval, shortTokens]
|
|
26538
26520
|
);
|
|
26539
26521
|
const fetchPerformanceCandles = react.useCallback(
|
|
26540
26522
|
async (start, end, interval, symbol) => {
|
|
26523
|
+
setRealtimeInterval(interval);
|
|
26541
26524
|
const parts = symbol.split(" ");
|
|
26542
26525
|
const assetSymbol = parts.length >= 2 ? parts.slice(1).join(" ") : symbol;
|
|
26543
26526
|
return fetchSymbolKlines(assetSymbol, interval, start, end);
|
|
26544
26527
|
},
|
|
26545
|
-
[]
|
|
26528
|
+
[setRealtimeInterval]
|
|
26546
26529
|
);
|
|
26547
26530
|
const fetchOverallPerformanceCandles = react.useCallback(
|
|
26548
26531
|
async (start, end, interval) => {
|
|
26532
|
+
setRealtimeInterval(interval);
|
|
26549
26533
|
const longSymbol = longTokens[0]?.symbol;
|
|
26550
26534
|
const shortSymbol = shortTokens[0]?.symbol;
|
|
26551
26535
|
if (isUnsupported) return [];
|
|
@@ -26602,7 +26586,7 @@ function useSymmChartCandles(selection) {
|
|
|
26602
26586
|
}
|
|
26603
26587
|
return result;
|
|
26604
26588
|
},
|
|
26605
|
-
[isUnsupported, longTokens, shortTokens]
|
|
26589
|
+
[isUnsupported, longTokens, setRealtimeInterval, shortTokens]
|
|
26606
26590
|
);
|
|
26607
26591
|
const addRealtimeListener = react.useCallback((cb) => {
|
|
26608
26592
|
const id = Math.random().toString(36).slice(2);
|