@orderly.network/hooks 2.0.1-alpha.6 → 2.0.1-alpha.8

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/index.mjs CHANGED
@@ -3,11 +3,11 @@ export { unstable_serialize, default as useSWR, useSWRConfig } from 'swr';
3
3
  import { get, WS, mutate as mutate$1 } from '@orderly.network/net';
4
4
  import React, { createContext, useContext, useState, useEffect, useCallback, useMemo, useRef, useId, useLayoutEffect } from 'react';
5
5
  import useSWRMutation from 'swr/mutation';
6
- import useConstant5 from 'use-constant';
6
+ import useConstant from 'use-constant';
7
7
  export { default as useConstant } from 'use-constant';
8
8
  import { SimpleDI, Account, EventEmitter, EVENT_NAMES, DefaultConfigStore, LocalStorageStore } from '@orderly.network/core';
9
9
  import { zero, getGlobalObject, getTimestamp, Decimal, timeConvertString, isTestnet, getPrecisionByNumber, camelCaseToUnderscoreCase, windowGuard, removeTrailingZeros, commify, todpIfNeed } from '@orderly.network/utils';
10
- import { OrderSide, OrderType, AccountStatusEnum, SDKError, OrderStatus, AlgoOrderRootType, TestnetChains, nativeTokenAddress, chainsInfoMap, ARBITRUM_TESTNET_CHAINID, ARBITRUM_MAINNET_CHAINID, isNativeTokenChecker, ChainNamespace, MaxUint256, DEPOSIT_FEE_RATE, AlgoOrderType, TriggerPriceType } from '@orderly.network/types';
10
+ import { OrderSide, OrderType, EnumTrackerKeys, AccountStatusEnum, SDKError, OrderStatus, AlgoOrderRootType, nativeTokenAddress, chainsInfoMap, ARBITRUM_TESTNET_CHAINID, ARBITRUM_MAINNET_CHAINID, isNativeTokenChecker, ChainNamespace, MaxUint256, DEPOSIT_FEE_RATE, TrackerListenerKeyMap, AlgoOrderType, TriggerPriceType } from '@orderly.network/types';
11
11
  import useSWRInfinite, { unstable_serialize } from 'swr/infinite';
12
12
  import { jsx } from 'react/jsx-runtime';
13
13
  import { pathOr, prop, omit, pick, compose, head, mergeDeepRight, min, max, propOr, isNil, path, lensIndex, over } from 'ramda';
@@ -21,6 +21,7 @@ import { produce } from 'immer';
21
21
  import { DefaultEVMWalletAdapter } from '@orderly.network/default-evm-adapter';
22
22
  import { DefaultSolanaWalletAdapter } from '@orderly.network/default-solana-adapter';
23
23
  import { EthersProvider } from '@orderly.network/web3-provider-ethers';
24
+ import * as amplitude from '@amplitude/analytics-browser';
24
25
  import { qrcode } from '@akamfoad/qr';
25
26
 
26
27
  var __defProp = Object.defineProperty;
@@ -32,10 +33,10 @@ var __export = (target, all) => {
32
33
  // src/version.ts
33
34
  if (typeof window !== "undefined") {
34
35
  window.__ORDERLY_VERSION__ = window.__ORDERLY_VERSION__ || {};
35
- window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "2.0.1-alpha.6";
36
+ window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "2.0.1-alpha.8";
36
37
  }
37
- var version_default = "2.0.1-alpha.6";
38
- var fetcher = (url, init = {}, queryOptions) => get(url, init, queryOptions?.formatter);
38
+ var version_default = "2.0.1-alpha.8";
39
+ var fetcher = (url, init2 = {}, queryOptions) => get(url, init2, queryOptions?.formatter);
39
40
  var OrderlyContext = createContext({
40
41
  // configStore: new MemoryConfigStore(),
41
42
  });
@@ -44,6 +45,11 @@ var OrderlyProvider = OrderlyContext.Provider;
44
45
  // src/useConfig.ts
45
46
  function useConfig(key, defaultValue) {
46
47
  const { configStore } = useContext(OrderlyContext);
48
+ if (!configStore) {
49
+ throw new Error(
50
+ "useConfig must be used within OrderlyConfigProvider or OrderlyAppProvider"
51
+ );
52
+ }
47
53
  if (typeof key !== "undefined") {
48
54
  if (typeof defaultValue !== "undefined") {
49
55
  return configStore.getOr(key, defaultValue);
@@ -62,7 +68,7 @@ var useQuery = (query, options) => {
62
68
  }
63
69
  return useSWR(
64
70
  query,
65
- (url, init) => fetcher(url.startsWith("http") ? url : `${apiBaseUrl}${url}`, init, {
71
+ (url, init2) => fetcher(url.startsWith("http") ? url : `${apiBaseUrl}${url}`, init2, {
66
72
  formatter
67
73
  }),
68
74
  swrOptions
@@ -70,7 +76,7 @@ var useQuery = (query, options) => {
70
76
  };
71
77
  var useLazyQuery = (query, options) => {
72
78
  const apiBaseUrl = useConfig("apiBaseUrl");
73
- const { formatter, init, ...swrOptions } = options || {};
79
+ const { formatter, init: init2, ...swrOptions } = options || {};
74
80
  if (typeof apiBaseUrl === "undefined") {
75
81
  throw new Error("please add OrderlyConfigProvider to your app");
76
82
  }
@@ -84,7 +90,7 @@ var useLazyQuery = (query, options) => {
84
90
  ).join("&");
85
91
  url = `${url}?${queryString}`;
86
92
  }
87
- return fetcher(url, init, {
93
+ return fetcher(url, init2, {
88
94
  formatter
89
95
  });
90
96
  },
@@ -100,7 +106,7 @@ var useAccountInstance = () => {
100
106
  "keyStore is not defined, please use OrderlyProvider and provide keyStore"
101
107
  );
102
108
  }
103
- const account5 = useConstant5(() => {
109
+ const account5 = useConstant(() => {
104
110
  let account6 = SimpleDI.get("account");
105
111
  if (!account6) {
106
112
  account6 = new Account(
@@ -116,20 +122,20 @@ var useAccountInstance = () => {
116
122
  return account5;
117
123
  };
118
124
  var fetcher2 = (url, options) => {
119
- const init = {
125
+ const init2 = {
120
126
  method: options.arg.method,
121
127
  headers: {
122
128
  ...options.arg.signature
123
129
  }
124
130
  };
125
131
  if (options.arg.data) {
126
- init.body = JSON.stringify(options.arg.data);
132
+ init2.body = JSON.stringify(options.arg.data);
127
133
  }
128
134
  if (typeof options.arg.params === "object" && Object.keys(options.arg.params).length) {
129
135
  let search = new URLSearchParams(options.arg.params);
130
136
  url = `${url}?${search.toString()}`;
131
137
  }
132
- return mutate$1(url, init);
138
+ return mutate$1(url, init2);
133
139
  };
134
140
  var useMutation = (url, method = "POST", options) => {
135
141
  const apiBaseUrl = useConfig("apiBaseUrl");
@@ -207,6 +213,16 @@ var signatureMiddleware = (useSWRNext) => {
207
213
  }
208
214
  };
209
215
  };
216
+ var useEventEmitter = () => {
217
+ return useConstant(() => {
218
+ let ee = SimpleDI.get("EE");
219
+ if (!ee) {
220
+ ee = new EventEmitter();
221
+ SimpleDI.registerByName("EE", ee);
222
+ }
223
+ return ee;
224
+ });
225
+ };
210
226
  var useAccount = () => {
211
227
  const {
212
228
  configStore,
@@ -224,7 +240,13 @@ var useAccount = () => {
224
240
  }
225
241
  const account5 = useAccountInstance();
226
242
  const [state, setState] = useState(account5.stateValue);
243
+ const ee = useEventEmitter();
227
244
  const statusChangeHandler = (nextState) => {
245
+ if (AccountStatusEnum.Connected === nextState.status) {
246
+ ee.emit(EnumTrackerKeys.WALLET_CONNECT, {
247
+ ...nextState
248
+ });
249
+ }
228
250
  setState(() => nextState);
229
251
  };
230
252
  useEffect(() => {
@@ -235,9 +257,13 @@ var useAccount = () => {
235
257
  }, []);
236
258
  const createOrderlyKey = useCallback(
237
259
  async (remember) => {
260
+ ee.emit(EnumTrackerKeys.SIGNIN_SUCCESS, {
261
+ ...state,
262
+ ...account5
263
+ });
238
264
  return account5.createOrderlyKey(remember ? 365 : 30);
239
265
  },
240
- [account5]
266
+ [account5, state]
241
267
  );
242
268
  const createAccount = useCallback(async () => {
243
269
  return account5.createAccount();
@@ -261,8 +287,8 @@ var usePrivateQuery = (query, options) => {
261
287
  const middleware = Array.isArray(options?.use) ? options?.use ?? [] : [];
262
288
  return useSWR(
263
289
  () => account5.state.status >= AccountStatusEnum.EnableTrading ? [query, account5.state.accountId] : null,
264
- (url, init) => {
265
- return fetcher(url, init, { formatter });
290
+ (url, init2) => {
291
+ return fetcher(url, init2, { formatter });
266
292
  },
267
293
  {
268
294
  ...swrOptions,
@@ -284,8 +310,8 @@ var usePrivateInfiniteQuery = (getKey, options) => {
284
310
  }
285
311
  return [queryKey, account5.state.accountId];
286
312
  },
287
- (url, init) => {
288
- return restOptions.fetcher?.(url, init) || get(url, init, formatter);
313
+ (url, init2) => {
314
+ return restOptions.fetcher?.(url, init2) || get(url, init2, formatter);
289
315
  },
290
316
  {
291
317
  ...restOptions,
@@ -312,10 +338,10 @@ var usePreLoadData = () => {
312
338
  const apiBaseUrl = useConfig("apiBaseUrl");
313
339
  const { data: systemInfo } = useSWR(
314
340
  "/v1/public/system_info",
315
- async (url, init) => {
341
+ async (url, init2) => {
316
342
  const data = await fetch(
317
343
  url.startsWith("http") ? url : `${apiBaseUrl}${url}`,
318
- init
344
+ init2
319
345
  );
320
346
  return await data.json();
321
347
  },
@@ -346,16 +372,6 @@ var usePreLoadData = () => {
346
372
  done: isDone
347
373
  };
348
374
  };
349
- var useEventEmitter = () => {
350
- return useConstant5(() => {
351
- let ee = SimpleDI.get("EE");
352
- if (!ee) {
353
- ee = new EventEmitter();
354
- SimpleDI.registerByName("EE", ee);
355
- }
356
- return ee;
357
- });
358
- };
359
375
 
360
376
  // src/utils/json.ts
361
377
  function parseJSON(value) {
@@ -453,10 +469,25 @@ function useLocalStorage(key, initialValue) {
453
469
  }, [key]);
454
470
  return [storedValue, setValue];
455
471
  }
472
+
473
+ // src/useNetworkInfo.ts
474
+ var useNetworkInfo = (networkId) => {
475
+ const [allChains, { findByChainId }] = useChains(networkId, {
476
+ pick: "network_infos",
477
+ filter: (chain) => chain.network_infos?.bridge_enable || chain.network_infos?.bridgeless
478
+ });
479
+ return (chainId) => {
480
+ const chain = findByChainId(chainId);
481
+ return {
482
+ id: chainId,
483
+ info: chain
484
+ };
485
+ };
486
+ };
456
487
  var WS_NAME = "nativeWebsocketClient";
457
488
  var useWS = () => {
458
489
  const { configStore } = useContext(OrderlyContext);
459
- const ws = useConstant5(() => {
490
+ const ws = useConstant(() => {
460
491
  let websocketClient = SimpleDI.get(WS_NAME);
461
492
  const account5 = SimpleDI.get(Account.instanceName);
462
493
  if (!websocketClient) {
@@ -558,6 +589,16 @@ var BaseMergeHandler = class {
558
589
  if (!data.created_time) {
559
590
  data.created_time = data.timestamp;
560
591
  }
592
+ if (data.status === OrderStatus.FILLED && !data.updated_time) {
593
+ data.updated_time = data.timestamp;
594
+ }
595
+ if (data.child_orders && data.child_orders.length) {
596
+ data.child_orders.map((child) => {
597
+ if (child.algo_status === OrderStatus.FILLED && child.is_activated && !child.updated_time) {
598
+ child.updated_time = data.timestamp;
599
+ }
600
+ });
601
+ }
561
602
  if (data.type && data.type.endsWith("_ORDER")) {
562
603
  data.type = data.type.replace("_ORDER", "");
563
604
  }
@@ -587,7 +628,8 @@ var BaseMergeHandler = class {
587
628
  return this.update(prevData);
588
629
  case "FILLED": {
589
630
  if (this.orderIsExisting(prevData)) {
590
- if (key.startsWith("orders:INCOMPLETE") || key.startsWith("orders:NEW")) {
631
+ if (key.startsWith("orders:INCOMPLETE") || key.startsWith("orders:NEW") || // all orders key
632
+ key.startsWith("orders:")) {
591
633
  if (this.isFullFilled()) {
592
634
  return this.remove(prevData);
593
635
  }
@@ -1588,6 +1630,18 @@ var PortfolioCalculator = class extends BaseCalculator {
1588
1630
  (output) => output.positionCalculator_all
1589
1631
  );
1590
1632
  let holding = portfolio.holding;
1633
+ if (scope === "portfolio" /* PORTFOLIO */ && data.holding && Array.isArray(holding)) {
1634
+ holding = holding.map((item) => {
1635
+ if (data.holding[item.token]) {
1636
+ return {
1637
+ ...item,
1638
+ holding: data.holding[item.token].holding,
1639
+ frozen: data.holding[item.token].frozen
1640
+ };
1641
+ }
1642
+ return item;
1643
+ });
1644
+ }
1591
1645
  const accountInfo = ctx.accountInfo;
1592
1646
  const symbolsInfo = ctx.symbolsInfo;
1593
1647
  return this.format({
@@ -1697,7 +1751,7 @@ var IndexPriceCalculator = class extends BaseCalculator {
1697
1751
  // src/useCalculatorService.ts
1698
1752
  var useCalculatorService = () => {
1699
1753
  const { get: get3 } = useSimpleDI();
1700
- const calculatorService = useConstant5(() => {
1754
+ const calculatorService = useConstant(() => {
1701
1755
  let calculatorService2 = get3(CalculatorServiceID);
1702
1756
  if (!calculatorService2) {
1703
1757
  const positionCalculator = new PositionCalculator();
@@ -2205,13 +2259,39 @@ var useOrderbookStream = (symbol, initial = INIT_DATA, options) => {
2205
2259
  });
2206
2260
  useEffect(() => {
2207
2261
  const updateData = [
2208
- reducedData.asks?.[reducedData.asks.length - 1]?.[0],
2209
- reducedData.bids?.[0]?.[0]
2262
+ [
2263
+ reducedData.asks?.[reducedData.asks.length - 1]?.[0],
2264
+ reducedData.bids?.[0]?.[0]
2265
+ ],
2266
+ [
2267
+ reducedData.asks?.[reducedData.asks.length - 2]?.[0],
2268
+ reducedData.bids?.[1]?.[0]
2269
+ ],
2270
+ [
2271
+ reducedData.asks?.[reducedData.asks.length - 3]?.[0],
2272
+ reducedData.bids?.[2]?.[0]
2273
+ ],
2274
+ [
2275
+ reducedData.asks?.[reducedData.asks.length - 4]?.[0],
2276
+ reducedData.bids?.[3]?.[0]
2277
+ ],
2278
+ [
2279
+ reducedData.asks?.[reducedData.asks.length - 5]?.[0],
2280
+ reducedData.bids?.[4]?.[0]
2281
+ ]
2210
2282
  ];
2211
2283
  eventEmitter.emit("orderbook:update", updateData);
2212
2284
  }, [
2213
2285
  reducedData.asks?.[reducedData.asks.length - 1]?.[0],
2214
- reducedData.bids?.[0]?.[0]
2286
+ reducedData.asks?.[reducedData.asks.length - 2]?.[0],
2287
+ reducedData.asks?.[reducedData.asks.length - 3]?.[0],
2288
+ reducedData.asks?.[reducedData.asks.length - 4]?.[0],
2289
+ reducedData.asks?.[reducedData.asks.length - 5]?.[0],
2290
+ reducedData.bids?.[0]?.[0],
2291
+ reducedData.bids?.[1]?.[0],
2292
+ reducedData.bids?.[2]?.[0],
2293
+ reducedData.bids?.[3]?.[0],
2294
+ reducedData.bids?.[4]?.[0]
2215
2295
  ]);
2216
2296
  const middlePrice = useMemo(() => {
2217
2297
  let asksFrist = 0, bidsFirst = 0;
@@ -2556,6 +2636,7 @@ var MarketsType = /* @__PURE__ */ ((MarketsType2) => {
2556
2636
  MarketsType2[MarketsType2["FAVORITES"] = 0] = "FAVORITES";
2557
2637
  MarketsType2[MarketsType2["RECENT"] = 1] = "RECENT";
2558
2638
  MarketsType2[MarketsType2["ALL"] = 2] = "ALL";
2639
+ MarketsType2[MarketsType2["NEW_LISTING"] = 3] = "NEW_LISTING";
2559
2640
  return MarketsType2;
2560
2641
  })(MarketsType || {});
2561
2642
  var MarketsStorageKey = "orderly_markets";
@@ -2592,6 +2673,9 @@ var useMarketsStore = () => {
2592
2673
  const getRecent = () => {
2593
2674
  return getStoreByKey("recent", []);
2594
2675
  };
2676
+ const getNewListing = () => {
2677
+ return getStoreByKey("newListing", []);
2678
+ };
2595
2679
  const getTabSort = () => {
2596
2680
  return getStoreByKey("tabSort", {});
2597
2681
  };
@@ -2601,6 +2685,7 @@ var useMarketsStore = () => {
2601
2685
  );
2602
2686
  const [favorites, setFavorites] = useState(getFavorites);
2603
2687
  const [recent, setRecent] = useState(getRecent);
2688
+ const [newListing, setNewListing] = useState(getNewListing);
2604
2689
  const [tabSort, setTabSort] = useState(getTabSort);
2605
2690
  const updateFavoriteTabs = (tab, operator) => {
2606
2691
  const tabs = updateTabs(favoriteTabs, tab, operator);
@@ -2645,10 +2730,18 @@ var useMarketsStore = () => {
2645
2730
  favoriteTabs,
2646
2731
  favorites,
2647
2732
  recent,
2733
+ newListing,
2648
2734
  tabSort,
2649
2735
  selectedFavoriteTab
2650
2736
  });
2651
- }, [favoriteTabs, favorites, recent, tabSort, selectedFavoriteTab]);
2737
+ }, [
2738
+ favoriteTabs,
2739
+ favorites,
2740
+ recent,
2741
+ newListing,
2742
+ tabSort,
2743
+ selectedFavoriteTab
2744
+ ]);
2652
2745
  useEffect(() => {
2653
2746
  const event = ({ id: srcId, key, data }) => {
2654
2747
  if (srcId === id) {
@@ -2662,6 +2755,8 @@ var useMarketsStore = () => {
2662
2755
  setFavorites(data);
2663
2756
  } else if (key === "recent") {
2664
2757
  setRecent(data);
2758
+ } else if (key === "newListing") {
2759
+ setNewListing(data);
2665
2760
  }
2666
2761
  };
2667
2762
  ee.on("markets:changed", event);
@@ -2673,6 +2768,7 @@ var useMarketsStore = () => {
2673
2768
  favoriteTabs,
2674
2769
  favorites,
2675
2770
  recent,
2771
+ newListing,
2676
2772
  tabSort,
2677
2773
  selectedFavoriteTab,
2678
2774
  updateFavorites: setFavorites,
@@ -2689,12 +2785,18 @@ var useMarkets = (type = 2 /* ALL */) => {
2689
2785
  const symbolsInfo = useSymbolsInfo();
2690
2786
  const [markets, setMarkets] = useState([]);
2691
2787
  const store = useMarketsStore();
2692
- const { favorites, recent } = store;
2788
+ const { favorites, recent, newListing } = store;
2693
2789
  useEffect(() => {
2694
2790
  const markets2 = addFieldToMarkets(futures, symbolsInfo);
2695
- const filterList = filterMarkets({ markets: markets2, favorites, recent, type });
2791
+ const filterList = filterMarkets({
2792
+ markets: markets2,
2793
+ favorites,
2794
+ recent,
2795
+ newListing,
2796
+ type
2797
+ });
2696
2798
  setMarkets(filterList);
2697
- }, [futures, symbolsInfo, favorites, recent, type]);
2799
+ }, [futures, symbolsInfo, favorites, recent, newListing, type]);
2698
2800
  return [markets, store];
2699
2801
  };
2700
2802
  var addFieldToMarkets = (futures, symbolsInfo) => {
@@ -2716,24 +2818,34 @@ var addFieldToMarkets = (futures, symbolsInfo) => {
2716
2818
  });
2717
2819
  };
2718
2820
  var filterMarkets = (params) => {
2719
- const { markets, favorites, recent, type } = params;
2821
+ const { markets, favorites, recent, newListing, type } = params;
2720
2822
  let curData = [];
2721
2823
  if (type === 2 /* ALL */) {
2722
2824
  curData = markets;
2825
+ } else if (type === 3 /* NEW_LISTING */) {
2826
+ curData = markets.filter((item) => isNewListing(item.created_time)).sort((a, b) => b.created_time - a.created_time);
2723
2827
  } else {
2724
- const storageData = type === 0 /* FAVORITES */ ? favorites : recent;
2828
+ const storageData = type === 0 /* FAVORITES */ ? favorites : type === 1 /* RECENT */ ? recent : newListing;
2725
2829
  const keys = storageData.map((item) => item.name);
2726
2830
  curData = markets?.filter((item) => keys.includes(item.symbol));
2727
2831
  }
2728
2832
  const favoriteKeys = favorites.map((item) => item.name);
2729
2833
  return curData?.map((item) => ({
2730
2834
  ...item,
2731
- isFavorite: type == 0 /* FAVORITES */ ? true : favoriteKeys.includes(item.symbol)
2835
+ isFavorite: type === 0 /* FAVORITES */ ? true : favoriteKeys.includes(item.symbol)
2732
2836
  }));
2733
2837
  };
2838
+ function isEmpty(value) {
2839
+ return value === void 0 || value === null;
2840
+ }
2841
+ var isNewListing = (createdTime) => {
2842
+ const thirtyDaysInMs = 30 * 24 * 60 * 60 * 1e3;
2843
+ const now = Date.now();
2844
+ return now - createdTime < thirtyDaysInMs;
2845
+ };
2734
2846
  function get8hFunding2(est_funding_rate, funding_period) {
2735
2847
  let funding8h = 0;
2736
- if (est_funding_rate === void 0 || est_funding_rate === null) {
2848
+ if (isEmpty(est_funding_rate)) {
2737
2849
  return null;
2738
2850
  }
2739
2851
  if (funding_period) {
@@ -2746,7 +2858,7 @@ function get24hChange2(params) {
2746
2858
  if (change !== void 0) {
2747
2859
  return change;
2748
2860
  }
2749
- if (close !== void 0 && open !== void 0) {
2861
+ if (!isEmpty(close) && !isEmpty(open)) {
2750
2862
  if (open === 0) {
2751
2863
  return 0;
2752
2864
  }
@@ -2934,6 +3046,41 @@ var useFundingRate = (symbol) => {
2934
3046
  countDown
2935
3047
  };
2936
3048
  };
3049
+
3050
+ // src/orderly/useFundingRateHistory.ts
3051
+ var calculatePositiveRate = (periodData, period) => {
3052
+ if (!periodData || !period)
3053
+ return 0;
3054
+ const daysMap = {
3055
+ "1d": 1,
3056
+ "3d": 3,
3057
+ "7d": 7,
3058
+ "14d": 14,
3059
+ "30d": 30,
3060
+ "90d": 90
3061
+ };
3062
+ const totalTimes = daysMap[period] * 3;
3063
+ return periodData.positive / totalTimes;
3064
+ };
3065
+ var useFundingRateHistory = () => {
3066
+ const {
3067
+ data: historyData,
3068
+ isLoading,
3069
+ ...rest
3070
+ } = useQuery("/v1/public/market_info/funding_history");
3071
+ return {
3072
+ data: historyData ?? [],
3073
+ isLoading,
3074
+ getPositiveRates: (data, period) => {
3075
+ if (!data?.length)
3076
+ return {};
3077
+ return data.reduce((acc, item) => {
3078
+ acc[item.symbol] = calculatePositiveRate(item.funding[period], period);
3079
+ return acc;
3080
+ }, {});
3081
+ }
3082
+ };
3083
+ };
2937
3084
  var findTPSLFromOrders = (orders, symbol) => {
2938
3085
  const order = findPositionTPSLFromOrders(orders, symbol);
2939
3086
  if (!order)
@@ -3118,10 +3265,10 @@ var useOrderStream = (params, options) => {
3118
3265
  side,
3119
3266
  size = 50,
3120
3267
  page,
3121
- dateRange,
3122
- includes: includes2 = ["ALL"],
3123
- excludes = []
3268
+ dateRange
3124
3269
  } = params;
3270
+ const [includes2, setIncludes] = useState(params.includes ?? ["ALL"]);
3271
+ const [excludes, setExcludes] = useState(params.excludes ?? []);
3125
3272
  const { data: markPrices } = useMarkPricesStream();
3126
3273
  const { registerKeyHandler, unregisterKeyHandler } = useDataCenterContext();
3127
3274
  const [
@@ -3474,7 +3621,7 @@ var useMaxQty = (symbol, side, reduceOnly = false) => {
3474
3621
  return 0;
3475
3622
  const getSymbolInfo = symbolInfo[symbol];
3476
3623
  const filterAlgoOrders = orders.filter(
3477
- (item) => item.algo_order_id === void 0
3624
+ (item) => item.algo_order_id === void 0 || item.algo_type === "BRACKET"
3478
3625
  );
3479
3626
  const buyOrdersQty = account.getQtyFromOrdersBySide(
3480
3627
  filterAlgoOrders,
@@ -3565,6 +3712,7 @@ var useMarginRatio = () => {
3565
3712
  }, [rows, notional]);
3566
3713
  return { marginRatio, currentLeverage, mmr };
3567
3714
  };
3715
+ var TestNetWhiteList = [421614, 901901901, 1516];
3568
3716
  function useChains(networkId, options = {}) {
3569
3717
  const { pick: pickField, ...swrOptions } = options;
3570
3718
  const {
@@ -3589,19 +3737,35 @@ function useChains(networkId, options = {}) {
3589
3737
  "https://api-evm.orderly.org/v1/public/token",
3590
3738
  { ...commonSwrOpts }
3591
3739
  );
3740
+ const { data: testTokenChainsRes } = useQuery(
3741
+ "https://testnet-api-evm.orderly.org/v1/public/token",
3742
+ { ...commonSwrOpts }
3743
+ );
3592
3744
  const brokerId = configStore.get("brokerId");
3593
3745
  const needFetchFromAPI = options.forceAPI || !customChains;
3594
3746
  const { data: chainInfos, error: chainInfoErr } = useQuery(
3595
3747
  needFetchFromAPI ? `https://api-evm.orderly.org/v1/public/chain_info${brokerId !== "orderly" ? `?broker_id=${brokerId}` : ""}` : null,
3596
3748
  { ...commonSwrOpts }
3597
3749
  );
3750
+ const { data: testChainInfos } = useQuery(
3751
+ needFetchFromAPI ? `https://testnet-api-evm.orderly.org/v1/public/chain_info${brokerId !== "orderly" ? `?broker_id=${brokerId}` : ""}` : null,
3752
+ { ...commonSwrOpts }
3753
+ );
3598
3754
  const chains = useMemo(() => {
3599
- const tokenChains = fillChainsInfo(tokenChainsRes, filterFun.current);
3600
- let testnetArr = needFetchFromAPI ? [...TestnetChains] : customChains?.testnet;
3755
+ const tokenChains = fillChainsInfo(
3756
+ tokenChainsRes,
3757
+ filterFun.current,
3758
+ chainInfos
3759
+ );
3760
+ const testTokenChains = fillChainsInfo(
3761
+ testTokenChainsRes,
3762
+ void 0,
3763
+ testChainInfos
3764
+ );
3765
+ let testnetArr = needFetchFromAPI ? filterAndUpdateChains(testTokenChains, testChainInfos, void 0, true) : customChains?.testnet;
3601
3766
  tokenChains?.forEach((item) => {
3602
3767
  const chainId = item.network_infos?.chain_id;
3603
3768
  chainsMap.current.set(chainId, item);
3604
- updateTestnetInfo(testnetArr, chainId, item);
3605
3769
  });
3606
3770
  testnetArr.forEach((chain) => {
3607
3771
  chainsMap.current.set(chain.network_infos?.chain_id, chain);
@@ -3616,10 +3780,12 @@ function useChains(networkId, options = {}) {
3616
3780
  mainnetArr.forEach((item) => {
3617
3781
  const chainId = item.network_infos?.chain_id;
3618
3782
  chainsMap.current.set(chainId, item);
3619
- updateTestnetInfo(testnetArr, chainId, item);
3620
3783
  });
3621
3784
  mainnetArr = filterByAllowedChains(mainnetArr, allowedChains?.mainnet);
3622
- testnetArr = filterByAllowedChains(testnetArr, allowedChains?.testnet);
3785
+ testnetArr = filterByAllowedChains(
3786
+ testnetArr,
3787
+ allowedChains?.testnet ?? TestNetWhiteList.map((id) => ({ id }))
3788
+ );
3623
3789
  if (!!pickField) {
3624
3790
  testnetArr = testnetArr.map((item) => item[pickField]);
3625
3791
  mainnetArr = mainnetArr.map((item) => item[pickField]);
@@ -3638,6 +3804,8 @@ function useChains(networkId, options = {}) {
3638
3804
  networkId,
3639
3805
  tokenChainsRes,
3640
3806
  chainInfos,
3807
+ testChainInfos,
3808
+ testTokenChainsRes,
3641
3809
  customChains,
3642
3810
  pickField,
3643
3811
  allowedChains
@@ -3683,15 +3851,17 @@ function _checkChainSupport(chainId, chains) {
3683
3851
  return chain.network_infos.chain_id === chainId;
3684
3852
  });
3685
3853
  }
3686
- function fillChainsInfo(chains, filter) {
3854
+ function fillChainsInfo(chains, filter, chainInfos) {
3687
3855
  let _chains = [];
3688
3856
  chains?.forEach((item) => {
3689
3857
  item.chain_details.forEach((chain) => {
3690
3858
  const chainId = Number(chain.chain_id);
3691
- const chainInfo = chainsInfoMap.get(chainId);
3859
+ const chainInfo = chainInfos?.find(
3860
+ (item2) => item2.chain_id == chainId
3861
+ );
3692
3862
  const _chain = {
3693
3863
  network_infos: {
3694
- name: chain.chain_name ?? chainInfo?.chainName ?? "--",
3864
+ name: chain.chain_name ?? chainInfo?.name ?? "--",
3695
3865
  chain_id: chainId,
3696
3866
  withdrawal_fee: chain.withdrawal_fee,
3697
3867
  cross_chain_withdrawal_fee: chain.cross_chain_withdrawal_fee,
@@ -3715,7 +3885,7 @@ function fillChainsInfo(chains, filter) {
3715
3885
  });
3716
3886
  return _chains;
3717
3887
  }
3718
- function filterAndUpdateChains(chains, chainInfos, filter) {
3888
+ function filterAndUpdateChains(chains, chainInfos, filter, isTestNet) {
3719
3889
  const filterChains = [];
3720
3890
  chains.forEach((chain) => {
3721
3891
  let _chain = { ...chain };
@@ -3731,9 +3901,9 @@ function filterAndUpdateChains(chains, chainInfos, filter) {
3731
3901
  public_rpc_url,
3732
3902
  currency_symbol,
3733
3903
  bridge_enable: true,
3734
- mainnet: true,
3735
- explorer_base_url,
3736
- est_txn_mins: null
3904
+ mainnet: !isTestNet,
3905
+ explorer_base_url
3906
+ // est_txn_mins: null,
3737
3907
  };
3738
3908
  }
3739
3909
  if (typeof filter === "function") {
@@ -3746,16 +3916,6 @@ function filterAndUpdateChains(chains, chainInfos, filter) {
3746
3916
  });
3747
3917
  return filterChains;
3748
3918
  }
3749
- function updateTestnetInfo(testnetArr, chainId, chain) {
3750
- if (isTestnet(chainId)) {
3751
- const index = testnetArr?.findIndex(
3752
- (item) => item.network_infos.chain_id === chainId
3753
- );
3754
- if (index > -1) {
3755
- testnetArr[index] = chain;
3756
- }
3757
- }
3758
- }
3759
3919
  function filterByAllowedChains(chains, allowedChains) {
3760
3920
  if (!allowedChains) {
3761
3921
  return chains;
@@ -3840,14 +4000,7 @@ var useWithdraw = (options) => {
3840
4000
  const { unsettledPnL, availableBalance, freeCollateral } = useCollateral();
3841
4001
  const networkId = useConfig("networkId");
3842
4002
  const [_, { findByChainId }] = useChains(void 0);
3843
- const withdraw = useCallback(
3844
- (inputs) => {
3845
- return account5.assetsManager.withdraw(inputs).then((res) => {
3846
- return res;
3847
- });
3848
- },
3849
- [state]
3850
- );
4003
+ const ee = useEventEmitter();
3851
4004
  useHoldingStream();
3852
4005
  const maxAmount = useMemo(() => {
3853
4006
  return freeCollateral;
@@ -3885,6 +4038,28 @@ var useWithdraw = (options) => {
3885
4038
  network: targetChain?.network_infos?.shortName
3886
4039
  };
3887
4040
  }, [targetChain]);
4041
+ const withdraw = useCallback(
4042
+ (inputs) => {
4043
+ return account5.assetsManager.withdraw(inputs).then((res) => {
4044
+ if (res.success) {
4045
+ ee.emit(EnumTrackerKeys.WITHDRAW_SUCCESS, {
4046
+ wallet: state?.connectWallet?.name,
4047
+ network: targetChain?.network_infos.name,
4048
+ quantity: inputs.amount
4049
+ });
4050
+ }
4051
+ return res;
4052
+ }).catch((err) => {
4053
+ ee.emit(EnumTrackerKeys.WITHDRAW_FAILED, {
4054
+ wallet: state?.connectWallet?.name,
4055
+ network: targetChain?.network_infos.name,
4056
+ msg: JSON.stringify(err)
4057
+ });
4058
+ throw err;
4059
+ });
4060
+ },
4061
+ [state, targetChain, state]
4062
+ );
3888
4063
  return {
3889
4064
  dst,
3890
4065
  withdraw,
@@ -3899,6 +4074,7 @@ var useDeposit = (options) => {
3899
4074
  const networkId = useConfig("networkId");
3900
4075
  const [balanceRevalidating, setBalanceRevalidating] = useState(false);
3901
4076
  const [allowanceRevalidating, setAllowanceRevalidating] = useState(false);
4077
+ const ee = useEventEmitter();
3902
4078
  const [_, { findByChainId }] = useChains(void 0);
3903
4079
  const [quantity, setQuantity] = useState("");
3904
4080
  const [depositFee, setDepositFee] = useState(0n);
@@ -4097,13 +4273,26 @@ var useDeposit = (options) => {
4097
4273
  throw new Error("Insufficient allowance");
4098
4274
  }
4099
4275
  return account5.assetsManager.deposit(quantity, depositFee).then((res) => {
4276
+ ee.emit(EnumTrackerKeys.DEPOSIT_SUCCESS, {
4277
+ wallet: state?.connectWallet?.name,
4278
+ network: targetChain?.network_infos.name,
4279
+ quantity
4280
+ });
4100
4281
  updateAllowanceWhenTxSuccess(res.hash);
4101
4282
  setBalance((value) => new Decimal(value).sub(quantity).toString());
4102
4283
  return res;
4284
+ }).catch((e) => {
4285
+ ee.emit(EnumTrackerKeys.DEPOSIT_FAILED, {
4286
+ wallet: state?.connectWallet?.name,
4287
+ network: targetChain?.network_infos?.name,
4288
+ msg: JSON.stringify(e)
4289
+ });
4290
+ throw e;
4103
4291
  });
4104
4292
  }, [account5, fetchBalance, quantity, depositFee, options?.address]);
4105
4293
  const loopGetBalance = async () => {
4106
4294
  getBalanceListener.current && clearTimeout(getBalanceListener.current);
4295
+ const time = account5.walletAdapter?.chainNamespace === ChainNamespace.solana ? 1e4 : 3e3;
4107
4296
  getBalanceListener.current = setTimeout(async () => {
4108
4297
  try {
4109
4298
  const balance2 = await fetchBalanceHandler(
@@ -4114,7 +4303,7 @@ var useDeposit = (options) => {
4114
4303
  loopGetBalance();
4115
4304
  } catch (err) {
4116
4305
  }
4117
- }, 3e3);
4306
+ }, time);
4118
4307
  };
4119
4308
  const getDepositFee = useCallback(
4120
4309
  async (quantity2) => {
@@ -4493,19 +4682,35 @@ function tpslCalculateHelper(key, inputs, options = {}) {
4493
4682
  // }),
4494
4683
  };
4495
4684
  }
4496
- function checkNotional(price, qty, minNotional) {
4497
- if (price !== void 0 && qty !== void 0 && minNotional !== void 0) {
4685
+ function checkNotional(props) {
4686
+ const { price, base_tick, qty, min_notional, base_dp, quote_dp, quote_tick } = props;
4687
+ if (price !== void 0 && qty !== void 0 && min_notional !== void 0) {
4498
4688
  try {
4499
4689
  const calcNotional = new Decimal(price).mul(new Decimal(qty)).toNumber();
4500
- const notional = Number.parseFloat(`${minNotional}`);
4501
- const str = calcNotional < notional ? `The order value should be greater or equal to ${minNotional} USDC` : void 0;
4502
- return str;
4690
+ const notional = Number.parseFloat(`${min_notional}`);
4691
+ if (calcNotional < notional) {
4692
+ let minQty = new Decimal(notional).div(price).toDecimalPlaces(base_dp, Decimal.ROUND_DOWN).add(base_tick ?? 0);
4693
+ if (base_tick && base_tick > 0) {
4694
+ minQty = new Decimal(
4695
+ getRoundedDownDivision(minQty.toNumber(), base_tick)
4696
+ );
4697
+ }
4698
+ const newMinNotional = minQty.mul(price).add(quote_tick ?? 0).toFixed(quote_dp);
4699
+ return `The order value should be greater or equal to ${newMinNotional} USDC`;
4700
+ }
4701
+ return void 0;
4503
4702
  } catch (e) {
4504
4703
  return void 0;
4505
4704
  }
4506
4705
  }
4507
4706
  return void 0;
4508
4707
  }
4708
+ function getRoundedDownDivision(value, tick) {
4709
+ const decimalValue = new Decimal(value);
4710
+ const decimalTick = new Decimal(tick);
4711
+ const quotient = decimalValue.dividedToIntegerBy(decimalTick);
4712
+ return quotient.mul(decimalTick).toNumber();
4713
+ }
4509
4714
 
4510
4715
  // src/services/orderCreator/baseCreator.ts
4511
4716
  var BaseOrderCreator = class {
@@ -4535,12 +4740,12 @@ var BaseOrderCreator = class {
4535
4740
  const errors = {};
4536
4741
  const { maxQty, symbol, markPrice } = configs;
4537
4742
  let { order_quantity, total, order_price, reduce_only, order_type } = values2;
4538
- const { min_notional } = symbol || {};
4743
+ const { min_notional, base_tick, quote_dp, quote_tick, base_dp } = symbol || {};
4539
4744
  if (!order_quantity) {
4540
4745
  if (total && order_price) {
4541
- const { quote_dp } = configs.symbol;
4746
+ const { quote_dp: quote_dp2 } = configs.symbol;
4542
4747
  const totalNumber = new Decimal(total);
4543
- const qty = totalNumber.dividedBy(order_price).toFixed(quote_dp);
4748
+ const qty = totalNumber.dividedBy(order_price).toFixed(quote_dp2);
4544
4749
  order_quantity = qty;
4545
4750
  }
4546
4751
  }
@@ -4550,26 +4755,34 @@ var BaseOrderCreator = class {
4550
4755
  message: "Quantity is required"
4551
4756
  };
4552
4757
  } else {
4553
- const { base_min, quote_dp, base_dp } = configs.symbol;
4758
+ const { base_min, quote_dp: quote_dp2, base_dp: base_dp2 } = configs.symbol;
4554
4759
  const qty = new Decimal(order_quantity);
4555
4760
  if (qty.lt(base_min)) {
4556
4761
  errors.order_quantity = {
4557
4762
  type: "min",
4558
4763
  message: `Quantity must be greater than ${new Decimal(base_min).todp(
4559
- base_dp
4764
+ base_dp2
4560
4765
  )}`
4561
4766
  };
4562
4767
  } else if (qty.gt(maxQty)) {
4563
4768
  errors.order_quantity = {
4564
4769
  type: "max",
4565
4770
  message: `Quantity must be less than ${new Decimal(maxQty).todp(
4566
- base_dp
4771
+ base_dp2
4567
4772
  )}`
4568
4773
  };
4569
4774
  }
4570
4775
  }
4571
4776
  const price = `${order_type}`.includes("MARKET") ? markPrice : order_price;
4572
- const notionalHintStr = checkNotional(price, order_quantity, min_notional);
4777
+ const notionalHintStr = checkNotional({
4778
+ base_tick,
4779
+ quote_tick,
4780
+ price,
4781
+ qty: order_quantity,
4782
+ min_notional,
4783
+ quote_dp,
4784
+ base_dp
4785
+ });
4573
4786
  if (notionalHintStr !== void 0 && !reduce_only) {
4574
4787
  errors.total = {
4575
4788
  type: "min",
@@ -5357,6 +5570,50 @@ var BracketMarketOrderCreator = class extends MarketOrderCreator {
5357
5570
  return { ...value, ...bracketData };
5358
5571
  }
5359
5572
  };
5573
+ var BBOOrderCreator = class extends BaseOrderCreator {
5574
+ create(values2) {
5575
+ const order = {
5576
+ ...this.baseOrder(values2),
5577
+ level: values2.level
5578
+ };
5579
+ return pick(
5580
+ [
5581
+ "symbol",
5582
+ "order_quantity",
5583
+ "visible_quantity",
5584
+ "reduce_only",
5585
+ "side",
5586
+ "order_type",
5587
+ "level"
5588
+ ],
5589
+ order
5590
+ );
5591
+ }
5592
+ async validate(values2, configs) {
5593
+ return this.baseValidate(values2, configs).then((errors) => {
5594
+ delete errors["total"];
5595
+ let { order_quantity, order_price, reduce_only, level } = values2;
5596
+ const { symbol } = configs;
5597
+ const { min_notional, base_tick, quote_dp, quote_tick, base_dp } = symbol || {};
5598
+ const notionalHintStr = checkNotional({
5599
+ base_tick,
5600
+ quote_tick,
5601
+ price: order_price,
5602
+ qty: order_quantity,
5603
+ min_notional,
5604
+ quote_dp,
5605
+ base_dp
5606
+ });
5607
+ if (notionalHintStr !== void 0 && !reduce_only) {
5608
+ errors.total = {
5609
+ type: "min",
5610
+ message: notionalHintStr
5611
+ };
5612
+ }
5613
+ return errors;
5614
+ });
5615
+ }
5616
+ };
5360
5617
 
5361
5618
  // src/services/orderCreator/factory.ts
5362
5619
  var OrderFactory = class {
@@ -5366,11 +5623,13 @@ var OrderFactory = class {
5366
5623
  return new BracketLimitOrderCreator();
5367
5624
  case `${AlgoOrderRootType.BRACKET}:${OrderType.MARKET}`:
5368
5625
  return new BracketMarketOrderCreator();
5369
- case OrderType.LIMIT: {
5626
+ case OrderType.LIMIT:
5370
5627
  return new LimitOrderCreator();
5371
- }
5372
5628
  case OrderType.MARKET:
5373
5629
  return new MarketOrderCreator();
5630
+ case OrderType.ASK:
5631
+ case OrderType.BID:
5632
+ return new BBOOrderCreator();
5374
5633
  case OrderType.IOC:
5375
5634
  return new IOCOrderCreator();
5376
5635
  case OrderType.FOK:
@@ -5842,7 +6101,7 @@ function useMaintenanceStatus() {
5842
6101
  const [startTime, setStartTime] = useState();
5843
6102
  const [endTime, setEndTime] = useState();
5844
6103
  const [brokerName, setBrokerName] = useState("Orderly network");
5845
- const { data: systemInfo, mutate: mutate3 } = useQuery(`/v1/public/system_info`, {
6104
+ const { data: systemInfo, mutate: mutate3 } = useQuery(`/v1/public/system_info?source=maintenance`, {
5846
6105
  revalidateOnFocus: false,
5847
6106
  errorRetryCount: 2,
5848
6107
  errorRetryInterval: 200
@@ -5850,18 +6109,18 @@ function useMaintenanceStatus() {
5850
6109
  const ws = useWS();
5851
6110
  const config = useConfig();
5852
6111
  useEffect(() => {
5853
- if (!systemInfo || !systemInfo.data) {
6112
+ if (!systemInfo) {
5854
6113
  return;
5855
6114
  }
5856
6115
  const brokerName2 = config.get("brokerName");
5857
6116
  if (brokerName2) {
5858
6117
  setBrokerName(brokerName2);
5859
6118
  }
5860
- if (systemInfo.data.scheduled_maintenance) {
5861
- setStartTime(systemInfo.data.scheduled_maintenance.start_time);
5862
- setEndTime(systemInfo.data.scheduled_maintenance.end_time);
6119
+ if (systemInfo.scheduled_maintenance) {
6120
+ setStartTime(systemInfo.scheduled_maintenance.start_time);
6121
+ setEndTime(systemInfo.scheduled_maintenance.end_time);
5863
6122
  }
5864
- if (systemInfo.data.status === 2) {
6123
+ if (systemInfo.status === 2) {
5865
6124
  setStatus(2);
5866
6125
  }
5867
6126
  }, [systemInfo, config]);
@@ -5890,7 +6149,9 @@ var usePrivateDataObserver = (options) => {
5890
6149
  const ws = useWS();
5891
6150
  const ee = useEventEmitter();
5892
6151
  const { state, account: account5 } = useAccount();
5893
- const { setAccountInfo, restoreHolding, updateHolding, cleanAll } = useAppStore((state2) => state2.actions);
6152
+ const { setAccountInfo, restoreHolding, cleanAll } = useAppStore(
6153
+ (state2) => state2.actions
6154
+ );
5894
6155
  const statusActions = useApiStatusActions();
5895
6156
  const calculatorService = useCalculatorService();
5896
6157
  const positionsActions = usePositionActions();
@@ -5949,7 +6210,7 @@ var usePrivateDataObserver = (options) => {
5949
6210
  onMessage: (data) => {
5950
6211
  const holding2 = data?.balances ?? {};
5951
6212
  if (holding2) {
5952
- updateHolding(holding2);
6213
+ calculatorService.calc("portfolio" /* PORTFOLIO */, { holding: holding2 });
5953
6214
  }
5954
6215
  }
5955
6216
  }
@@ -6283,8 +6544,8 @@ var ProxyConfigStore = class {
6283
6544
  }
6284
6545
  };
6285
6546
  var ExtendedConfigStore = class extends DefaultConfigStore {
6286
- constructor(init) {
6287
- super(init);
6547
+ constructor(init2) {
6548
+ super(init2);
6288
6549
  }
6289
6550
  get(key) {
6290
6551
  if (key === MarketsStorageKey) {
@@ -6332,20 +6593,20 @@ var OrderlyConfigProvider = (props) => {
6332
6593
  "If you have provided a custom `configStore` and the `brokerId` is set in the `configStore`, please remove the `brokerId` prop."
6333
6594
  );
6334
6595
  }
6335
- const innerConfigStore = useConstant5(() => {
6596
+ const innerConfigStore = useMemo(() => {
6336
6597
  return new ProxyConfigStore(
6337
6598
  configStore || new ExtendedConfigStore({ brokerId, brokerName, networkId })
6338
6599
  );
6339
- });
6340
- const innerKeyStore = useConstant5(() => {
6600
+ }, [configStore, brokerId, brokerName, networkId]);
6601
+ const innerKeyStore = useMemo(() => {
6341
6602
  return keyStore || new LocalStorageStore(networkId);
6342
- });
6343
- const innerWalletAdapters = useConstant5(() => {
6603
+ }, [networkId, keyStore]);
6604
+ const innerWalletAdapters = useMemo(() => {
6344
6605
  return walletAdapters || [
6345
6606
  new DefaultEVMWalletAdapter(new EthersProvider()),
6346
6607
  new DefaultSolanaWalletAdapter()
6347
6608
  ];
6348
- });
6609
+ }, [walletAdapters]);
6349
6610
  useLayoutEffect(() => {
6350
6611
  let account6 = SimpleDI.get(Account.instanceName);
6351
6612
  if (!account6) {
@@ -6388,6 +6649,91 @@ var OrderlyConfigProvider = (props) => {
6388
6649
  }
6389
6650
  );
6390
6651
  };
6652
+ var apiKeyMap = {
6653
+ dev: "4d6b7db0fdd6e9de2b6a270414fd51e0",
6654
+ qa: "96476b00bc2701360f9b480629ae5263",
6655
+ staging: "dffc00e003479b86d410c448e00f2304",
6656
+ prod: "3ab9ae56ed16cc57bc2ac97ffc1098c2"
6657
+ };
6658
+ var TrackerContext = createContext({});
6659
+ var OrderlyTrackerProvider = ({ children }) => {
6660
+ const listenKeys = Object.keys(TrackerListenerKeyMap);
6661
+ const ee = useEventEmitter();
6662
+ const env = useGetEnv();
6663
+ const walletConnectRef = useRef(false);
6664
+ const { account: account5, state } = useAccount();
6665
+ const networkId = useConfig("networkId");
6666
+ const brokerId = useConfig("brokerId");
6667
+ const getChainInfo = useNetworkInfo(networkId);
6668
+ const handleEvent = useCallback(
6669
+ (key, params) => {
6670
+ account5?.accountId && amplitude.setUserId(account5?.accountId);
6671
+ if (key === EnumTrackerKeys.WALLET_CONNECT) {
6672
+ if (walletConnectRef.current)
6673
+ return;
6674
+ const info = getChainInfo(
6675
+ params?.connectWallet?.chainId
6676
+ ).info;
6677
+ const { address = "", connectWallet } = params;
6678
+ const identify2 = {
6679
+ address,
6680
+ broker_id: brokerId,
6681
+ sdk_version: window?.__ORDERLY_VERSION__?.["@orderly.network/net"] ?? ""
6682
+ };
6683
+ const identifyEvent = new amplitude.Identify();
6684
+ Object.keys(identify2).map((subKey) => {
6685
+ identifyEvent.set(subKey, identify2[subKey]);
6686
+ });
6687
+ amplitude.identify(identifyEvent);
6688
+ const eventProperties = {
6689
+ wallet: connectWallet?.name,
6690
+ network: info?.network_infos?.name
6691
+ };
6692
+ amplitude.track(TrackerListenerKeyMap[key], eventProperties);
6693
+ walletConnectRef.current = true;
6694
+ return;
6695
+ }
6696
+ if (key === EnumTrackerKeys.SIGNIN_SUCCESS) {
6697
+ const info = getChainInfo(
6698
+ params?.connectWallet?.chainId
6699
+ ).info;
6700
+ amplitude.track(TrackerListenerKeyMap[key], {
6701
+ wallet: params?.connectWallet?.name,
6702
+ network: info?.network_infos?.name
6703
+ });
6704
+ return;
6705
+ }
6706
+ amplitude.track(TrackerListenerKeyMap[key], params);
6707
+ },
6708
+ [account5?.accountId, brokerId, state?.connectWallet?.name]
6709
+ );
6710
+ useEffect(() => {
6711
+ amplitude.init(apiKeyMap[env], { serverZone: "EU" });
6712
+ listenKeys.forEach((key) => {
6713
+ ee.on(key, (params = {}) => {
6714
+ setTimeout(() => {
6715
+ handleEvent(key, params);
6716
+ }, 2e3);
6717
+ });
6718
+ });
6719
+ return () => {
6720
+ listenKeys.forEach((key) => {
6721
+ ee.off(key);
6722
+ });
6723
+ };
6724
+ }, [env]);
6725
+ return /* @__PURE__ */ jsx(
6726
+ TrackerContext.Provider,
6727
+ {
6728
+ value: {
6729
+ track: (key, params) => {
6730
+ amplitude.track(key, params);
6731
+ }
6732
+ },
6733
+ children
6734
+ }
6735
+ );
6736
+ };
6391
6737
  var WalletConnectorContext = createContext({});
6392
6738
  var useWalletConnector = () => {
6393
6739
  return useContext(WalletConnectorContext);
@@ -7354,7 +7700,7 @@ var DataPaint = class extends BasePaint {
7354
7700
  );
7355
7701
  }
7356
7702
  if (typeof options.data?.position.pnl !== "undefined") {
7357
- const prefix = options.data?.position.pnl > 0 ? "+" : "";
7703
+ const prefix = options.data?.position.pnl >= 0 ? "+" : "";
7358
7704
  let text = `${prefix}${commify(options.data?.position.pnl)} ${options.data?.position.currency}`;
7359
7705
  let fontWeight = 600;
7360
7706
  if (prevElementBoundingBox.width) {
@@ -13071,13 +13417,13 @@ var OmnichainLedgerV1ABI_default = [
13071
13417
  type: "function"
13072
13418
  }
13073
13419
  ];
13074
- var ENVType = /* @__PURE__ */ ((ENVType2) => {
13075
- ENVType2["prod"] = "prod";
13076
- ENVType2["staging"] = "staging";
13077
- ENVType2["qa"] = "qa";
13078
- ENVType2["dev"] = "dev";
13079
- return ENVType2;
13080
- })(ENVType || {});
13420
+ var ENVType2 = /* @__PURE__ */ ((ENVType3) => {
13421
+ ENVType3["prod"] = "prod";
13422
+ ENVType3["staging"] = "staging";
13423
+ ENVType3["qa"] = "qa";
13424
+ ENVType3["dev"] = "dev";
13425
+ return ENVType3;
13426
+ })(ENVType2 || {});
13081
13427
  var useGetEnv = () => {
13082
13428
  const { configStore } = useContext(OrderlyContext);
13083
13429
  const baseUrl = configStore.get("apiBaseUrl") || "https://api-evm.orderly.org";
@@ -13298,6 +13644,8 @@ var getOrderCreator = (order) => {
13298
13644
  let type;
13299
13645
  if (isBracketOrder(order)) {
13300
13646
  type = `${AlgoOrderRootType.BRACKET}:${order.order_type}`;
13647
+ } else if (order.order_type === OrderType.LIMIT) {
13648
+ type = order.order_type_ext || order.order_type;
13301
13649
  } else {
13302
13650
  type = order.order_type;
13303
13651
  }
@@ -13703,8 +14051,10 @@ var useOrderEntry2 = (symbol, options = {}) => {
13703
14051
  validated: false,
13704
14052
  errors: null
13705
14053
  });
13706
- const askAndBid = useRef([]);
14054
+ const askAndBid = useRef([[]]);
13707
14055
  const lastChangedField = useRef();
14056
+ const lastOrderTypeExt = useRef();
14057
+ const lastLevel = useRef();
13708
14058
  const actions = useMarkPriceActions();
13709
14059
  const symbolConfig = useSymbolsInfo();
13710
14060
  const accountInfo = useAccountInfo();
@@ -13732,8 +14082,35 @@ var useOrderEntry2 = (symbol, options = {}) => {
13732
14082
  formattedOrder.side,
13733
14083
  formattedOrder.reduce_only
13734
14084
  );
14085
+ const updateOrderPrice = () => {
14086
+ const order_type_ext = formattedOrder.order_type_ext ?? lastOrderTypeExt.current;
14087
+ const level = formattedOrder.level ?? lastLevel.current;
14088
+ if (![OrderType.ASK, OrderType.BID].includes(order_type_ext) || level === void 0) {
14089
+ return;
14090
+ }
14091
+ lastOrderTypeExt.current = order_type_ext;
14092
+ lastLevel.current = level;
14093
+ const index = order_type_ext === OrderType.ASK ? 0 : 1;
14094
+ const price = askAndBid.current?.[level]?.[index];
14095
+ if (price && !isNaN(price)) {
14096
+ setValue("order_price", price, {
14097
+ shouldUpdateLastChangedField: false
14098
+ });
14099
+ }
14100
+ };
14101
+ const updateOrderPriceByOrderBook = () => {
14102
+ const { order_type, order_type_ext, order_quantity } = formattedOrder;
14103
+ const isBBO = order_type === OrderType.LIMIT && [OrderType.ASK, OrderType.BID].includes(order_type_ext);
14104
+ if (lastChangedField.current !== "total" && isBBO) {
14105
+ updateOrderPrice();
14106
+ }
14107
+ };
14108
+ useEffect(() => {
14109
+ updateOrderPrice();
14110
+ }, [formattedOrder.order_type_ext, formattedOrder.level]);
13735
14111
  const onOrderBookUpdate = useDebouncedCallback((data) => {
13736
14112
  askAndBid.current = data;
14113
+ updateOrderPriceByOrderBook();
13737
14114
  }, 200);
13738
14115
  useEffect(() => {
13739
14116
  ee.on("orderbook:update", onOrderBookUpdate);
@@ -13847,7 +14224,7 @@ var useOrderEntry2 = (symbol, options = {}) => {
13847
14224
  const markPrice2 = actions.getMarkPriceBySymbol(symbol);
13848
14225
  if (!markPrice2 || !accountInfo)
13849
14226
  return null;
13850
- return calcEstLiqPrice(formattedOrder, askAndBid.current, {
14227
+ return calcEstLiqPrice(formattedOrder, askAndBid.current[0], {
13851
14228
  baseIMR: symbolInfo?.base_imr,
13852
14229
  baseMMR: symbolInfo?.base_mmr,
13853
14230
  markPrice: markPrice2,
@@ -13859,7 +14236,7 @@ var useOrderEntry2 = (symbol, options = {}) => {
13859
14236
  });
13860
14237
  }, [formattedOrder, accountInfo, positions2, totalCollateral, symbol]);
13861
14238
  const estLeverage = useMemo(() => {
13862
- return calcEstLeverage(formattedOrder, askAndBid.current, {
14239
+ return calcEstLeverage(formattedOrder, askAndBid.current[0], {
13863
14240
  totalCollateral,
13864
14241
  positions: positions2,
13865
14242
  symbol
@@ -13902,6 +14279,14 @@ var useOrderEntry2 = (symbol, options = {}) => {
13902
14279
  }
13903
14280
  const order = generateOrder(creator, prepareData());
13904
14281
  const result = await doCreateOrder(order);
14282
+ if (result.success) {
14283
+ ee.emit(EnumTrackerKeys.PLACEORDER_SUCCESS, {
14284
+ side: order.side,
14285
+ order_type: order.order_type,
14286
+ tp_sl: hasTPSL(formattedOrder),
14287
+ reduce_only: !!order.reduce_only
14288
+ });
14289
+ }
13905
14290
  if (result.success && resetOnSuccess) {
13906
14291
  reset();
13907
14292
  resetMetaState();
@@ -14083,6 +14468,6 @@ var useOrderEntity = (order, options) => {
14083
14468
  };
14084
14469
  };
14085
14470
 
14086
- export { AssetHistoryStatusEnum, DefaultLayoutConfig, DistributionId, ENVType, ExtendedConfigStore, MarketsStorageKey, MarketsType, OrderlyConfigProvider, OrderlyContext, OrderlyProvider, StatusContext, StatusProvider, TWType, WalletConnectorContext, WsNetworkStatus, checkNotional, cleanStringStyle, parseJSON, useAccount, useAccountInfo2 as useAccountInfo, useAccountInstance, useAccountRewardsHistory, useAllBrokers, useApiKeyManager, useAssetsHistory, useBoolean, useChain, useChains, useCheckReferralCode, useCollateral, useCommission, useConfig, useCurEpochEstimate, useDaily, useDeposit, useDistribution, useDistributionHistory, useEpochInfo, useEventEmitter, useFundingFeeHistory, useFundingRate, useFundingRates, useGetClaimed, useGetEnv, useGetReferralCode, useHoldingStream, useIndexPrice, useKeyStore, useLazyQuery, useLeverage, useLocalStorage, useMaintenanceStatus, useMarginRatio, useMarkPrice, useMarkPriceBySymbol, useMarkPricesStream, useMarket, useMarketTradeStream, useMarkets, useMarketsStore, useMarketsStream, useMaxQty, useMediaQuery, useMutation, useOrderEntity, useOrderEntry2 as useOrderEntry, useOrderEntry as useOrderEntry_deprecated, useOrderStore2 as useOrderStore, useOrderStream, useOrderbookStream, usePositionActions, usePositionStream, usePoster, usePreLoadData, usePrivateDataObserver, usePrivateInfiniteQuery, usePrivateQuery, useQuery, useRefereeHistory, useRefereeInfo, useRefereeRebateSummary, useReferralInfo, useReferralRebateSummary, useSessionStorage, useSettleSubscription, useSimpleDI, useStatisticsDaily, useSymbolLeverage, useSymbolPriceRange, useSymbolsInfo, useTPSLOrder, useTickerStream, useWS, useWalletConnector, useWalletRewardsHistory, useWalletSubscription, useWithdraw, useWsStatus, utils_exports as utils, version_default as version };
14471
+ export { AssetHistoryStatusEnum, DefaultLayoutConfig, DistributionId, ENVType2 as ENVType, ExtendedConfigStore, MarketsStorageKey, MarketsType, OrderlyConfigProvider, OrderlyContext, OrderlyProvider, OrderlyTrackerProvider, StatusContext, StatusProvider, TWType, WalletConnectorContext, WsNetworkStatus, checkNotional, cleanStringStyle, parseJSON, useAccount, useAccountInfo2 as useAccountInfo, useAccountInstance, useAccountRewardsHistory, useAllBrokers, useApiKeyManager, useAssetsHistory, useBoolean, useChain, useChains, useCheckReferralCode, useCollateral, useCommission, useConfig, useCurEpochEstimate, useDaily, useDeposit, useDistribution, useDistributionHistory, useEpochInfo, useEventEmitter, useFundingFeeHistory, useFundingRate, useFundingRateHistory, useFundingRates, useGetClaimed, useGetEnv, useGetReferralCode, useHoldingStream, useIndexPrice, useKeyStore, useLazyQuery, useLeverage, useLocalStorage, useMaintenanceStatus, useMarginRatio, useMarkPrice, useMarkPriceBySymbol, useMarkPricesStream, useMarket, useMarketTradeStream, useMarkets, useMarketsStore, useMarketsStream, useMaxQty, useMediaQuery, useMutation, useNetworkInfo, useOrderEntity, useOrderEntry2 as useOrderEntry, useOrderEntry as useOrderEntry_deprecated, useOrderStore2 as useOrderStore, useOrderStream, useOrderbookStream, usePositionActions, usePositionStream, usePoster, usePreLoadData, usePrivateDataObserver, usePrivateInfiniteQuery, usePrivateQuery, useQuery, useRefereeHistory, useRefereeInfo, useRefereeRebateSummary, useReferralInfo, useReferralRebateSummary, useSessionStorage, useSettleSubscription, useSimpleDI, useStatisticsDaily, useSymbolLeverage, useSymbolPriceRange, useSymbolsInfo, useTPSLOrder, useTickerStream, useWS, useWalletConnector, useWalletRewardsHistory, useWalletSubscription, useWithdraw, useWsStatus, utils_exports as utils, version_default as version };
14087
14472
  //# sourceMappingURL=out.js.map
14088
14473
  //# sourceMappingURL=index.mjs.map