@pear-protocol/symmio-client 0.3.15 → 0.3.17
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/README.md +5 -5
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +12 -2
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +57 -18
- package/dist/react/index.d.ts +57 -18
- package/dist/react/index.js +118 -30
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +118 -31
- package/dist/react/index.mjs.map +1 -1
- package/dist/react/provider.js +47 -15
- package/dist/react/provider.js.map +1 -1
- package/dist/react/provider.mjs +47 -15
- package/dist/react/provider.mjs.map +1 -1
- package/package.json +5 -4
package/dist/react/index.js
CHANGED
|
@@ -75,6 +75,7 @@ var RECONNECT_DELAYS = [1e3, 2e3, 4e3, 8e3, 16e3, 3e4];
|
|
|
75
75
|
var IDLE_CLOSE_DELAY_MS = 3e4;
|
|
76
76
|
var STALE_CONNECTION_MS = 3e4;
|
|
77
77
|
var STALE_CHECK_INTERVAL_MS = 1e4;
|
|
78
|
+
var RECONNECT_RESET_MS = 6e4;
|
|
78
79
|
var STABLE_QUOTES = ["USDT0", "USDT", "USDC", "USDE", "USDH", "USD"];
|
|
79
80
|
function normalizeBaseSymbol(symbol) {
|
|
80
81
|
const normalized = symbol.toUpperCase().trim();
|
|
@@ -126,6 +127,7 @@ var BinanceWsManager = class {
|
|
|
126
127
|
reconnectTimer = null;
|
|
127
128
|
idleCloseTimer = null;
|
|
128
129
|
staleCheckTimer = null;
|
|
130
|
+
reconnectResetTimer = null;
|
|
129
131
|
intentionalClose = false;
|
|
130
132
|
pendingSubscribes = /* @__PURE__ */ new Set();
|
|
131
133
|
lastMessageAt = 0;
|
|
@@ -164,6 +166,7 @@ var BinanceWsManager = class {
|
|
|
164
166
|
const wrappedCb = (raw) => {
|
|
165
167
|
cb({
|
|
166
168
|
symbol: normalizeBaseSymbol(raw.s),
|
|
169
|
+
binanceSymbol: raw.s,
|
|
167
170
|
markPrice: parseFloat(raw.p),
|
|
168
171
|
indexPrice: parseFloat(raw.i),
|
|
169
172
|
time: raw.E,
|
|
@@ -185,6 +188,7 @@ var BinanceWsManager = class {
|
|
|
185
188
|
cb(
|
|
186
189
|
extractTickers(raw).map((entry) => ({
|
|
187
190
|
symbol: normalizeBaseSymbol(entry.s),
|
|
191
|
+
binanceSymbol: entry.s,
|
|
188
192
|
markPrice: parseFloat(entry.p),
|
|
189
193
|
indexPrice: parseFloat(entry.i),
|
|
190
194
|
time: entry.E,
|
|
@@ -204,6 +208,7 @@ var BinanceWsManager = class {
|
|
|
204
208
|
this.clearReconnectTimer();
|
|
205
209
|
this.clearIdleCloseTimer();
|
|
206
210
|
this.clearStaleCheckTimer();
|
|
211
|
+
this.clearReconnectResetTimer();
|
|
207
212
|
this.pendingSubscribes.clear();
|
|
208
213
|
if (this.ws) {
|
|
209
214
|
this.ws.close();
|
|
@@ -257,9 +262,9 @@ var BinanceWsManager = class {
|
|
|
257
262
|
this.intentionalClose = false;
|
|
258
263
|
this.ws = new WebSocket(BINANCE_WS_URL);
|
|
259
264
|
this.ws.onopen = () => {
|
|
260
|
-
this.reconnectAttempt = 0;
|
|
261
265
|
this.lastMessageAt = Date.now();
|
|
262
266
|
this.startStaleCheck();
|
|
267
|
+
this.scheduleReconnectReset();
|
|
263
268
|
const activeStreams = Array.from(
|
|
264
269
|
/* @__PURE__ */ new Set([...this.streams.keys(), ...this.pendingSubscribes])
|
|
265
270
|
);
|
|
@@ -272,6 +277,7 @@ var BinanceWsManager = class {
|
|
|
272
277
|
try {
|
|
273
278
|
const data = JSON.parse(event.data);
|
|
274
279
|
this.lastMessageAt = Date.now();
|
|
280
|
+
this.resetReconnectAttempt();
|
|
275
281
|
this.handleMessage(data);
|
|
276
282
|
} catch {
|
|
277
283
|
}
|
|
@@ -281,6 +287,7 @@ var BinanceWsManager = class {
|
|
|
281
287
|
this.intentionalClose = false;
|
|
282
288
|
this.ws = null;
|
|
283
289
|
this.clearStaleCheckTimer();
|
|
290
|
+
this.clearReconnectResetTimer();
|
|
284
291
|
if (this.streams.size === 0) {
|
|
285
292
|
return;
|
|
286
293
|
}
|
|
@@ -374,6 +381,17 @@ var BinanceWsManager = class {
|
|
|
374
381
|
this.ws.close();
|
|
375
382
|
}, STALE_CHECK_INTERVAL_MS);
|
|
376
383
|
}
|
|
384
|
+
scheduleReconnectReset() {
|
|
385
|
+
this.clearReconnectResetTimer();
|
|
386
|
+
this.reconnectResetTimer = setTimeout(() => {
|
|
387
|
+
this.reconnectResetTimer = null;
|
|
388
|
+
this.resetReconnectAttempt();
|
|
389
|
+
}, RECONNECT_RESET_MS);
|
|
390
|
+
}
|
|
391
|
+
resetReconnectAttempt() {
|
|
392
|
+
this.reconnectAttempt = 0;
|
|
393
|
+
this.clearReconnectResetTimer();
|
|
394
|
+
}
|
|
377
395
|
clearReconnectTimer() {
|
|
378
396
|
if (!this.reconnectTimer) return;
|
|
379
397
|
clearTimeout(this.reconnectTimer);
|
|
@@ -389,6 +407,11 @@ var BinanceWsManager = class {
|
|
|
389
407
|
clearInterval(this.staleCheckTimer);
|
|
390
408
|
this.staleCheckTimer = null;
|
|
391
409
|
}
|
|
410
|
+
clearReconnectResetTimer() {
|
|
411
|
+
if (!this.reconnectResetTimer) return;
|
|
412
|
+
clearTimeout(this.reconnectResetTimer);
|
|
413
|
+
this.reconnectResetTimer = null;
|
|
414
|
+
}
|
|
392
415
|
};
|
|
393
416
|
var BINANCE_WS_SINGLETON_KEY = "__pearBinanceWsManager__";
|
|
394
417
|
function getBinanceWsManager() {
|
|
@@ -406,15 +429,8 @@ var refCounts = /* @__PURE__ */ new Map();
|
|
|
406
429
|
var streamSymbols = /* @__PURE__ */ new Map();
|
|
407
430
|
var allMarkPricesRefCount = 0;
|
|
408
431
|
var allMarkPricesUnsubscribe = null;
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
const normalized = symbol.toUpperCase().trim();
|
|
412
|
-
for (const quote of STABLE_QUOTES2) {
|
|
413
|
-
if (normalized.endsWith(quote) && normalized.length > quote.length) {
|
|
414
|
-
return normalized.slice(0, -quote.length);
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
return normalized;
|
|
432
|
+
function normalizeBinanceSymbolKey(symbol) {
|
|
433
|
+
return symbol.toUpperCase().trim();
|
|
418
434
|
}
|
|
419
435
|
function getNextRefCount(binanceSymbol) {
|
|
420
436
|
return (refCounts.get(binanceSymbol) ?? 0) + 1;
|
|
@@ -449,7 +465,7 @@ var useBinanceMarkPriceStore = zustand.create((set) => ({
|
|
|
449
465
|
fundingRates: {},
|
|
450
466
|
nextFundingTimes: {},
|
|
451
467
|
subscribeSymbol: (symmSymbol, rawBinanceSymbol) => {
|
|
452
|
-
const binanceSymbol =
|
|
468
|
+
const binanceSymbol = normalizeBinanceSymbolKey(rawBinanceSymbol);
|
|
453
469
|
const nextRefCount = getNextRefCount(binanceSymbol);
|
|
454
470
|
refCounts.set(binanceSymbol, nextRefCount);
|
|
455
471
|
addMappedSymbol(binanceSymbol, symmSymbol);
|
|
@@ -461,8 +477,10 @@ var useBinanceMarkPriceStore = zustand.create((set) => ({
|
|
|
461
477
|
let nextFundingRates = null;
|
|
462
478
|
let nextFundingTimes = null;
|
|
463
479
|
entries.forEach((entry) => {
|
|
464
|
-
const
|
|
465
|
-
|
|
480
|
+
const binanceSymbolKey = normalizeBinanceSymbolKey(
|
|
481
|
+
entry.binanceSymbol ?? entry.symbol
|
|
482
|
+
);
|
|
483
|
+
const mappedSymbols = streamSymbols.get(binanceSymbolKey);
|
|
466
484
|
if (!mappedSymbols || mappedSymbols.size === 0) return;
|
|
467
485
|
nextMarkPrices ??= { ...state.markPrices };
|
|
468
486
|
nextFundingRates ??= { ...state.fundingRates };
|
|
@@ -487,7 +505,7 @@ var useBinanceMarkPriceStore = zustand.create((set) => ({
|
|
|
487
505
|
allMarkPricesRefCount += 1;
|
|
488
506
|
},
|
|
489
507
|
unsubscribeSymbol: (symmSymbol, rawBinanceSymbol) => {
|
|
490
|
-
const binanceSymbol =
|
|
508
|
+
const binanceSymbol = normalizeBinanceSymbolKey(rawBinanceSymbol);
|
|
491
509
|
const removedSubscription = removeMappedSymbol(binanceSymbol, symmSymbol);
|
|
492
510
|
if (!removedSubscription) {
|
|
493
511
|
return;
|
|
@@ -527,6 +545,7 @@ var useBinanceMarkPriceStore = zustand.create((set) => ({
|
|
|
527
545
|
}));
|
|
528
546
|
|
|
529
547
|
// src/react/hooks/use-binance-ws.ts
|
|
548
|
+
var BOOTSTRAP_RETRY_DELAYS_MS = [1e3, 2e3, 5e3];
|
|
530
549
|
function useBinanceWs(params) {
|
|
531
550
|
const { symmCoreClient, chainId } = params;
|
|
532
551
|
const subscribeSymbol = useBinanceMarkPriceStore((state) => state.subscribeSymbol);
|
|
@@ -537,7 +556,8 @@ function useBinanceWs(params) {
|
|
|
537
556
|
}
|
|
538
557
|
let cancelled = false;
|
|
539
558
|
let subscribedPairs = [];
|
|
540
|
-
|
|
559
|
+
let retryTimer = null;
|
|
560
|
+
const run = async (attempt = 0) => {
|
|
541
561
|
try {
|
|
542
562
|
const result = await symmCoreClient.markets.listSymmHedger({ chainId });
|
|
543
563
|
if (cancelled) {
|
|
@@ -557,11 +577,22 @@ function useBinanceWs(params) {
|
|
|
557
577
|
subscribeSymbol(symbol, binanceSymbol);
|
|
558
578
|
});
|
|
559
579
|
} catch {
|
|
580
|
+
const delay = BOOTSTRAP_RETRY_DELAYS_MS[attempt];
|
|
581
|
+
if (cancelled || delay == null) {
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
584
|
+
retryTimer = setTimeout(() => {
|
|
585
|
+
retryTimer = null;
|
|
586
|
+
void run(attempt + 1);
|
|
587
|
+
}, delay);
|
|
560
588
|
}
|
|
561
589
|
};
|
|
562
590
|
void run();
|
|
563
591
|
return () => {
|
|
564
592
|
cancelled = true;
|
|
593
|
+
if (retryTimer) {
|
|
594
|
+
clearTimeout(retryTimer);
|
|
595
|
+
}
|
|
565
596
|
subscribedPairs.forEach(([symbol, binanceSymbol]) => {
|
|
566
597
|
unsubscribeSymbol(symbol, binanceSymbol);
|
|
567
598
|
});
|
|
@@ -602,6 +633,7 @@ var symmKeys = {
|
|
|
602
633
|
triggerOrders: (params) => ["symm", "triggerOrders", params],
|
|
603
634
|
triggerConfig: (orderId) => ["symm", "triggerConfig", orderId],
|
|
604
635
|
markets: (chainId, search, pageSize) => ["symm", "markets", chainId, search, pageSize],
|
|
636
|
+
marketPositioning: (chainId, market) => ["symm", "marketPositioning", chainId, market],
|
|
605
637
|
hedgerMarketById: (id, chainId) => ["symm", "hedgerMarketById", id, chainId],
|
|
606
638
|
hedgerMarketBySymbol: (symbol, chainId) => ["symm", "hedgerMarketBySymbol", symbol, chainId],
|
|
607
639
|
lockedParams: (marketName, leverage, chainId) => ["symm", "lockedParams", marketName, leverage, chainId],
|
|
@@ -1674,6 +1706,7 @@ var SymmioSDKError = class extends Error {
|
|
|
1674
1706
|
this.code = code;
|
|
1675
1707
|
this.name = "SymmioSDKError";
|
|
1676
1708
|
}
|
|
1709
|
+
code;
|
|
1677
1710
|
};
|
|
1678
1711
|
function validateAddress(address, name) {
|
|
1679
1712
|
if (!viem.isAddress(address)) {
|
|
@@ -25895,15 +25928,24 @@ function readTimestamp(source) {
|
|
|
25895
25928
|
const parsed = Number(timestamp);
|
|
25896
25929
|
return Number.isFinite(parsed) ? parsed : void 0;
|
|
25897
25930
|
}
|
|
25931
|
+
function hasAccountDataShape(value) {
|
|
25932
|
+
return isRecord(value) && ("equity" in value || "maintenanceMargin" in value || "availableForOrder" in value || "totalLocked" in value);
|
|
25933
|
+
}
|
|
25898
25934
|
function getSymmAccountData(response) {
|
|
25899
25935
|
if (!isRecord(response)) {
|
|
25900
25936
|
return void 0;
|
|
25901
25937
|
}
|
|
25902
25938
|
const data = response.data;
|
|
25903
25939
|
if (isRecord(data)) {
|
|
25904
|
-
|
|
25940
|
+
if (hasAccountDataShape(data.accountData)) {
|
|
25941
|
+
return data.accountData;
|
|
25942
|
+
}
|
|
25943
|
+
if (hasAccountDataShape(data)) {
|
|
25944
|
+
return data;
|
|
25945
|
+
}
|
|
25946
|
+
return void 0;
|
|
25905
25947
|
}
|
|
25906
|
-
if (
|
|
25948
|
+
if (hasAccountDataShape(response)) {
|
|
25907
25949
|
return response;
|
|
25908
25950
|
}
|
|
25909
25951
|
return void 0;
|
|
@@ -26119,7 +26161,7 @@ function useSymmAccountOverview(params) {
|
|
|
26119
26161
|
chainId: params.chainId,
|
|
26120
26162
|
query: {
|
|
26121
26163
|
...params.query,
|
|
26122
|
-
enabled:
|
|
26164
|
+
enabled: params.query?.enabled ?? true
|
|
26123
26165
|
}
|
|
26124
26166
|
});
|
|
26125
26167
|
const data = react.useMemo(() => {
|
|
@@ -26641,6 +26683,34 @@ function useSymmMarkets(params) {
|
|
|
26641
26683
|
enabled: internalEnabled && (params?.query?.enabled ?? true)
|
|
26642
26684
|
});
|
|
26643
26685
|
}
|
|
26686
|
+
function normalizeMarket(market) {
|
|
26687
|
+
if (Array.isArray(market)) {
|
|
26688
|
+
const markets = market.map((marketName2) => marketName2.trim()).filter((marketName2) => marketName2.length > 0);
|
|
26689
|
+
return markets.length > 0 ? markets : void 0;
|
|
26690
|
+
}
|
|
26691
|
+
const marketName = market?.trim();
|
|
26692
|
+
return marketName ? marketName : void 0;
|
|
26693
|
+
}
|
|
26694
|
+
function hasMarket(market) {
|
|
26695
|
+
return Array.isArray(market) ? market.length > 0 : market !== void 0;
|
|
26696
|
+
}
|
|
26697
|
+
function useSymmMarketPositioning(params) {
|
|
26698
|
+
const { symmCoreClient, chainId: ctxChainId } = useSymmContext();
|
|
26699
|
+
const chainId = params?.chainId ?? ctxChainId;
|
|
26700
|
+
const market = normalizeMarket(params?.market);
|
|
26701
|
+
const internalEnabled = !!symmCoreClient && hasMarket(market);
|
|
26702
|
+
return reactQuery.useQuery({
|
|
26703
|
+
...params?.query,
|
|
26704
|
+
queryKey: symmKeys.marketPositioning(chainId, market),
|
|
26705
|
+
queryFn: () => {
|
|
26706
|
+
if (!hasMarket(market)) {
|
|
26707
|
+
throw new Error("Market is required to fetch positioning");
|
|
26708
|
+
}
|
|
26709
|
+
return symmCoreClient.markets.getPositioning({ chainId, market });
|
|
26710
|
+
},
|
|
26711
|
+
enabled: internalEnabled && (params?.query?.enabled ?? true)
|
|
26712
|
+
});
|
|
26713
|
+
}
|
|
26644
26714
|
function useSymmHedgerMarketById(params) {
|
|
26645
26715
|
const { symmCoreClient, chainId: ctxChainId } = useSymmContext();
|
|
26646
26716
|
const { id } = params;
|
|
@@ -26746,7 +26816,9 @@ async function fetch24hrTicker(symbol) {
|
|
|
26746
26816
|
return {
|
|
26747
26817
|
lastPrice: parseFloat(data.lastPrice),
|
|
26748
26818
|
openPrice: parseFloat(data.openPrice),
|
|
26749
|
-
priceChangePercent: parseFloat(data.priceChangePercent)
|
|
26819
|
+
priceChangePercent: parseFloat(data.priceChangePercent),
|
|
26820
|
+
volume: parseFloat(data.volume),
|
|
26821
|
+
quoteVolume: parseFloat(data.quoteVolume)
|
|
26750
26822
|
};
|
|
26751
26823
|
}
|
|
26752
26824
|
async function fetch24hrTickers() {
|
|
@@ -26760,7 +26832,9 @@ async function fetch24hrTickers() {
|
|
|
26760
26832
|
result[item.symbol] = {
|
|
26761
26833
|
lastPrice: parseFloat(item.lastPrice),
|
|
26762
26834
|
openPrice: parseFloat(item.openPrice),
|
|
26763
|
-
priceChangePercent: parseFloat(item.priceChangePercent)
|
|
26835
|
+
priceChangePercent: parseFloat(item.priceChangePercent),
|
|
26836
|
+
volume: parseFloat(item.volume),
|
|
26837
|
+
quoteVolume: parseFloat(item.quoteVolume)
|
|
26764
26838
|
};
|
|
26765
26839
|
}
|
|
26766
26840
|
return result;
|
|
@@ -26796,7 +26870,11 @@ function useSymmTokenSelectionMarkets(params) {
|
|
|
26796
26870
|
return;
|
|
26797
26871
|
}
|
|
26798
26872
|
const ticker = allTickers[binanceSymbol];
|
|
26799
|
-
tickerSnapshots[symbol] = ticker ? {
|
|
26873
|
+
tickerSnapshots[symbol] = ticker ? {
|
|
26874
|
+
openPrice: ticker.openPrice,
|
|
26875
|
+
volume: ticker.volume,
|
|
26876
|
+
quoteVolume: ticker.quoteVolume
|
|
26877
|
+
} : null;
|
|
26800
26878
|
});
|
|
26801
26879
|
return { tickerSnapshots };
|
|
26802
26880
|
},
|
|
@@ -26806,21 +26884,30 @@ function useSymmTokenSelectionMarkets(params) {
|
|
|
26806
26884
|
});
|
|
26807
26885
|
const markets = react.useMemo(() => {
|
|
26808
26886
|
const snapshots = priceQuery.data?.tickerSnapshots ?? {};
|
|
26809
|
-
return baseMarkets.map((market) => {
|
|
26887
|
+
return baseMarkets.map((market, index) => {
|
|
26810
26888
|
const symbol = market.symbol ?? "";
|
|
26811
26889
|
const markPrice = symbol ? liveMarkPrices[symbol] ?? null : null;
|
|
26812
|
-
const
|
|
26890
|
+
const ticker = symbol ? snapshots[symbol] ?? null : null;
|
|
26891
|
+
const prevDayPrice = ticker?.openPrice ?? null;
|
|
26813
26892
|
const priceChange24h = markPrice != null && prevDayPrice != null ? markPrice - prevDayPrice : null;
|
|
26814
26893
|
const priceChange24hPercent = markPrice != null && prevDayPrice != null && prevDayPrice !== 0 ? (markPrice - prevDayPrice) / prevDayPrice * 100 : null;
|
|
26815
26894
|
return {
|
|
26816
|
-
|
|
26817
|
-
|
|
26818
|
-
|
|
26819
|
-
|
|
26820
|
-
|
|
26821
|
-
|
|
26895
|
+
market: {
|
|
26896
|
+
...market,
|
|
26897
|
+
collateralToken: "USDC",
|
|
26898
|
+
markPrice,
|
|
26899
|
+
prevDayPrice,
|
|
26900
|
+
priceChange24h,
|
|
26901
|
+
priceChange24hPercent,
|
|
26902
|
+
volume24h: ticker?.volume ?? null,
|
|
26903
|
+
quoteVolume24h: ticker?.quoteVolume ?? null
|
|
26904
|
+
},
|
|
26905
|
+
index
|
|
26822
26906
|
};
|
|
26823
|
-
})
|
|
26907
|
+
}).sort((a, b) => {
|
|
26908
|
+
const volumeDelta = (b.market.quoteVolume24h ?? 0) - (a.market.quoteVolume24h ?? 0);
|
|
26909
|
+
return volumeDelta === 0 ? a.index - b.index : volumeDelta;
|
|
26910
|
+
}).map(({ market }) => market);
|
|
26824
26911
|
}, [baseMarkets, liveMarkPrices, priceQuery.data]);
|
|
26825
26912
|
const marketsBySymbol = react.useMemo(
|
|
26826
26913
|
() => new Map(
|
|
@@ -27881,6 +27968,7 @@ exports.useSymmInstantTradeExecuteMutation = useSymmInstantTradeExecuteMutation;
|
|
|
27881
27968
|
exports.useSymmInternalTransferCollateralMutation = useSymmInternalTransferCollateralMutation;
|
|
27882
27969
|
exports.useSymmLockedParams = useSymmLockedParams;
|
|
27883
27970
|
exports.useSymmMarkReadNotificationMutation = useSymmMarkReadNotificationMutation;
|
|
27971
|
+
exports.useSymmMarketPositioning = useSymmMarketPositioning;
|
|
27884
27972
|
exports.useSymmMarkets = useSymmMarkets;
|
|
27885
27973
|
exports.useSymmNotificationsQuery = useSymmNotificationsQuery;
|
|
27886
27974
|
exports.useSymmOpenBasketMutation = useSymmOpenBasketMutation;
|