@pear-protocol/symmio-client 0.2.29 → 0.2.31

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.
@@ -159,7 +159,9 @@ var BinanceWsManager = class {
159
159
  symbol: normalizeBaseSymbol(raw.s),
160
160
  markPrice: parseFloat(raw.p),
161
161
  indexPrice: parseFloat(raw.i),
162
- time: raw.E
162
+ time: raw.E,
163
+ fundingRate: parseFloat(raw.r ?? "0"),
164
+ nextFundingTime: Number(raw.T ?? 0)
163
165
  });
164
166
  };
165
167
  this.addStreamCallback(streamName, id, wrappedCb);
@@ -178,7 +180,9 @@ var BinanceWsManager = class {
178
180
  symbol: normalizeBaseSymbol(entry.s),
179
181
  markPrice: parseFloat(entry.p),
180
182
  indexPrice: parseFloat(entry.i),
181
- time: entry.E
183
+ time: entry.E,
184
+ fundingRate: parseFloat(entry.r ?? "0"),
185
+ nextFundingTime: Number(entry.T ?? 0)
182
186
  }))
183
187
  );
184
188
  };
@@ -358,6 +362,8 @@ function getPrevRefCount(binanceSymbol) {
358
362
  }
359
363
  var useBinanceMarkPriceStore = create((set) => ({
360
364
  markPrices: {},
365
+ fundingRates: {},
366
+ nextFundingTimes: {},
361
367
  subscribeSymbol: (symmSymbol, rawBinanceSymbol) => {
362
368
  const binanceSymbol = normalizeBinanceSymbol(rawBinanceSymbol);
363
369
  const nextRefCount = getNextRefCount(binanceSymbol);
@@ -370,16 +376,29 @@ var useBinanceMarkPriceStore = create((set) => ({
370
376
  allMarkPricesUnsubscribe = wsManager.subscribeAllMarkPrices((entries) => {
371
377
  set((state) => {
372
378
  let nextMarkPrices = null;
379
+ let nextFundingRates = null;
380
+ let nextFundingTimes = null;
373
381
  entries.forEach((entry) => {
374
382
  const canonicalSymbol = normalizeBinanceSymbol(entry.symbol);
375
383
  const mappedSymbols = streamSymbols.get(canonicalSymbol);
376
384
  if (!mappedSymbols || mappedSymbols.size === 0) return;
377
385
  nextMarkPrices ??= { ...state.markPrices };
386
+ nextFundingRates ??= { ...state.fundingRates };
387
+ nextFundingTimes ??= { ...state.nextFundingTimes };
378
388
  mappedSymbols.forEach((mappedSymbol) => {
379
389
  nextMarkPrices[mappedSymbol] = entry.markPrice;
390
+ nextFundingRates[mappedSymbol] = entry.fundingRate;
391
+ nextFundingTimes[mappedSymbol] = entry.nextFundingTime;
380
392
  });
381
393
  });
382
- return nextMarkPrices ? { markPrices: nextMarkPrices } : state;
394
+ if (!nextMarkPrices || !nextFundingRates || !nextFundingTimes) {
395
+ return state;
396
+ }
397
+ return {
398
+ markPrices: nextMarkPrices,
399
+ fundingRates: nextFundingRates,
400
+ nextFundingTimes
401
+ };
383
402
  });
384
403
  });
385
404
  }
@@ -408,10 +427,20 @@ var useBinanceMarkPriceStore = create((set) => ({
408
427
  allMarkPricesUnsubscribe = null;
409
428
  }
410
429
  set((state) => {
411
- if (state.markPrices[symmSymbol] == null) return state;
430
+ if (state.markPrices[symmSymbol] == null && state.fundingRates[symmSymbol] == null && state.nextFundingTimes[symmSymbol] == null) {
431
+ return state;
432
+ }
412
433
  const nextMarkPrices = { ...state.markPrices };
434
+ const nextFundingRates = { ...state.fundingRates };
435
+ const nextFundingTimes = { ...state.nextFundingTimes };
413
436
  delete nextMarkPrices[symmSymbol];
414
- return { markPrices: nextMarkPrices };
437
+ delete nextFundingRates[symmSymbol];
438
+ delete nextFundingTimes[symmSymbol];
439
+ return {
440
+ markPrices: nextMarkPrices,
441
+ fundingRates: nextFundingRates,
442
+ nextFundingTimes
443
+ };
415
444
  });
416
445
  }
417
446
  }));
@@ -25560,7 +25589,9 @@ function useSymmTokenSelectionMarkets(params) {
25560
25589
  }, [baseMarkets, liveMarkPrices, priceQuery.data]);
25561
25590
  const marketsBySymbol = useMemo(
25562
25591
  () => new Map(
25563
- markets.filter((m) => !!m.symbol).map((m) => [m.symbol, m])
25592
+ markets.filter(
25593
+ (m) => !!m.symbol
25594
+ ).map((m) => [m.symbol, m])
25564
25595
  ),
25565
25596
  [markets]
25566
25597
  );
@@ -25568,64 +25599,7 @@ function useSymmTokenSelectionMarkets(params) {
25568
25599
  () => new Map(markets.map((market) => [market.id, market])),
25569
25600
  [markets]
25570
25601
  );
25571
- useEffect(() => {
25572
- console.debug("[useSymmTokenSelectionMarkets] data flow", {
25573
- params,
25574
- query: {
25575
- status: query.status,
25576
- fetchStatus: query.fetchStatus,
25577
- isLoading: query.isLoading,
25578
- isSuccess: query.isSuccess,
25579
- isError: query.isError,
25580
- error: query.error
25581
- },
25582
- priceQuery: {
25583
- status: priceQuery.status,
25584
- fetchStatus: priceQuery.fetchStatus,
25585
- isLoading: priceQuery.isLoading,
25586
- isSuccess: priceQuery.isSuccess,
25587
- isError: priceQuery.isError,
25588
- error: priceQuery.error
25589
- },
25590
- marketSymbols,
25591
- symbolsKey,
25592
- liveMarkPrices,
25593
- tickerSnapshots: priceQuery.data?.tickerSnapshots ?? {},
25594
- result: {
25595
- marketCount: markets.length,
25596
- markets: markets.map((market) => ({
25597
- id: market.id,
25598
- symbol: market.symbol,
25599
- markPrice: market.markPrice,
25600
- prevDayPrice: market.prevDayPrice,
25601
- priceChange24h: market.priceChange24h,
25602
- priceChange24hPercent: market.priceChange24hPercent
25603
- }))
25604
- }
25605
- });
25606
- }, [
25607
- liveMarkPrices,
25608
- marketSymbols,
25609
- markets,
25610
- params,
25611
- priceQuery.data,
25612
- priceQuery.error,
25613
- priceQuery.fetchStatus,
25614
- priceQuery.isError,
25615
- priceQuery.isLoading,
25616
- priceQuery.isSuccess,
25617
- priceQuery.status,
25618
- query.error,
25619
- query.fetchStatus,
25620
- query.isError,
25621
- query.isLoading,
25622
- query.isSuccess,
25623
- query.status,
25624
- symbolsKey
25625
- ]);
25626
25602
  return {
25627
- query,
25628
- priceQuery,
25629
25603
  markets,
25630
25604
  marketsBySymbol,
25631
25605
  marketsById,
@@ -26024,6 +25998,12 @@ function useSymmChartSelection(input) {
26024
25998
  }
26025
25999
 
26026
26000
  // src/utils/chart-metrics.ts
26001
+ function normalizeWeight(weight) {
26002
+ if (!Number.isFinite(weight) || weight <= 0) {
26003
+ return 0;
26004
+ }
26005
+ return weight <= 1 ? weight : weight / 100;
26006
+ }
26027
26007
  function getPositiveValue(metadata, field) {
26028
26008
  const value = metadata?.[field];
26029
26009
  if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
@@ -26043,7 +26023,8 @@ function computeWeightedProduct(tokens, metadataMap, field, invert = false) {
26043
26023
  return null;
26044
26024
  }
26045
26025
  hasToken = true;
26046
- const exponent = invert ? -(token.weight / 100) : token.weight / 100;
26026
+ const normalizedWeight = normalizeWeight(token.weight);
26027
+ const exponent = invert ? -normalizedWeight : normalizedWeight;
26047
26028
  product *= Math.pow(price, exponent);
26048
26029
  }
26049
26030
  return hasToken ? product : 1;
@@ -26166,7 +26147,7 @@ async function fetchTickerSnapshot(symbol) {
26166
26147
  openPrice: ticker.openPrice
26167
26148
  };
26168
26149
  }
26169
- function toSymmTokenMetadata(currentPrice, prevDayPrice) {
26150
+ function toSymmTokenMetadata(currentPrice, prevDayPrice, fundingRate, nextFundingTime) {
26170
26151
  const priceChange24h = currentPrice - prevDayPrice;
26171
26152
  const priceChange24hPercent = prevDayPrice !== 0 ? (currentPrice - prevDayPrice) / prevDayPrice * 100 : 0;
26172
26153
  return {
@@ -26174,9 +26155,10 @@ function toSymmTokenMetadata(currentPrice, prevDayPrice) {
26174
26155
  prevDayPrice,
26175
26156
  priceChange24h,
26176
26157
  priceChange24hPercent,
26177
- netFunding: 0,
26178
- // SYMM funding integration deferred
26179
- markPrice: currentPrice
26158
+ netFunding: fundingRate,
26159
+ markPrice: currentPrice,
26160
+ fundingRate,
26161
+ nextFundingTime
26180
26162
  };
26181
26163
  }
26182
26164
  function useSymmTokenSelectionMetadata(selection, options = {}) {
@@ -26190,6 +26172,12 @@ function useSymmTokenSelectionMetadata(selection, options = {}) {
26190
26172
  const unavailableReason = isUnsupported ? `Binance market data is unavailable for ${unsupportedSymbols.join(", ")}.` : null;
26191
26173
  const symbolsKey = [...selectedSymbols].sort().join(",");
26192
26174
  const liveMarkPrices = useBinanceMarkPriceStore((state) => state.markPrices);
26175
+ const liveFundingRates = useBinanceMarkPriceStore(
26176
+ (state) => state.fundingRates
26177
+ );
26178
+ const liveNextFundingTimes = useBinanceMarkPriceStore(
26179
+ (state) => state.nextFundingTimes
26180
+ );
26193
26181
  const query = useQuery({
26194
26182
  queryKey: ["symm", "chart-metadata", symbolsKey],
26195
26183
  queryFn: async () => {
@@ -26222,13 +26210,27 @@ function useSymmTokenSelectionMetadata(selection, options = {}) {
26222
26210
  const isLoading = query.isLoading;
26223
26211
  for (const token of longTokens) {
26224
26212
  const currentPrice = liveMarkPrices[token.symbol];
26213
+ const fundingRate = liveFundingRates[token.symbol];
26214
+ const nextFundingTime = liveNextFundingTimes[token.symbol];
26225
26215
  const ticker = tickerSnapshots[token.symbol];
26226
- longMeta[token.symbol] = currentPrice != null && ticker ? toSymmTokenMetadata(currentPrice, ticker.openPrice) : null;
26216
+ longMeta[token.symbol] = currentPrice != null && ticker ? toSymmTokenMetadata(
26217
+ currentPrice,
26218
+ ticker.openPrice,
26219
+ fundingRate ?? 0,
26220
+ nextFundingTime ?? 0
26221
+ ) : null;
26227
26222
  }
26228
26223
  for (const token of shortTokens) {
26229
26224
  const currentPrice = liveMarkPrices[token.symbol];
26225
+ const fundingRate = liveFundingRates[token.symbol];
26226
+ const nextFundingTime = liveNextFundingTimes[token.symbol];
26230
26227
  const ticker = tickerSnapshots[token.symbol];
26231
- shortMeta[token.symbol] = currentPrice != null && ticker ? toSymmTokenMetadata(currentPrice, ticker.openPrice) : null;
26228
+ shortMeta[token.symbol] = currentPrice != null && ticker ? toSymmTokenMetadata(
26229
+ currentPrice,
26230
+ ticker.openPrice,
26231
+ fundingRate ?? 0,
26232
+ nextFundingTime ?? 0
26233
+ ) : null;
26232
26234
  }
26233
26235
  const allLongReady = longTokens.every(
26234
26236
  (t) => longMeta[t.symbol]?.currentPrice != null
@@ -26249,7 +26251,6 @@ function useSymmTokenSelectionMetadata(selection, options = {}) {
26249
26251
  const weightedRatio24h = computeWeightedRatio24h(metricInput) ?? 0;
26250
26252
  const sumNetFunding = computeNetFundingSum(metricInput);
26251
26253
  return {
26252
- query,
26253
26254
  isLoading,
26254
26255
  isPriceDataReady,
26255
26256
  isUnsupported,
@@ -26266,60 +26267,17 @@ function useSymmTokenSelectionMetadata(selection, options = {}) {
26266
26267
  }, [
26267
26268
  isUnsupported,
26268
26269
  longTokens,
26270
+ query,
26269
26271
  query.data,
26270
26272
  query.isLoading,
26271
26273
  shortTokens,
26272
26274
  unavailableReason,
26273
26275
  unsupportedSymbols,
26274
26276
  selectedSymbols.length,
26277
+ liveFundingRates,
26278
+ liveNextFundingTimes,
26275
26279
  liveMarkPrices
26276
26280
  ]);
26277
- useEffect(() => {
26278
- console.debug("[useSymmTokenSelectionMetadata] data flow", {
26279
- selection,
26280
- options,
26281
- query: {
26282
- status: query.status,
26283
- fetchStatus: query.fetchStatus,
26284
- isLoading: query.isLoading,
26285
- isSuccess: query.isSuccess,
26286
- isError: query.isError,
26287
- error: query.error
26288
- },
26289
- selectedSymbols,
26290
- unsupportedSymbols,
26291
- unavailableReason,
26292
- liveMarkPrices,
26293
- tickerSnapshots: query.data?.tickerSnapshots ?? {},
26294
- result: {
26295
- isLoading: result.isLoading,
26296
- isPriceDataReady: result.isPriceDataReady,
26297
- isUnsupported: result.isUnsupported,
26298
- longTokensMetadata: result.longTokensMetadata,
26299
- shortTokensMetadata: result.shortTokensMetadata,
26300
- weightedRatio: result.weightedRatio,
26301
- weightedRatio24h: result.weightedRatio24h,
26302
- priceRatio: result.priceRatio,
26303
- priceRatio24h: result.priceRatio24h,
26304
- sumNetFunding: result.sumNetFunding
26305
- }
26306
- });
26307
- }, [
26308
- liveMarkPrices,
26309
- options,
26310
- query.data,
26311
- query.error,
26312
- query.fetchStatus,
26313
- query.isError,
26314
- query.isLoading,
26315
- query.isSuccess,
26316
- query.status,
26317
- result,
26318
- selectedSymbols,
26319
- selection,
26320
- unavailableReason,
26321
- unsupportedSymbols
26322
- ]);
26323
26281
  return result;
26324
26282
  }
26325
26283
 
@@ -26349,6 +26307,12 @@ function toBinanceInterval(interval) {
26349
26307
  }
26350
26308
 
26351
26309
  // src/react/hooks/use-symm-chart-candles.ts
26310
+ function normalizeWeight2(weight) {
26311
+ if (!Number.isFinite(weight) || weight <= 0) {
26312
+ return 0;
26313
+ }
26314
+ return weight <= 1 ? weight : weight / 100;
26315
+ }
26352
26316
  function areIntervalsEqual(currentInterval, nextInterval) {
26353
26317
  return currentInterval === toBinanceInterval(nextInterval);
26354
26318
  }
@@ -26386,7 +26350,8 @@ function computeWeightedValues(tokens, candlesBySymbol, invert = false) {
26386
26350
  if (!(candle.o > 0 && candle.h > 0 && candle.l > 0 && candle.c > 0)) {
26387
26351
  return null;
26388
26352
  }
26389
- const exponent = invert ? -(token.weight / 100) : token.weight / 100;
26353
+ const normalizedWeight = normalizeWeight2(token.weight);
26354
+ const exponent = invert ? -normalizedWeight : normalizedWeight;
26390
26355
  o *= Math.pow(candle.o, exponent);
26391
26356
  h *= Math.pow(candle.h, exponent);
26392
26357
  l *= Math.pow(candle.l, exponent);