@orderly.network/hooks 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,20 +1,22 @@
1
- import useSWR, { mutate } from 'swr';
2
- export { unstable_serialize, default as useSWR, useSWRConfig } from 'swr';
3
1
  import { get, WS, mutate as mutate$1 } from '@orderly.network/net';
2
+ import useSWR__default, { mutate } from 'swr';
3
+ import * as useSWR from 'swr';
4
+ export { useSWR as swr };
5
+ export { unstable_serialize, default as useSWR, useSWRConfig } from 'swr';
6
+ import { TesntTokenFallback, ArbitrumSepoliaTokenInfo, SolanaDevnetTokenInfo, OrderType, OrderSide, SDKError, TrackerEventName, AccountStatusEnum, AlgoOrderRootType, OrderStatus, ArbitrumSepoliaChainInfo, SolanaDevnetChainInfo, ARBITRUM_TESTNET_CHAINID, SOLANA_TESTNET_CHAINID, MONAD_TESTNET_CHAINID, ABSTRACT_TESTNET_CHAINID, BSC_TESTNET_CHAINID, nativeTokenAddress, ChainKey, chainsInfoMap, ARBITRUM_MAINNET_CHAINID, isNativeTokenChecker, ChainNamespace, MaxUint256, DEPOSIT_FEE_RATE, LedgerWalletKey, SolanaChains, AlgoOrderType, TriggerPriceType } from '@orderly.network/types';
4
7
  import React, { createContext, useContext, useCallback, useState, useEffect, useMemo, useRef, useId, useLayoutEffect } from 'react';
5
- import { TesntTokenFallback, ArbitrumSepoliaTokenInfo, SolanaDevnetTokenInfo, OrderType, OrderSide, SDKError, TrackerEventName, AccountStatusEnum, AlgoOrderRootType, OrderStatus, ArbitrumSepoliaChainInfo, SolanaDevnetChainInfo, ARBITRUM_TESTNET_CHAINID, SOLANA_TESTNET_CHAINID, MONAD_TESTNET_CHAINID, ABSTRACT_TESTNET_CHAINID, nativeTokenAddress, ChainKey, chainsInfoMap, ARBITRUM_MAINNET_CHAINID, isNativeTokenChecker, ChainNamespace, MaxUint256, DEPOSIT_FEE_RATE, LedgerWalletKey, SolanaChains, AlgoOrderType, TriggerPriceType } from '@orderly.network/types';
6
8
  import useSWRMutation from 'swr/mutation';
7
9
  import useConstant from 'use-constant';
8
10
  export { default as useConstant } from 'use-constant';
9
11
  import { SimpleDI, Account, EventEmitter, EVENT_NAMES, DefaultConfigStore, LocalStorageStore } from '@orderly.network/core';
10
- import { zero, windowGuard, getGlobalObject, getTimestamp, Decimal, timeConvertString, isTestnet, getPrecisionByNumber, camelCaseToUnderscoreCase, removeTrailingZeros, commify, todpIfNeed } from '@orderly.network/utils';
12
+ import { zero, windowGuard, getTimestamp, getGlobalObject, Decimal, timeConvertString, isTestnet, getPrecisionByNumber, camelCaseToUnderscoreCase, removeTrailingZeros, commify, todpIfNeed } from '@orderly.network/utils';
11
13
  import { debounce } from 'lodash';
12
14
  import useSWRInfinite, { unstable_serialize } from 'swr/infinite';
13
15
  import * as amplitude from '@amplitude/analytics-browser';
14
16
  import { jsx } from 'react/jsx-runtime';
15
- import { pathOr, omit, prop, pick, compose, head, mergeDeepRight, min, max, isNil, propOr, path, lensIndex, over } from 'ramda';
16
17
  import { create } from 'zustand';
17
18
  import { immer } from 'zustand/middleware/immer';
19
+ import { pathOr, omit, prop, pick, compose, head, mergeDeepRight, min, max, isNil, propOr, path, lensIndex, over } from 'ramda';
18
20
  import { order, account, positions } from '@orderly.network/perp';
19
21
  import useSWRSubscription from 'swr/subscription';
20
22
  import { useDebouncedCallback, useThrottledCallback } from 'use-debounce';
@@ -34,9 +36,9 @@ var __export = (target, all) => {
34
36
  // src/version.ts
35
37
  if (typeof window !== "undefined") {
36
38
  window.__ORDERLY_VERSION__ = window.__ORDERLY_VERSION__ || {};
37
- window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "2.2.0";
39
+ window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "2.3.0";
38
40
  }
39
- var version_default = "2.2.0";
41
+ var version_default = "2.3.0";
40
42
  var fetcher = (url, init2 = {}, queryOptions) => get(url, init2, queryOptions?.formatter);
41
43
  var OrderlyContext = createContext({
42
44
  // configStore: new MemoryConfigStore(),
@@ -57,13 +59,15 @@ function useConfig(key, defaultValue) {
57
59
  }
58
60
  return configStore;
59
61
  }
62
+
63
+ // src/useQuery.ts
60
64
  var useQuery = (query, options) => {
61
65
  const apiBaseUrl = useConfig("apiBaseUrl");
62
66
  const { formatter, ...swrOptions } = options || {};
63
67
  if (typeof apiBaseUrl === "undefined") {
64
68
  throw new SDKError("please add OrderlyConfigProvider to your app");
65
69
  }
66
- return useSWR(
70
+ return useSWR__default(
67
71
  query,
68
72
  (url, init2) => fetcher(url.startsWith("http") ? url : `${apiBaseUrl}${url}`, init2, {
69
73
  formatter
@@ -82,14 +86,10 @@ var useLazyQuery = (query, options) => {
82
86
  (url, options2) => {
83
87
  url = url.startsWith("http") ? url : `${apiBaseUrl}${url}`;
84
88
  if (options2?.arg) {
85
- const queryString = Object.entries(options2.arg).map(
86
- ([key, value]) => `${key}=${encodeURIComponent(value)}`
87
- ).join("&");
89
+ const queryString = Object.entries(options2.arg).map(([key, value]) => `${key}=${encodeURIComponent(value)}`).join("&");
88
90
  url = `${url}?${queryString}`;
89
91
  }
90
- return fetcher(url, init2, {
91
- formatter
92
- });
92
+ return fetcher(url, init2, { formatter });
93
93
  },
94
94
  swrOptions
95
95
  );
@@ -105,20 +105,20 @@ var useAccountInstance = () => {
105
105
  "keyStore is not defined, please use OrderlyProvider and provide keyStore"
106
106
  );
107
107
  }
108
- const account5 = useConstant(() => {
109
- let account6 = SimpleDI.get("account");
110
- if (!account6) {
111
- account6 = new Account(
108
+ const account7 = useConstant(() => {
109
+ let account8 = SimpleDI.get("account");
110
+ if (!account8) {
111
+ account8 = new Account(
112
112
  configStore,
113
113
  keyStore,
114
114
  // getWalletAdapter,
115
115
  walletAdapters
116
116
  );
117
- SimpleDI.registerByName("account", account6);
117
+ SimpleDI.registerByName("account", account8);
118
118
  }
119
- return account6;
119
+ return account8;
120
120
  });
121
- return account5;
121
+ return account7;
122
122
  };
123
123
  var fetcher2 = (url, options) => {
124
124
  const init2 = {
@@ -142,7 +142,7 @@ var useMutation = (url, method = "POST", options) => {
142
142
  if (!url.startsWith("http")) {
143
143
  fullUrl = `${apiBaseUrl}${url}`;
144
144
  }
145
- const account5 = useAccountInstance();
145
+ const account7 = useAccountInstance();
146
146
  const { trigger, data, error, reset, isMutating } = useSWRMutation(
147
147
  fullUrl,
148
148
  // method === "POST" ? fetcher : deleteFetcher,
@@ -160,7 +160,7 @@ var useMutation = (url, method = "POST", options) => {
160
160
  url: newUrl,
161
161
  data: data2
162
162
  };
163
- const signer = account5.signer;
163
+ const signer = account7.signer;
164
164
  const signature = await signer.sign(payload, getTimestamp());
165
165
  return trigger(
166
166
  {
@@ -169,7 +169,7 @@ var useMutation = (url, method = "POST", options) => {
169
169
  method,
170
170
  signature: {
171
171
  ...signature,
172
- "orderly-account-id": account5.accountId
172
+ "orderly-account-id": account7.accountId
173
173
  }
174
174
  },
175
175
  options2
@@ -187,22 +187,22 @@ var useMutation = (url, method = "POST", options) => {
187
187
  };
188
188
  var signatureMiddleware = (useSWRNext) => {
189
189
  const apiBaseUrl = useConfig("apiBaseUrl");
190
- return (key, fetcher3, config) => {
190
+ return (key, fetcher4, config) => {
191
191
  try {
192
192
  const extendedFetcher = async (args) => {
193
- let url = Array.isArray(args) ? args[0] : args;
194
- let account5 = SimpleDI.get("account");
195
- let fullUrl = `${apiBaseUrl}${url}`;
196
- const signer = account5.signer;
193
+ const url = Array.isArray(args) ? args[0] : args;
194
+ const account7 = SimpleDI.get("account");
195
+ const fullUrl = `${apiBaseUrl}${url}`;
196
+ const signer = account7.signer;
197
197
  const payload = {
198
198
  method: "GET",
199
199
  url
200
200
  };
201
201
  const signature = await signer.sign(payload, getTimestamp());
202
- return fetcher3(fullUrl, {
202
+ return fetcher4(fullUrl, {
203
203
  headers: {
204
204
  ...signature,
205
- "orderly-account-id": account5.accountId
205
+ "orderly-account-id": account7.accountId
206
206
  }
207
207
  });
208
208
  };
@@ -269,16 +269,47 @@ var useTrack = () => {
269
269
  setIdentify
270
270
  };
271
271
  };
272
+ var WS_NAME = "nativeWebsocketClient";
273
+ var useWS = () => {
274
+ const { configStore } = useContext(OrderlyContext);
275
+ const ws = useConstant(() => {
276
+ let websocketClient = SimpleDI.get(WS_NAME);
277
+ const account7 = SimpleDI.get(Account.instanceName);
278
+ if (!websocketClient) {
279
+ websocketClient = new WS({
280
+ networkId: configStore.get("networkId"),
281
+ publicUrl: configStore.get("publicWsUrl"),
282
+ privateUrl: configStore.get("privateWsUrl"),
283
+ onSigntureRequest: async (accountId) => {
284
+ const signer = account7.signer;
285
+ const timestamp = getTimestamp();
286
+ const result = await signer.signText(timestamp.toString());
287
+ return { ...result, timestamp };
288
+ }
289
+ });
290
+ if ((account7.stateValue.status === AccountStatusEnum.EnableTrading || account7.stateValue.status === AccountStatusEnum.EnableTradingWithoutConnected) && account7.accountId) {
291
+ websocketClient.openPrivate(account7.accountId);
292
+ }
293
+ account7.on("change:status", (nextState) => {
294
+ if ((nextState.status === AccountStatusEnum.EnableTrading || nextState.status === AccountStatusEnum.EnableTradingWithoutConnected) && account7.accountId) {
295
+ websocketClient.openPrivate(account7.accountId);
296
+ } else {
297
+ websocketClient.closePrivate(1e3, "switch account");
298
+ }
299
+ });
300
+ if (typeof window !== "undefined") {
301
+ getGlobalObject()["__Orderly_WS"] = websocketClient;
302
+ }
303
+ SimpleDI.registerByName(WS_NAME, websocketClient);
304
+ }
305
+ return websocketClient;
306
+ });
307
+ return ws;
308
+ };
272
309
 
273
310
  // src/useAccount.ts
274
311
  var useAccount = () => {
275
- const {
276
- configStore,
277
- keyStore
278
- // onWalletConnect,
279
- // onWalletDisconnect,
280
- // onSetChain,
281
- } = useContext(OrderlyContext);
312
+ const { configStore, keyStore } = useContext(OrderlyContext);
282
313
  if (!configStore)
283
314
  throw new SDKError(
284
315
  "configStore is not defined, please use OrderlyProvider"
@@ -288,49 +319,83 @@ var useAccount = () => {
288
319
  "keyStore is not defined, please use OrderlyProvider and provide keyStore"
289
320
  );
290
321
  }
291
- const account5 = useAccountInstance();
292
- const [state, setState] = useState(account5.stateValue);
322
+ const account7 = useAccountInstance();
323
+ const [state, setState] = useState(account7.stateValue);
293
324
  const { track: track2 } = useTrack();
294
325
  const statusChangeHandler = (nextState) => {
295
326
  setState(() => nextState);
296
327
  };
297
328
  useEffect(() => {
298
- account5.on("change:status", statusChangeHandler);
329
+ account7.on("change:status", statusChangeHandler);
299
330
  return () => {
300
- account5.off("change:status", statusChangeHandler);
331
+ account7.off("change:status", statusChangeHandler);
301
332
  };
302
- }, []);
333
+ }, [account7]);
303
334
  const createOrderlyKey = useCallback(
304
335
  async (remember) => {
305
336
  track2(TrackerEventName.signinSuccess, {
306
- network: account5.chainId,
337
+ network: account7.chainId,
307
338
  wallet: state.connectWallet?.name
308
339
  });
309
- return account5.createOrderlyKey(remember ? 365 : 30);
340
+ return account7.createOrderlyKey(remember ? 365 : 30).then((res) => {
341
+ return account7.restoreSubAccount().then((_) => {
342
+ return res;
343
+ });
344
+ });
345
+ },
346
+ [account7, state]
347
+ );
348
+ const ws = useWS();
349
+ const switchAccount = useCallback(
350
+ async (accountId) => {
351
+ ws.closePrivate(1e3, "switch account");
352
+ return account7.switchAccount(accountId);
310
353
  },
311
- [account5, state]
354
+ [account7]
312
355
  );
313
356
  const createAccount = useCallback(async () => {
314
- return account5.createAccount();
315
- }, [account5]);
357
+ return account7.createAccount();
358
+ }, [account7]);
359
+ const createSubAccount = useCallback(
360
+ async (description) => {
361
+ return account7.createSubAccount(description);
362
+ },
363
+ [account7]
364
+ );
365
+ const updateSubAccount = useCallback(
366
+ async (value) => {
367
+ return account7.updateSubAccount(value);
368
+ },
369
+ [account7]
370
+ );
371
+ const refreshSubAccountBalances = useCallback(() => {
372
+ return account7.refreshSubAccountBalances();
373
+ }, [account7]);
374
+ const isSubAccount = useMemo(() => {
375
+ return state.accountId !== state.mainAccountId;
376
+ }, [state]);
316
377
  return {
317
- account: account5,
378
+ account: account7,
318
379
  state,
319
- // info: {},
320
- // login,
380
+ isSubAccount,
381
+ isMainAccount: !isSubAccount,
382
+ subAccount: {
383
+ refresh: refreshSubAccountBalances,
384
+ create: createSubAccount,
385
+ update: updateSubAccount
386
+ },
387
+ switchAccount,
321
388
  createOrderlyKey,
322
389
  createAccount
323
- // disconnect,
324
- // connect,
325
- // setChain,
326
- // settlement,
327
390
  };
328
391
  };
392
+
393
+ // src/usePrivateQuery.ts
329
394
  var usePrivateQuery = (query, options) => {
330
395
  const { formatter, ...swrOptions } = options || {};
331
396
  const { state } = useAccount();
332
397
  const middleware = Array.isArray(options?.use) ? options?.use ?? [] : [];
333
- return useSWR(
398
+ return useSWR__default(
334
399
  () => state.status >= AccountStatusEnum.EnableTrading || state.status === AccountStatusEnum.EnableTradingWithoutConnected ? [query, state.accountId] : null,
335
400
  (url, init2) => {
336
401
  return fetcher(url, init2, { formatter });
@@ -338,7 +403,7 @@ var usePrivateQuery = (query, options) => {
338
403
  {
339
404
  ...swrOptions,
340
405
  use: [signatureMiddleware, ...middleware],
341
- onError: (err) => {
406
+ onError: () => {
342
407
  }
343
408
  }
344
409
  );
@@ -349,6 +414,8 @@ var usePrivateInfiniteQuery = (getKey, options) => {
349
414
  const middleware = Array.isArray(restOptions?.use) ? restOptions?.use ?? [] : [];
350
415
  const result = useSWRInfinite(
351
416
  (pageIndex, previousPageData) => {
417
+ if (!getKey)
418
+ return null;
352
419
  const queryKey = getKey(pageIndex, previousPageData);
353
420
  if (queryKey && (state.status >= AccountStatusEnum.EnableTrading || state.status === AccountStatusEnum.EnableTradingWithoutConnected)) {
354
421
  return [queryKey, state.accountId];
@@ -396,7 +463,7 @@ var usePreLoadData = () => {
396
463
  }
397
464
  );
398
465
  const apiBaseUrl = useConfig("apiBaseUrl");
399
- const { data: systemInfo } = useSWR(
466
+ const { data: systemInfo } = useSWR__default(
400
467
  "/v1/public/system_info",
401
468
  async (url, init2) => {
402
469
  const data = await fetch(
@@ -487,14 +554,16 @@ function useSessionStorage(key, initialValue) {
487
554
  );
488
555
  return [storedValue, setValue];
489
556
  }
490
- function useLocalStorage(key, initialValue) {
557
+ function useLocalStorage(key, initialValue, options = {
558
+ parseJSON
559
+ }) {
491
560
  const readValue = useCallback(() => {
492
561
  if (typeof window === "undefined") {
493
562
  return initialValue;
494
563
  }
495
564
  try {
496
565
  const item = window.localStorage.getItem(key);
497
- return item ? parseJSON(item) : initialValue;
566
+ return item ? options.parseJSON(item) : initialValue;
498
567
  } catch (error) {
499
568
  return initialValue;
500
569
  }
@@ -623,43 +692,6 @@ var useTrackingInstance = () => {
623
692
  });
624
693
  return trackInstace;
625
694
  };
626
- var WS_NAME = "nativeWebsocketClient";
627
- var useWS = () => {
628
- const { configStore } = useContext(OrderlyContext);
629
- const ws = useConstant(() => {
630
- let websocketClient = SimpleDI.get(WS_NAME);
631
- const account5 = SimpleDI.get(Account.instanceName);
632
- if (!websocketClient) {
633
- websocketClient = new WS({
634
- networkId: configStore.get("networkId"),
635
- publicUrl: configStore.get("publicWsUrl"),
636
- privateUrl: configStore.get("privateWsUrl"),
637
- onSigntureRequest: async (accountId) => {
638
- const signer = account5.signer;
639
- const timestamp = getTimestamp();
640
- const result = await signer.signText(timestamp.toString());
641
- return { ...result, timestamp };
642
- }
643
- });
644
- if ((account5.stateValue.status === AccountStatusEnum.EnableTrading || account5.stateValue.status === AccountStatusEnum.EnableTradingWithoutConnected) && account5.stateValue.accountId) {
645
- websocketClient.openPrivate(account5.stateValue.accountId);
646
- }
647
- account5.on("change:status", (nextState) => {
648
- if ((nextState.status === AccountStatusEnum.EnableTrading || nextState.status === AccountStatusEnum.EnableTradingWithoutConnected) && nextState.accountId) {
649
- websocketClient.openPrivate(nextState.accountId);
650
- } else {
651
- websocketClient.closePrivate(1e3, "switch account");
652
- }
653
- });
654
- if (typeof window !== "undefined") {
655
- getGlobalObject()["__Orderly_WS"] = websocketClient;
656
- }
657
- SimpleDI.registerByName(WS_NAME, websocketClient);
658
- }
659
- return websocketClient;
660
- });
661
- return ws;
662
- };
663
695
  var useKeyStore = () => {
664
696
  const ctx = useContext(OrderlyContext);
665
697
  return ctx.keyStore;
@@ -715,6 +747,73 @@ var StatusProvider = (props) => {
715
747
  const wsStatus = useWsStatus();
716
748
  return /* @__PURE__ */ jsx(StatusContext.Provider, { value: { ws: wsStatus }, children: props.children });
717
749
  };
750
+ var useWSObserver = (calculatorService) => {
751
+ const ws = useWS();
752
+ useEffect(() => {
753
+ const markPriceSubscription = ws.subscribe("markprices", {
754
+ onMessage: (message) => {
755
+ const data = /* @__PURE__ */ Object.create(null);
756
+ for (let index = 0; index < message.length; index++) {
757
+ const element = message[index];
758
+ data[element.symbol] = element.price;
759
+ }
760
+ calculatorService.calc("markPrice" /* MARK_PRICE */, data, {
761
+ skipWhenOnPause: true
762
+ });
763
+ },
764
+ onError: (error) => {
765
+ }
766
+ });
767
+ const indexPriceSubscription = ws.subscribe("indexprices", {
768
+ onMessage: (message) => {
769
+ if (!Array.isArray(message))
770
+ return;
771
+ const prices = /* @__PURE__ */ Object.create(null);
772
+ for (let index = 0; index < message.length; index++) {
773
+ const element = message[index];
774
+ prices[element.symbol.replace("SPOT", "PERP")] = element.price;
775
+ }
776
+ calculatorService.calc("indexPrice" /* INDEX_PRICE */, prices, {
777
+ skipWhenOnPause: true
778
+ });
779
+ }
780
+ });
781
+ return () => {
782
+ markPriceSubscription?.();
783
+ indexPriceSubscription?.();
784
+ };
785
+ }, []);
786
+ };
787
+ var useApiStatusStore = create()(
788
+ immer((set) => ({
789
+ apis: {
790
+ positions: {
791
+ loading: false
792
+ }
793
+ },
794
+ actions: {
795
+ updateStatus: (key, status) => {
796
+ set((state) => {
797
+ state.apis[key] = status;
798
+ });
799
+ },
800
+ updateApiLoading: (key, loading) => {
801
+ set((state) => {
802
+ state.apis[key].loading = loading;
803
+ });
804
+ },
805
+ updateApiError: (key, error) => {
806
+ set((state) => {
807
+ state.apis[key] = {
808
+ loading: false,
809
+ error
810
+ };
811
+ });
812
+ }
813
+ }
814
+ }))
815
+ );
816
+ var useApiStatusActions = () => useApiStatusStore((state) => state.actions);
718
817
  var BaseMergeHandler = class {
719
818
  constructor(message) {
720
819
  this.message = message;
@@ -938,72 +1037,6 @@ var AlgoOrderMergeHandler = class _AlgoOrderMergeHandler extends BaseMergeHandle
938
1037
  return rootOrder;
939
1038
  }
940
1039
  };
941
-
942
- // src/services/orderMerge/regularOrderMergeHandler.ts
943
- var RegularOrderMergeHandler = class extends BaseMergeHandler {
944
- get orderId() {
945
- return this.data.order_id;
946
- }
947
- get status() {
948
- return this.data.status;
949
- }
950
- pre(message, prevData) {
951
- return object2underscore(message);
952
- }
953
- isFullFilled() {
954
- return "total_executed_quantity" in this.data && this.data.total_executed_quantity === this.data.quantity;
955
- }
956
- };
957
-
958
- // src/utils/swr.ts
959
- var generateKeyFun = (args) => (pageIndex, previousPageData) => {
960
- if (previousPageData && !previousPageData.rows?.length)
961
- return null;
962
- const { status, symbol, side, size = 100, page, dateRange } = args;
963
- const search = new URLSearchParams([
964
- ["size", size.toString()],
965
- ["page", `${pageIndex + 1}`],
966
- ["source_type", "ALL"]
967
- ]);
968
- if (dateRange) {
969
- if (dateRange.from) {
970
- search.set("start_t", `${dateRange.from.getTime()}`);
971
- }
972
- if (dateRange.to) {
973
- search.set("end_t", `${dateRange.to.getTime()}`);
974
- }
975
- }
976
- if (page) {
977
- search.set("page", `${page}`);
978
- }
979
- if (status) {
980
- search.set(`status`, status);
981
- }
982
- if (symbol) {
983
- search.set(`symbol`, symbol);
984
- }
985
- if (side) {
986
- search.set(`side`, side);
987
- }
988
- return `/v1/orders?${search.toString()}`;
989
- };
990
- var updateOrdersHandler = (key, updatedOrder, orders) => {
991
- if (!orders) {
992
- return;
993
- }
994
- const handler = new RegularOrderMergeHandler(updatedOrder);
995
- return handler.merge(key, updatedOrder, orders);
996
- };
997
- function updateAlgoOrdersHandler(key, message, orders) {
998
- if (!orders) {
999
- return;
1000
- }
1001
- const mergeHandler = new AlgoOrderMergeHandler(message);
1002
- const result = mergeHandler.merge(key, message, orders);
1003
- return result;
1004
- }
1005
- function getPositionBySymbol(symbol) {
1006
- }
1007
1040
  var useAppStore = create()(
1008
1041
  immer((set) => ({
1009
1042
  // accountInfo: null,
@@ -1423,9 +1456,9 @@ var usePositionStore = create()(
1423
1456
  all: POSITION_EMPTY
1424
1457
  },
1425
1458
  actions: {
1426
- setPositions: (key, positions2) => {
1459
+ setPositions: (key, positions3) => {
1427
1460
  set((state) => {
1428
- state.positions[key] = positions2;
1461
+ state.positions[key] = positions3;
1429
1462
  });
1430
1463
  },
1431
1464
  closePosition: (symbol) => {
@@ -1445,36 +1478,6 @@ var usePositionStore = create()(
1445
1478
  );
1446
1479
  var usePositions = (symbol = "all") => usePositionStore((state) => (state.positions[symbol] ?? POSITION_EMPTY).rows);
1447
1480
  var usePositionActions = () => usePositionStore((state) => state.actions);
1448
- var useApiStatusStore = create()(
1449
- immer((set) => ({
1450
- apis: {
1451
- positions: {
1452
- loading: false
1453
- }
1454
- },
1455
- actions: {
1456
- updateStatus: (key, status) => {
1457
- set((state) => {
1458
- state.apis[key] = status;
1459
- });
1460
- },
1461
- updateApiLoading: (key, loading) => {
1462
- set((state) => {
1463
- state.apis[key].loading = loading;
1464
- });
1465
- },
1466
- updateApiError: (key, error) => {
1467
- set((state) => {
1468
- state.apis[key] = {
1469
- loading: false,
1470
- error
1471
- };
1472
- });
1473
- }
1474
- }
1475
- }))
1476
- );
1477
- var useApiStatusActions = () => useApiStatusStore((state) => state.actions);
1478
1481
 
1479
1482
  // src/orderly/calculator/positions.ts
1480
1483
  var NAME_PREFIX = "positionCalculator";
@@ -1510,38 +1513,41 @@ var PositionCalculator = class extends BaseCalculator {
1510
1513
  }
1511
1514
  }
1512
1515
  calcByMarkPrice(markPrice, ctx) {
1513
- let positions2 = this.getPosition(markPrice, ctx);
1514
- if (!positions2 || !Array.isArray(positions2.rows) || !positions2.rows.length)
1515
- return positions2;
1516
- positions2 = {
1517
- ...positions2,
1518
- rows: positions2.rows.map((item) => ({
1519
- ...item,
1520
- mark_price: markPrice[item.symbol] || item.mark_price
1521
- }))
1516
+ let positions3 = this.getPosition(markPrice, ctx);
1517
+ useAppStore.getState().fundingRates;
1518
+ if (!positions3 || !Array.isArray(positions3.rows) || !positions3.rows.length)
1519
+ return positions3;
1520
+ positions3 = {
1521
+ ...positions3,
1522
+ rows: positions3.rows.map((item) => {
1523
+ return {
1524
+ ...item,
1525
+ mark_price: markPrice[item.symbol] || item.mark_price
1526
+ };
1527
+ })
1522
1528
  };
1523
- return this.format(positions2, ctx);
1529
+ return this.format(positions3, ctx);
1524
1530
  }
1525
1531
  calcByIndexPrice(indexPrice, ctx) {
1526
- let positions2 = this.getPosition(indexPrice, ctx);
1527
- if (!positions2) {
1528
- return positions2;
1529
- }
1530
- if (!Array.isArray(positions2.rows) || !positions2.rows.length)
1531
- return positions2;
1532
- positions2 = {
1533
- ...positions2,
1534
- rows: positions2.rows.map((item) => ({
1532
+ let positions3 = this.getPosition(indexPrice, ctx);
1533
+ if (!positions3) {
1534
+ return positions3;
1535
+ }
1536
+ if (!Array.isArray(positions3.rows) || !positions3.rows.length)
1537
+ return positions3;
1538
+ positions3 = {
1539
+ ...positions3,
1540
+ rows: positions3.rows.map((item) => ({
1535
1541
  ...item,
1536
1542
  index_price: indexPrice[item.symbol] || item.index_price || item.mark_price
1537
1543
  }))
1538
1544
  };
1539
- return this.format(positions2, ctx);
1545
+ return this.format(positions3, ctx);
1540
1546
  }
1541
- calcByPosition(positions2, ctx) {
1542
- if (positions2.rows.length === 0)
1543
- return positions2;
1544
- return this.format(positions2, ctx);
1547
+ calcByPosition(positions3, ctx) {
1548
+ if (positions3.rows.length === 0)
1549
+ return positions3;
1550
+ return this.format(positions3, ctx);
1545
1551
  }
1546
1552
  format(data, ctx) {
1547
1553
  const { accountInfo, symbolsInfo, fundingRates, portfolio } = ctx;
@@ -1551,6 +1557,7 @@ var PositionCalculator = class extends BaseCalculator {
1551
1557
  let unrealPnL_total = zero, unrealPnL_total_index = zero, notional_total = zero, unsettlementPnL_total = zero;
1552
1558
  let rows = data.rows.map((item) => {
1553
1559
  const info = symbolsInfo[item.symbol];
1560
+ const sum_unitary_funding = fundingRates?.[item.symbol]?.["sum_unitary_funding"] ?? 0;
1554
1561
  const notional = positions.notional(item.position_qty, item.mark_price);
1555
1562
  const unrealPnl = positions.unrealizedPnL({
1556
1563
  qty: item.position_qty,
@@ -1609,8 +1616,10 @@ var PositionCalculator = class extends BaseCalculator {
1609
1616
  unrealPnL_total_index = unrealPnL_total_index.add(unrealPnl_index);
1610
1617
  notional_total = notional_total.add(notional);
1611
1618
  unsettlementPnL_total = unsettlementPnL_total.add(unsettlementPnL2);
1619
+ const fundingFee = new Decimal(sum_unitary_funding).sub(item.last_sum_unitary_funding).mul(item.position_qty).negated().toNumber();
1612
1620
  return {
1613
1621
  ...item,
1622
+ fundingFee,
1614
1623
  mm: positions.maintenanceMargin({
1615
1624
  positionQty: item.position_qty,
1616
1625
  markPrice: item.mark_price,
@@ -1679,12 +1688,12 @@ var PositionCalculator = class extends BaseCalculator {
1679
1688
  };
1680
1689
  }
1681
1690
  getPosition(_, ctx) {
1682
- let positions2 = ctx.get((output) => output[this.name]) || usePositionStore.getState().positions[this.symbol];
1691
+ const positions3 = ctx.get((output) => output[this.name]) || usePositionStore.getState().positions[this.symbol];
1683
1692
  if (this.symbol === AllPositions) {
1684
- return positions2;
1693
+ return positions3;
1685
1694
  }
1686
- if (positions2 && Array.isArray(positions2.rows)) {
1687
- return positions2;
1695
+ if (positions3 && Array.isArray(positions3.rows)) {
1696
+ return positions3;
1688
1697
  }
1689
1698
  return this.preprocess(this.getAllPositions(ctx));
1690
1699
  }
@@ -1699,25 +1708,6 @@ var PositionCalculator = class extends BaseCalculator {
1699
1708
  PositionCalculator.logPosition = (symbol = "all") => {
1700
1709
  return usePositionStore.getState().positions[symbol];
1701
1710
  };
1702
-
1703
- // src/utils/parseHolding.ts
1704
- var parseHolding = (holding, markPrices) => {
1705
- const nonUSDC = [];
1706
- let USDC_holding = 0;
1707
- holding.forEach((item) => {
1708
- if (item.token === "USDC") {
1709
- USDC_holding = item.holding;
1710
- } else {
1711
- nonUSDC.push({
1712
- holding: item.holding,
1713
- markPrice: markPrices[item.token] ?? 0,
1714
- // markPrice: 0,
1715
- discount: 0
1716
- });
1717
- }
1718
- });
1719
- return [USDC_holding, nonUSDC];
1720
- };
1721
1711
  function createGetter(data, depth = 2) {
1722
1712
  const getValue = (value, defaultValue) => {
1723
1713
  if (defaultValue === void 0) {
@@ -1748,6 +1738,25 @@ function createGetter(data, depth = 2) {
1748
1738
  });
1749
1739
  }
1750
1740
 
1741
+ // src/utils/parseHolding.ts
1742
+ var parseHolding = (holding, markPrices) => {
1743
+ const nonUSDC = [];
1744
+ let USDC_holding = 0;
1745
+ holding.forEach((item) => {
1746
+ if (item.token === "USDC") {
1747
+ USDC_holding = item.holding;
1748
+ } else {
1749
+ nonUSDC.push({
1750
+ holding: item.holding,
1751
+ markPrice: markPrices[item.token] ?? 0,
1752
+ // markPrice: 0,
1753
+ discount: 0
1754
+ });
1755
+ }
1756
+ });
1757
+ return [USDC_holding, nonUSDC];
1758
+ };
1759
+
1751
1760
  // src/orderly/calculator/portfolio.ts
1752
1761
  var PortfolioCalculatorName = "portfolio";
1753
1762
  var PortfolioCalculator = class extends BaseCalculator {
@@ -1756,7 +1765,7 @@ var PortfolioCalculator = class extends BaseCalculator {
1756
1765
  this.name = PortfolioCalculatorName;
1757
1766
  }
1758
1767
  calc(scope, data, ctx) {
1759
- let markPrices, positions2;
1768
+ let markPrices, positions3;
1760
1769
  const portfolio = this.getPortfolio(ctx);
1761
1770
  if (scope === "markPrice" /* MARK_PRICE */) {
1762
1771
  markPrices = data;
@@ -1765,27 +1774,31 @@ var PortfolioCalculator = class extends BaseCalculator {
1765
1774
  (cache) => cache[MarketCalculatorName]
1766
1775
  );
1767
1776
  }
1768
- positions2 = ctx.get(
1777
+ positions3 = ctx.get(
1769
1778
  (output) => output.positionCalculator_all
1770
1779
  );
1771
1780
  let holding = portfolio.holding;
1772
1781
  if (scope === "portfolio" /* PORTFOLIO */ && data.holding && Array.isArray(holding)) {
1773
- holding = holding.map((item) => {
1774
- if (data.holding[item.token]) {
1775
- return {
1776
- ...item,
1777
- holding: data.holding[item.token].holding,
1778
- frozen: data.holding[item.token].frozen
1779
- };
1780
- }
1781
- return item;
1782
- });
1782
+ if (Array.isArray(data.holding)) {
1783
+ holding = data.holding;
1784
+ } else {
1785
+ holding = holding.map((item) => {
1786
+ if (data.holding[item.token]) {
1787
+ return {
1788
+ ...item,
1789
+ holding: data.holding[item.token].holding,
1790
+ frozen: data.holding[item.token].frozen
1791
+ };
1792
+ }
1793
+ return item;
1794
+ });
1795
+ }
1783
1796
  }
1784
1797
  const accountInfo = ctx.accountInfo;
1785
1798
  const symbolsInfo = ctx.symbolsInfo;
1786
1799
  return this.format({
1787
1800
  holding,
1788
- positions: positions2,
1801
+ positions: positions3,
1789
1802
  markPrices,
1790
1803
  accountInfo,
1791
1804
  symbolsInfo
@@ -1795,12 +1808,12 @@ var PortfolioCalculator = class extends BaseCalculator {
1795
1808
  return ctx.get((output) => output[this.name]) || useAppStore.getState().portfolio;
1796
1809
  }
1797
1810
  format(inputs) {
1798
- const { holding, positions: positions2, markPrices, accountInfo, symbolsInfo } = inputs;
1799
- if (!holding || !positions2 || !Array.isArray(positions2.rows) || !markPrices || !accountInfo) {
1811
+ const { holding, positions: positions3, markPrices, accountInfo, symbolsInfo } = inputs;
1812
+ if (!holding || !positions3 || !Array.isArray(positions3.rows) || !markPrices || !accountInfo) {
1800
1813
  return null;
1801
1814
  }
1802
- const unsettledPnL = pathOr(0, ["total_unsettled_pnl"])(positions2);
1803
- const unrealizedPnL = pathOr(0, ["total_unreal_pnl"])(positions2);
1815
+ const unsettledPnL = pathOr(0, ["total_unsettled_pnl"])(positions3);
1816
+ const unrealizedPnL = pathOr(0, ["total_unreal_pnl"])(positions3);
1804
1817
  const [USDC_holding, nonUSDC] = parseHolding(holding, markPrices);
1805
1818
  const usdc = holding.find((item) => item.token === "USDC");
1806
1819
  const totalCollateral = account.totalCollateral({
@@ -1818,7 +1831,7 @@ var PortfolioCalculator = class extends BaseCalculator {
1818
1831
  totalValue: totalValue.toNumber()
1819
1832
  });
1820
1833
  const totalInitialMarginWithOrders = account.totalInitialMarginWithQty({
1821
- positions: positions2.rows,
1834
+ positions: positions3.rows,
1822
1835
  markPrices,
1823
1836
  IMR_Factors: accountInfo.imr_factor,
1824
1837
  maxLeverage: accountInfo.max_leverage,
@@ -1830,7 +1843,7 @@ var PortfolioCalculator = class extends BaseCalculator {
1830
1843
  });
1831
1844
  const availableBalance = account.availableBalance({
1832
1845
  USDCHolding: usdc?.holding ?? 0,
1833
- unsettlementPnL: positions2.total_unsettled_pnl ?? 0
1846
+ unsettlementPnL: positions3.total_unsettled_pnl ?? 0
1834
1847
  });
1835
1848
  return {
1836
1849
  totalCollateral,
@@ -1922,6 +1935,75 @@ var useCalculatorService = () => {
1922
1935
  return calculatorService;
1923
1936
  };
1924
1937
 
1938
+ // src/services/orderMerge/regularOrderMergeHandler.ts
1939
+ var RegularOrderMergeHandler = class extends BaseMergeHandler {
1940
+ get orderId() {
1941
+ return this.data.order_id;
1942
+ }
1943
+ get status() {
1944
+ return this.data.status;
1945
+ }
1946
+ pre(message, prevData) {
1947
+ return object2underscore(message);
1948
+ }
1949
+ isFullFilled() {
1950
+ return "total_executed_quantity" in this.data && this.data.total_executed_quantity === this.data.quantity;
1951
+ }
1952
+ };
1953
+
1954
+ // src/utils/swr.ts
1955
+ var generateKeyFun = (url, args) => (pageIndex, previousPageData) => {
1956
+ if (previousPageData && !previousPageData.rows?.length)
1957
+ return null;
1958
+ const { status, symbol, side, size = 100, page, dateRange } = args;
1959
+ const search = new URLSearchParams([
1960
+ ["size", size.toString()],
1961
+ ["page", `${pageIndex + 1}`]
1962
+ // ["source_type", "ALL"],
1963
+ ]);
1964
+ if (args.sourceTypeAll) {
1965
+ search.set("source_type", "ALL");
1966
+ }
1967
+ if (dateRange) {
1968
+ if (dateRange.from) {
1969
+ search.set("start_t", `${dateRange.from.getTime()}`);
1970
+ }
1971
+ if (dateRange.to) {
1972
+ search.set("end_t", `${dateRange.to.getTime()}`);
1973
+ }
1974
+ }
1975
+ if (page) {
1976
+ search.set("page", `${page}`);
1977
+ }
1978
+ if (status) {
1979
+ search.set(`status`, status);
1980
+ }
1981
+ if (symbol) {
1982
+ search.set(`symbol`, symbol);
1983
+ }
1984
+ if (side) {
1985
+ search.set(`side`, side);
1986
+ }
1987
+ return `${url}?${search.toString()}`;
1988
+ };
1989
+ var updateOrdersHandler = (key, updatedOrder, orders) => {
1990
+ if (!orders) {
1991
+ return;
1992
+ }
1993
+ const handler = new RegularOrderMergeHandler(updatedOrder);
1994
+ return handler.merge(key, updatedOrder, orders);
1995
+ };
1996
+ function updateAlgoOrdersHandler(key, message, orders) {
1997
+ if (!orders) {
1998
+ return;
1999
+ }
2000
+ const mergeHandler = new AlgoOrderMergeHandler(message);
2001
+ const result = mergeHandler.merge(key, message, orders);
2002
+ return result;
2003
+ }
2004
+ function getPositionBySymbol(symbol) {
2005
+ }
2006
+
1925
2007
  // src/orderly/orderbook.service.ts
1926
2008
  var defaultRawOrderBook = {
1927
2009
  asks: [],
@@ -2044,10 +2126,10 @@ var useMarkPrice = (symbol) => {
2044
2126
  };
2045
2127
  var useSymbolsInfo = () => {
2046
2128
  const symbolsInfo = useAppStore((state) => state.symbolsInfo);
2047
- return useMemo(
2048
- () => createGetter({ ...symbolsInfo }),
2049
- [symbolsInfo]
2050
- );
2129
+ return useMemo(() => createGetter({ ...symbolsInfo }), [symbolsInfo]);
2130
+ };
2131
+ var useSymbolsInfoStore = () => {
2132
+ return useAppStore((state) => state.symbolsInfo);
2051
2133
  };
2052
2134
  var useIndexPrice = (symbol) => {
2053
2135
  symbol = symbol.replace("PERP", "SPOT");
@@ -2403,41 +2485,8 @@ var useOrderbookStream = (symbol, initial = INIT_DATA, options) => {
2403
2485
  bids: [...data.bids]
2404
2486
  });
2405
2487
  useEffect(() => {
2406
- const updateData = [
2407
- [
2408
- reducedData.asks?.[reducedData.asks.length - 1]?.[0],
2409
- reducedData.bids?.[0]?.[0]
2410
- ],
2411
- [
2412
- reducedData.asks?.[reducedData.asks.length - 2]?.[0],
2413
- reducedData.bids?.[1]?.[0]
2414
- ],
2415
- [
2416
- reducedData.asks?.[reducedData.asks.length - 3]?.[0],
2417
- reducedData.bids?.[2]?.[0]
2418
- ],
2419
- [
2420
- reducedData.asks?.[reducedData.asks.length - 4]?.[0],
2421
- reducedData.bids?.[3]?.[0]
2422
- ],
2423
- [
2424
- reducedData.asks?.[reducedData.asks.length - 5]?.[0],
2425
- reducedData.bids?.[4]?.[0]
2426
- ]
2427
- ];
2428
- eventEmitter.emit("orderbook:update", updateData);
2429
- }, [
2430
- reducedData.asks?.[reducedData.asks.length - 1]?.[0],
2431
- reducedData.asks?.[reducedData.asks.length - 2]?.[0],
2432
- reducedData.asks?.[reducedData.asks.length - 3]?.[0],
2433
- reducedData.asks?.[reducedData.asks.length - 4]?.[0],
2434
- reducedData.asks?.[reducedData.asks.length - 5]?.[0],
2435
- reducedData.bids?.[0]?.[0],
2436
- reducedData.bids?.[1]?.[0],
2437
- reducedData.bids?.[2]?.[0],
2438
- reducedData.bids?.[3]?.[0],
2439
- reducedData.bids?.[4]?.[0]
2440
- ]);
2488
+ eventEmitter.emit("orderbook:update", reducedData);
2489
+ }, [reducedData]);
2441
2490
  const middlePrice = useMemo(() => {
2442
2491
  let asksFrist = 0, bidsFirst = 0;
2443
2492
  if (data.asks.length > 0) {
@@ -2466,7 +2515,9 @@ var useOrderbookStream = (symbol, initial = INIT_DATA, options) => {
2466
2515
 
2467
2516
  // src/orderly/useAccountInfo.ts
2468
2517
  var useAccountInfo2 = () => {
2469
- return usePrivateQuery("/v1/client/info");
2518
+ return usePrivateQuery("/v1/client/info", {
2519
+ revalidateOnFocus: false
2520
+ });
2470
2521
  };
2471
2522
  var useMarketsStream = () => {
2472
2523
  const ws = useWS();
@@ -2531,6 +2582,10 @@ var useFundingRates = () => {
2531
2582
  const data = useAppStore((state) => state.fundingRates);
2532
2583
  return createGetter({ ...data });
2533
2584
  };
2585
+ var useFundingRatesStore = () => {
2586
+ const data = useAppStore((state) => state.fundingRates);
2587
+ return data;
2588
+ };
2534
2589
  var DefaultTab = { name: "Popular", id: 1 };
2535
2590
  var marketsKey = "markets";
2536
2591
  var useMarket = (type) => {
@@ -3117,6 +3172,12 @@ var useMarkPricesStream = () => {
3117
3172
  const data = useMarkPriceStore((state) => state.markPrices);
3118
3173
  return { data };
3119
3174
  };
3175
+
3176
+ // src/orderly/useIndexPricesStream.ts
3177
+ var useIndexPricesStream = () => {
3178
+ const data = useIndexPriceStore((state) => state.indexPrices);
3179
+ return { data };
3180
+ };
3120
3181
  var generateLeverageLevers = (max3) => {
3121
3182
  const min3 = 1;
3122
3183
  const parts = 5;
@@ -3128,8 +3189,11 @@ var generateLeverageLevers = (max3) => {
3128
3189
  return result;
3129
3190
  };
3130
3191
  var useLeverage = () => {
3131
- const { data, mutate: mutate3 } = usePrivateQuery(
3132
- "/v1/client/info"
3192
+ const { data, mutate: mutate5 } = usePrivateQuery(
3193
+ "/v1/client/info",
3194
+ {
3195
+ revalidateOnFocus: false
3196
+ }
3133
3197
  );
3134
3198
  const [update, { isMutating }] = useMutation("/v1/client/leverage");
3135
3199
  const { data: leverageConfig, isLoading } = useQuery("/v1/public/leverage", {
@@ -3141,12 +3205,12 @@ var useLeverage = () => {
3141
3205
  async (data2) => {
3142
3206
  const res = await update(data2);
3143
3207
  if (res.success) {
3144
- return mutate3();
3208
+ return mutate5();
3145
3209
  } else {
3146
3210
  throw new Error(res.message);
3147
3211
  }
3148
3212
  },
3149
- [update, mutate3]
3213
+ [update, mutate5]
3150
3214
  );
3151
3215
  const memoizedCurLeverage = useMemo(() => {
3152
3216
  if (data?.max_leverage !== void 0) {
@@ -3297,6 +3361,11 @@ var findPositionTPSLFromOrders = (orders, symbol) => {
3297
3361
  };
3298
3362
 
3299
3363
  // src/orderly/usePositionStream/usePositionStream.ts
3364
+ var scopes = [
3365
+ "position" /* POSITION */,
3366
+ "markPrice" /* MARK_PRICE */,
3367
+ "indexPrice" /* INDEX_PRICE */
3368
+ ];
3300
3369
  var usePositionStream = (symbol = "all", options) => {
3301
3370
  const { calcMode } = options || {};
3302
3371
  const { includedPendingOrder = false } = options || {};
@@ -3317,49 +3386,34 @@ var usePositionStream = (symbol = "all", options) => {
3317
3386
  (state) => state.apis
3318
3387
  );
3319
3388
  useEffect(() => {
3320
- if (symbol === "all")
3389
+ if (symbol === "all") {
3321
3390
  return;
3391
+ }
3322
3392
  positionCalculator.current = new PositionCalculator(symbol);
3323
- calculatorService.register(
3324
- "position" /* POSITION */,
3325
- positionCalculator.current
3326
- );
3327
- calculatorService.register(
3328
- "markPrice" /* MARK_PRICE */,
3329
- positionCalculator.current
3330
- );
3331
- calculatorService.register(
3332
- "indexPrice" /* INDEX_PRICE */,
3333
- positionCalculator.current
3334
- );
3393
+ for (const scope of scopes) {
3394
+ calculatorService.register(scope, positionCalculator.current);
3395
+ }
3335
3396
  return () => {
3336
- calculatorService.unregister(
3337
- "position" /* POSITION */,
3338
- positionCalculator.current
3339
- );
3340
- calculatorService.unregister(
3341
- "markPrice" /* MARK_PRICE */,
3342
- positionCalculator.current
3343
- );
3344
- calculatorService.unregister(
3345
- "indexPrice" /* INDEX_PRICE */,
3346
- positionCalculator.current
3347
- );
3397
+ for (const scope of scopes) {
3398
+ calculatorService.unregister(scope, positionCalculator.current);
3399
+ }
3348
3400
  };
3349
3401
  }, [symbol]);
3350
3402
  const formattedPositions = usePositionStore((state) => {
3351
- const positions2 = state.positions[symbol] ?? POSITION_EMPTY;
3352
- return [positions2.rows, omit(["rows"], positions2)];
3403
+ const positions3 = state.positions[symbol] ?? POSITION_EMPTY;
3404
+ return [positions3.rows, omit(["rows"], positions3)];
3353
3405
  });
3354
3406
  const { totalCollateral, totalValue, totalUnrealizedROI } = useAppStore(
3355
3407
  (state) => state.portfolio
3356
3408
  );
3357
3409
  const aggregated = useMemo(() => {
3358
- let data = formattedPositions[1];
3359
- if (!data)
3410
+ const data = formattedPositions[1];
3411
+ if (!data) {
3360
3412
  return {};
3361
- if (calcMode === "markPrice")
3413
+ }
3414
+ if (calcMode === "markPrice") {
3362
3415
  return data;
3416
+ }
3363
3417
  const { total_unreal_pnl_index, unrealPnlROI_index, ...rest } = data;
3364
3418
  return {
3365
3419
  ...rest,
@@ -3411,7 +3465,10 @@ var usePositionStream = (symbol = "all", options) => {
3411
3465
  });
3412
3466
  }
3413
3467
  }
3414
- const positionInfoGetter = createGetter(aggregated, 1);
3468
+ const positionInfoGetter = createGetter(
3469
+ aggregated,
3470
+ 1
3471
+ );
3415
3472
  return [
3416
3473
  {
3417
3474
  rows,
@@ -3448,10 +3505,15 @@ var useOrderStream = (params, options) => {
3448
3505
  side,
3449
3506
  size = 50,
3450
3507
  page,
3451
- dateRange
3508
+ dateRange,
3509
+ sourceTypeAll
3452
3510
  } = params;
3453
- const [includes2, setIncludes] = useState(params.includes ?? ["ALL"]);
3454
- const [excludes, setExcludes] = useState(params.excludes ?? []);
3511
+ const [includes2, setIncludes] = useState(
3512
+ params.includes ?? ["ALL"]
3513
+ );
3514
+ const [excludes, setExcludes] = useState(
3515
+ params.excludes ?? []
3516
+ );
3455
3517
  const { data: markPrices } = useMarkPricesStream();
3456
3518
  const { registerKeyHandler, unregisterKeyHandler } = useDataCenterContext();
3457
3519
  const [
@@ -3472,38 +3534,63 @@ var useOrderStream = (params, options) => {
3472
3534
  doUpdateAlgoOrder,
3473
3535
  { error: updateAlgoOrderError, isMutating: updateAlgoMutating }
3474
3536
  ] = useMutation("/v1/algo/order", "PUT");
3537
+ const normalOrderKeyFn = useMemo(() => {
3538
+ return generateKeyFun("/v1/orders", {
3539
+ status,
3540
+ symbol,
3541
+ side,
3542
+ size,
3543
+ page,
3544
+ dateRange,
3545
+ sourceTypeAll
3546
+ });
3547
+ }, [status, symbol, side, size, page, dateRange]);
3548
+ const algoOrderKeyFn = useMemo(() => {
3549
+ return sourceTypeAll ? null : generateKeyFun("/v1/algo/orders", {
3550
+ status,
3551
+ symbol,
3552
+ side,
3553
+ size: 100,
3554
+ page,
3555
+ dateRange
3556
+ });
3557
+ }, [status, symbol, side, dateRange, size]);
3475
3558
  useEffect(() => {
3476
3559
  const formatKey = (value) => value ? `:${value}` : "";
3477
3560
  const key = `orders${formatKey(status)}${formatKey(symbol)}${formatKey(
3478
3561
  side
3479
3562
  )}${formatKey(size.toString())}`;
3480
- registerKeyHandler?.(
3481
- key,
3482
- generateKeyFun({ status, symbol, side, size, page, dateRange })
3483
- );
3563
+ registerKeyHandler?.(key, normalOrderKeyFn);
3564
+ if (algoOrderKeyFn) {
3565
+ registerKeyHandler?.(key.replace("orders", "algoOrders"), algoOrderKeyFn);
3566
+ }
3484
3567
  return () => {
3485
3568
  if (!options?.stopOnUnmount)
3486
3569
  return;
3487
3570
  unregisterKeyHandler(key);
3571
+ if (algoOrderKeyFn) {
3572
+ unregisterKeyHandler(key.replace("orders", "algoOrders"));
3573
+ }
3488
3574
  };
3489
- }, [status, symbol, side, size, page, dateRange, options?.keeplive]);
3490
- const ordersResponse = usePrivateInfiniteQuery(
3491
- generateKeyFun({ status, symbol, side, size, page, dateRange }),
3492
- {
3493
- initialSize: 1,
3494
- // revalidateFirstPage: false,
3495
- // onError: (err) => {
3496
- // console.error("fetch failed::::", err);
3497
- // },
3498
- formatter: (data) => data,
3499
- revalidateOnFocus: false
3500
- }
3501
- );
3575
+ }, [normalOrderKeyFn, options?.keeplive]);
3576
+ const normalOrdersResponse = usePrivateInfiniteQuery(normalOrderKeyFn, {
3577
+ initialSize: 1,
3578
+ formatter: (data) => data,
3579
+ revalidateOnFocus: false
3580
+ });
3581
+ const algoOrdersResponse = usePrivateInfiniteQuery(algoOrderKeyFn, {
3582
+ formatter: (data) => data,
3583
+ revalidateOnFocus: false
3584
+ });
3502
3585
  const flattenOrders = useMemo(() => {
3503
- if (!ordersResponse.data) {
3586
+ if (!normalOrdersResponse.data || !algoOrdersResponse.data && !sourceTypeAll) {
3504
3587
  return null;
3505
3588
  }
3506
- let orders2 = ordersResponse.data?.map((item) => item.rows)?.flat();
3589
+ let orders2 = normalOrdersResponse.data?.map((item) => item.rows)?.flat();
3590
+ if (algoOrdersResponse.data) {
3591
+ const algoOrders = algoOrdersResponse.data?.map((item) => item.rows)?.flat();
3592
+ orders2 = [...orders2, ...algoOrders];
3593
+ }
3507
3594
  if (includes2.includes("ALL") && excludes.length === 0) {
3508
3595
  return orders2;
3509
3596
  }
@@ -3519,7 +3606,7 @@ var useOrderStream = (params, options) => {
3519
3606
  );
3520
3607
  }
3521
3608
  return orders2;
3522
- }, [ordersResponse.data, includes2, excludes]);
3609
+ }, [normalOrdersResponse.data, algoOrdersResponse.data, includes2, excludes]);
3523
3610
  const orders = useMemo(() => {
3524
3611
  if (!flattenOrders) {
3525
3612
  return null;
@@ -3559,13 +3646,13 @@ var useOrderStream = (params, options) => {
3559
3646
  doCancelAllOrders(null),
3560
3647
  doCancelAllAlgoOrders(null, { algo_type: "STOP" })
3561
3648
  ]);
3562
- }, [ordersResponse.data]);
3649
+ }, [normalOrdersResponse.data, algoOrdersResponse.data]);
3563
3650
  const cancelAllTPSLOrders = useCallback(() => {
3564
3651
  return cancelAlgoOrdersByTypes([
3565
3652
  AlgoOrderRootType.POSITIONAL_TP_SL,
3566
3653
  AlgoOrderRootType.TP_SL
3567
3654
  ]);
3568
- }, [ordersResponse.data]);
3655
+ }, [algoOrdersResponse.data]);
3569
3656
  const _updateOrder = useCallback(
3570
3657
  (orderId, order, type) => {
3571
3658
  switch (type) {
@@ -3599,7 +3686,8 @@ var useOrderStream = (params, options) => {
3599
3686
  source: `SDK${version_default}`
3600
3687
  }).then((res) => {
3601
3688
  if (res.success) {
3602
- ordersResponse.mutate();
3689
+ normalOrdersResponse.mutate();
3690
+ algoOrdersResponse.mutate();
3603
3691
  return res;
3604
3692
  } else {
3605
3693
  throw new Error(res.message);
@@ -3628,7 +3716,6 @@ var useOrderStream = (params, options) => {
3628
3716
  return _cancelOrder(orderId, "algoOrder", symbol2);
3629
3717
  }, []);
3630
3718
  const loadMore = () => {
3631
- ordersResponse.setSize(ordersResponse.size + 1);
3632
3719
  };
3633
3720
  const cancelTPSLChildOrder = useCallback(
3634
3721
  (orderId, rootAlgoOrderId) => {
@@ -3657,14 +3744,18 @@ var useOrderStream = (params, options) => {
3657
3744
  []
3658
3745
  );
3659
3746
  const meta = useMemo(() => {
3660
- return ordersResponse.data?.[0]?.meta;
3661
- }, [ordersResponse.data?.[0]]);
3747
+ return normalOrdersResponse.data?.[0]?.meta;
3748
+ }, [normalOrdersResponse.data?.[0]]);
3749
+ const refresh = useCallback(() => {
3750
+ normalOrdersResponse.mutate();
3751
+ algoOrdersResponse.mutate();
3752
+ }, []);
3662
3753
  return [
3663
3754
  orders,
3664
3755
  {
3665
3756
  total,
3666
- isLoading: ordersResponse.isLoading,
3667
- refresh: ordersResponse.mutate,
3757
+ isLoading: normalOrdersResponse.isLoading || algoOrdersResponse.isLoading,
3758
+ refresh,
3668
3759
  loadMore,
3669
3760
  cancelAllOrders,
3670
3761
  cancelAllTPSLOrders,
@@ -3755,7 +3846,8 @@ var useCollateral = (options = { dp: 6 }) => {
3755
3846
  totalValue,
3756
3847
  freeCollateral,
3757
3848
  availableBalance,
3758
- unsettledPnL
3849
+ unsettledPnL,
3850
+ holding
3759
3851
  } = useAppStore((state) => state.portfolio);
3760
3852
  const accountInfo = useAppStore((state) => state.accountInfo);
3761
3853
  return {
@@ -3764,14 +3856,14 @@ var useCollateral = (options = { dp: 6 }) => {
3764
3856
  totalValue: totalValue?.toDecimalPlaces(dp).toNumber() ?? null,
3765
3857
  availableBalance,
3766
3858
  unsettledPnL,
3767
- accountInfo
3859
+ accountInfo,
3860
+ holding
3768
3861
  // @hidden
3769
3862
  // positions: positionsPath(positions),
3770
3863
  };
3771
3864
  };
3772
3865
  var useMaxQty = (symbol, side, reduceOnly = false) => {
3773
- const positions2 = usePositions();
3774
- const [orders] = useOrderStream({ status: OrderStatus.NEW, size: 500 });
3866
+ const positions3 = usePositions();
3775
3867
  const accountInfo = useAccountInfo();
3776
3868
  const symbolInfo = useSymbolsInfo();
3777
3869
  const { totalCollateral } = useCollateral();
@@ -3780,7 +3872,7 @@ var useMaxQty = (symbol, side, reduceOnly = false) => {
3780
3872
  if (!symbol)
3781
3873
  return 0;
3782
3874
  const positionQty = account.getQtyFromPositions(
3783
- positions2 === null ? [] : positions2,
3875
+ positions3 === null ? [] : positions3,
3784
3876
  symbol
3785
3877
  );
3786
3878
  if (reduceOnly) {
@@ -3800,28 +3892,16 @@ var useMaxQty = (symbol, side, reduceOnly = false) => {
3800
3892
  }
3801
3893
  return 0;
3802
3894
  }
3803
- if (!markPrices || !markPrices[symbol] || !orders || !accountInfo)
3895
+ if (!markPrices || !markPrices[symbol] || !accountInfo || !positions3)
3804
3896
  return 0;
3805
3897
  const getSymbolInfo = symbolInfo[symbol];
3806
- const filterAlgoOrders = orders.filter(
3807
- (item) => item.algo_order_id === void 0 || item.algo_type === "BRACKET"
3808
- );
3809
- const buyOrdersQty = account.getQtyFromOrdersBySide(
3810
- filterAlgoOrders,
3811
- symbol,
3812
- OrderSide.BUY
3813
- );
3814
- const sellOrdersQty = account.getQtyFromOrdersBySide(
3815
- filterAlgoOrders,
3816
- symbol,
3817
- OrderSide.SELL
3818
- );
3819
- const otherPositions = !Array.isArray(positions2) ? [] : positions2.filter((item) => item.symbol !== symbol);
3820
- const otherOrders = filterAlgoOrders.filter(
3821
- (item) => item.symbol !== symbol
3898
+ const currentSymbolPosition = positions3.find(
3899
+ (item) => item.symbol === symbol
3822
3900
  );
3901
+ const buyOrdersQty = currentSymbolPosition?.pending_long_qty ?? 0;
3902
+ const sellOrdersQty = currentSymbolPosition?.pending_short_qty ?? 0;
3903
+ const otherPositions = !Array.isArray(positions3) ? [] : positions3.filter((item) => item.symbol !== symbol);
3823
3904
  const otherIMs = account.otherIMs({
3824
- orders: otherOrders,
3825
3905
  positions: otherPositions,
3826
3906
  symbolInfo,
3827
3907
  markPrices,
@@ -3844,10 +3924,9 @@ var useMaxQty = (symbol, side, reduceOnly = false) => {
3844
3924
  });
3845
3925
  }, [
3846
3926
  symbol,
3847
- positions2,
3927
+ positions3,
3848
3928
  reduceOnly,
3849
3929
  markPrices,
3850
- orders,
3851
3930
  accountInfo,
3852
3931
  symbolInfo,
3853
3932
  side,
@@ -3856,9 +3935,8 @@ var useMaxQty = (symbol, side, reduceOnly = false) => {
3856
3935
  return Math.max(maxQty, 0);
3857
3936
  };
3858
3937
  var useMarginRatio = () => {
3859
- const positions2 = usePositionStore((state2) => state2.positions.all);
3860
- const { rows } = positions2;
3861
- const { notional } = positions2;
3938
+ const positions3 = usePositionStore((state2) => state2.positions.all);
3939
+ const { rows, notional } = positions3;
3862
3940
  const { state } = useAccount();
3863
3941
  const { data: markPrices } = useMarkPricesStream();
3864
3942
  const { totalCollateral } = useCollateral();
@@ -3879,8 +3957,9 @@ var useMarginRatio = () => {
3879
3957
  return null;
3880
3958
  }, [marginRatio, state.status]);
3881
3959
  const mmr = useMemo(() => {
3882
- if (!rows || rows.length <= 0 || notional == null)
3960
+ if (!rows || rows.length <= 0 || notional == null) {
3883
3961
  return null;
3962
+ }
3884
3963
  let positionsMM = zero;
3885
3964
  for (let index = 0; index < rows.length; index++) {
3886
3965
  const item = rows[index];
@@ -3899,7 +3978,8 @@ var TestNetWhiteList = [
3899
3978
  ARBITRUM_TESTNET_CHAINID,
3900
3979
  SOLANA_TESTNET_CHAINID,
3901
3980
  MONAD_TESTNET_CHAINID,
3902
- ABSTRACT_TESTNET_CHAINID
3981
+ ABSTRACT_TESTNET_CHAINID,
3982
+ BSC_TESTNET_CHAINID
3903
3983
  ];
3904
3984
  var testnetTokenFallback = TesntTokenFallback([
3905
3985
  ArbitrumSepoliaTokenInfo,
@@ -4165,7 +4245,7 @@ var useChain = (token) => {
4165
4245
  };
4166
4246
  var useHoldingStream = () => {
4167
4247
  const ws = useWS();
4168
- const { data, isLoading, mutate: mutate3 } = usePrivateQuery(
4248
+ const { data, isLoading, mutate: mutate5 } = usePrivateQuery(
4169
4249
  "/v1/client/holding",
4170
4250
  {
4171
4251
  formatter: (data2) => {
@@ -4189,14 +4269,17 @@ var useHoldingStream = () => {
4189
4269
  onMessage: (data2) => {
4190
4270
  const holding = data2?.balances ?? {};
4191
4271
  if (holding) {
4192
- mutate3((prevData) => {
4272
+ mutate5((prevData) => {
4193
4273
  return prevData?.map((item) => {
4194
4274
  const token = holding[item.token];
4195
- return {
4196
- ...item,
4197
- frozen: token.frozen,
4198
- holding: token.holding
4199
- };
4275
+ if (token) {
4276
+ return {
4277
+ ...item,
4278
+ frozen: token.frozen,
4279
+ holding: token.holding
4280
+ };
4281
+ }
4282
+ return item;
4200
4283
  });
4201
4284
  });
4202
4285
  next(holding);
@@ -4215,7 +4298,7 @@ var useHoldingStream = () => {
4215
4298
 
4216
4299
  // src/orderly/useWithdraw.ts
4217
4300
  var useWithdraw = (options) => {
4218
- const { account: account5, state } = useAccount();
4301
+ const { account: account7, state } = useAccount();
4219
4302
  const [isLoading, setIsLoading] = useState(false);
4220
4303
  const { unsettledPnL, availableBalance, freeCollateral } = useCollateral();
4221
4304
  const networkId = useConfig("networkId");
@@ -4261,10 +4344,11 @@ var useWithdraw = (options) => {
4261
4344
  }, [targetChain]);
4262
4345
  const withdraw = useCallback(
4263
4346
  (inputs) => {
4264
- return account5.assetsManager.withdraw(inputs).then((res) => {
4347
+ return account7.assetsManager.withdraw({ ...inputs, decimals: 6 }).then((res) => {
4265
4348
  if (res.success) {
4266
4349
  track2(TrackerEventName.withdrawSuccess, {
4267
4350
  wallet: state?.connectWallet?.name,
4351
+ // TODO: fix network name, befault is not pass srcChainId
4268
4352
  network: targetChain?.network_infos.name,
4269
4353
  quantity: inputs.amount
4270
4354
  });
@@ -4279,7 +4363,7 @@ var useWithdraw = (options) => {
4279
4363
  throw err;
4280
4364
  });
4281
4365
  },
4282
- [state, targetChain, state]
4366
+ [state, targetChain, state, options?.decimals]
4283
4367
  );
4284
4368
  return {
4285
4369
  dst,
@@ -4295,14 +4379,13 @@ var useDeposit = (options) => {
4295
4379
  const networkId = useConfig("networkId");
4296
4380
  const [balanceRevalidating, setBalanceRevalidating] = useState(false);
4297
4381
  const [allowanceRevalidating, setAllowanceRevalidating] = useState(false);
4298
- useEventEmitter();
4299
4382
  const [_, { findByChainId }] = useChains(void 0);
4300
4383
  const [quantity, setQuantity] = useState("");
4301
4384
  const [depositFee, setDepositFee] = useState(0n);
4302
4385
  const [depositFeeRevalidating, setDepositFeeRevalidating] = useState(false);
4303
4386
  const [balance, setBalance] = useState("0");
4304
4387
  const [allowance, setAllowance] = useState("0");
4305
- const { account: account5, state } = useAccount();
4388
+ const { account: account7, state } = useAccount();
4306
4389
  const { track: track2 } = useTrack();
4307
4390
  const prevAddress = useRef();
4308
4391
  const getBalanceListener = useRef();
@@ -4310,16 +4393,16 @@ var useDeposit = (options) => {
4310
4393
  let chain;
4311
4394
  if (networkId === "testnet") {
4312
4395
  chain = findByChainId(
4313
- isTestnet(options?.srcChainId) ? options?.srcChainId : ARBITRUM_TESTNET_CHAINID
4396
+ isTestnet(options.srcChainId) ? options.srcChainId : ARBITRUM_TESTNET_CHAINID
4314
4397
  );
4315
4398
  } else {
4316
- chain = findByChainId(options?.srcChainId);
4399
+ chain = findByChainId(options.srcChainId);
4317
4400
  if (!chain?.network_infos?.bridgeless) {
4318
4401
  chain = findByChainId(ARBITRUM_MAINNET_CHAINID);
4319
4402
  }
4320
4403
  }
4321
4404
  return chain;
4322
- }, [networkId, findByChainId, options?.srcChainId]);
4405
+ }, [networkId, findByChainId, options.srcChainId]);
4323
4406
  const dst = useMemo(() => {
4324
4407
  const USDC = targetChain?.token_infos.find(
4325
4408
  (token) => token.symbol === "USDC"
@@ -4333,18 +4416,18 @@ var useDeposit = (options) => {
4333
4416
  };
4334
4417
  }, [targetChain]);
4335
4418
  const isNativeToken = useMemo(
4336
- () => isNativeTokenChecker(options?.address || ""),
4337
- [options?.address]
4419
+ () => isNativeTokenChecker(options.address || ""),
4420
+ [options.address]
4338
4421
  );
4339
4422
  const fetchBalanceHandler = useCallback(
4340
4423
  async (address, decimals) => {
4341
4424
  let balance2;
4342
4425
  if (!!address && isNativeTokenChecker(address)) {
4343
- balance2 = await account5.assetsManager.getNativeBalance({
4426
+ balance2 = await account7.assetsManager.getNativeBalance({
4344
4427
  decimals
4345
4428
  });
4346
4429
  } else {
4347
- balance2 = await account5.assetsManager.getBalance(address, { decimals });
4430
+ balance2 = await account7.assetsManager.getBalance(address, { decimals });
4348
4431
  }
4349
4432
  return balance2;
4350
4433
  },
@@ -4370,7 +4453,7 @@ var useDeposit = (options) => {
4370
4453
  continue;
4371
4454
  }
4372
4455
  tasks.push(
4373
- account5.assetsManager.getBalanceByAddress(token.address, {
4456
+ account7.assetsManager.getBalanceByAddress(token.address, {
4374
4457
  decimals: token?.decimals
4375
4458
  })
4376
4459
  );
@@ -4387,7 +4470,7 @@ var useDeposit = (options) => {
4387
4470
  if (address && isNativeTokenChecker(address))
4388
4471
  return;
4389
4472
  prevAddress.current = key;
4390
- const allowance2 = await account5.assetsManager.getAllowance({
4473
+ const allowance2 = await account7.assetsManager.getAllowance({
4391
4474
  address,
4392
4475
  vaultAddress,
4393
4476
  decimals
@@ -4402,7 +4485,7 @@ var useDeposit = (options) => {
4402
4485
  if (!address || isNativeTokenChecker(address))
4403
4486
  return;
4404
4487
  prevAddress.current = address;
4405
- const allowance2 = await account5.assetsManager.getAllowance({
4488
+ const allowance2 = await account7.assetsManager.getAllowance({
4406
4489
  address,
4407
4490
  decimals
4408
4491
  });
@@ -4426,19 +4509,21 @@ var useDeposit = (options) => {
4426
4509
  if (state.status < AccountStatusEnum.Connected)
4427
4510
  return;
4428
4511
  setBalanceRevalidating(true);
4429
- queryBalance(options?.address, options?.decimals);
4512
+ queryBalance(options.address, options.decimals);
4430
4513
  const params = {
4431
- address: options?.address,
4432
- decimals: options?.decimals
4514
+ address: options.address,
4515
+ decimals: options.decimals
4433
4516
  };
4434
- if (account5.walletAdapter?.chainNamespace === ChainNamespace.solana) {
4435
- setAllowance(account5.walletAdapter.formatUnits(MaxUint256));
4517
+ if (account7.walletAdapter?.chainNamespace === ChainNamespace.solana) {
4518
+ setAllowance(
4519
+ account7.walletAdapter.formatUnits(MaxUint256, options.decimals)
4520
+ );
4436
4521
  return;
4437
4522
  }
4438
- if (dst.chainId !== options?.srcChainId) {
4523
+ if (dst.chainId !== options.srcChainId) {
4439
4524
  queryAllowance(params);
4440
4525
  } else {
4441
- if (dst.symbol !== options?.srcToken) {
4526
+ if (dst.symbol !== options.srcToken) {
4442
4527
  queryAllowance(params);
4443
4528
  } else {
4444
4529
  getAllowanceByDefaultAddress(params);
@@ -4446,54 +4531,60 @@ var useDeposit = (options) => {
4446
4531
  }
4447
4532
  }, [
4448
4533
  state.status,
4449
- options?.address,
4450
- options?.srcChainId,
4451
- options?.srcToken,
4452
- options?.decimals,
4453
- account5.address,
4534
+ options.address,
4535
+ options.srcChainId,
4536
+ options.srcToken,
4537
+ options.decimals,
4538
+ account7.address,
4454
4539
  dst.chainId,
4455
4540
  dst.symbol
4456
4541
  ]);
4457
4542
  const updateAllowanceWhenTxSuccess = useCallback(
4458
4543
  (txHash) => {
4459
- return account5.walletAdapter?.pollTransactionReceiptWithBackoff(txHash).then((receipt) => {
4544
+ return account7.walletAdapter?.pollTransactionReceiptWithBackoff(txHash).then((receipt) => {
4460
4545
  if (receipt.status === 1) {
4461
- account5.assetsManager.getAllowance({ address: options?.address }).then((allowance2) => {
4546
+ account7.assetsManager.getAllowance({ address: options.address }).then((allowance2) => {
4462
4547
  setAllowance(() => allowance2);
4463
4548
  });
4464
4549
  }
4465
4550
  });
4466
4551
  },
4467
- [account5, options?.address]
4552
+ [account7, options.address]
4468
4553
  );
4469
4554
  const approve = useCallback(
4470
4555
  async (amount) => {
4471
- if (!options?.address) {
4556
+ if (!options.address) {
4472
4557
  throw new SDKError("Address is required");
4473
4558
  }
4474
- return account5.assetsManager.approve({
4559
+ return account7.assetsManager.approve({
4475
4560
  address: options.address,
4476
- amount
4561
+ amount,
4562
+ decimals: options.decimals
4477
4563
  }).then((res) => {
4478
4564
  return updateAllowanceWhenTxSuccess(res.hash);
4479
4565
  }).catch((e) => {
4480
4566
  throw e;
4481
4567
  });
4482
4568
  },
4483
- [account5, getAllowance, options?.address, dst]
4569
+ [account7, getAllowance, options.address, options.decimals, dst]
4484
4570
  );
4485
4571
  const deposit = useCallback(async () => {
4486
- if (!options?.address) {
4572
+ if (!options.address) {
4487
4573
  throw new SDKError("Address is required");
4488
4574
  }
4489
- const _allowance = await account5.assetsManager.getAllowance({
4490
- address: options?.address
4575
+ const _allowance = await account7.assetsManager.getAllowance({
4576
+ address: options.address,
4577
+ decimals: options.decimals
4491
4578
  });
4492
4579
  setAllowance(() => _allowance);
4493
4580
  if (new Decimal(quantity).greaterThan(_allowance)) {
4494
4581
  throw new SDKError("Insufficient allowance");
4495
4582
  }
4496
- return account5.assetsManager.deposit(quantity, depositFee).then((res) => {
4583
+ return account7.assetsManager.deposit({
4584
+ amount: quantity,
4585
+ fee: depositFee,
4586
+ decimals: options.decimals
4587
+ }).then((res) => {
4497
4588
  track2(TrackerEventName.depositSuccess, {
4498
4589
  wallet: state?.connectWallet?.name,
4499
4590
  network: targetChain?.network_infos.name,
@@ -4510,15 +4601,22 @@ var useDeposit = (options) => {
4510
4601
  });
4511
4602
  throw e;
4512
4603
  });
4513
- }, [account5, fetchBalance, quantity, depositFee, options?.address]);
4604
+ }, [
4605
+ account7,
4606
+ fetchBalance,
4607
+ quantity,
4608
+ depositFee,
4609
+ options.address,
4610
+ options.decimals
4611
+ ]);
4514
4612
  const loopGetBalance = async () => {
4515
4613
  getBalanceListener.current && clearTimeout(getBalanceListener.current);
4516
- const time = account5.walletAdapter?.chainNamespace === ChainNamespace.solana ? 1e4 : 3e3;
4614
+ const time = account7.walletAdapter?.chainNamespace === ChainNamespace.solana ? 1e4 : 3e3;
4517
4615
  getBalanceListener.current = setTimeout(async () => {
4518
4616
  try {
4519
4617
  const balance2 = await fetchBalanceHandler(
4520
- options?.address,
4521
- options?.decimals
4618
+ options.address,
4619
+ options.decimals
4522
4620
  );
4523
4621
  setBalance(balance2);
4524
4622
  loopGetBalance();
@@ -4528,12 +4626,13 @@ var useDeposit = (options) => {
4528
4626
  };
4529
4627
  const getDepositFee = useCallback(
4530
4628
  async (quantity2) => {
4531
- return account5.assetsManager.getDepositFee(
4532
- quantity2,
4533
- targetChain?.network_infos
4534
- );
4629
+ return account7.assetsManager.getDepositFee({
4630
+ amount: quantity2,
4631
+ chain: targetChain?.network_infos,
4632
+ decimals: options.decimals
4633
+ });
4535
4634
  },
4536
- [account5, targetChain]
4635
+ [account7, targetChain, options.decimals]
4537
4636
  );
4538
4637
  const enquiryDepositFee = useCallback(() => {
4539
4638
  if (isNaN(Number(quantity)) || !quantity || Number(quantity) === 0) {
@@ -4556,14 +4655,14 @@ var useDeposit = (options) => {
4556
4655
  enquiryDepositFee();
4557
4656
  }, [quantity]);
4558
4657
  useEffect(() => {
4559
- if (!options?.address) {
4658
+ if (!options.address) {
4560
4659
  return;
4561
4660
  }
4562
4661
  loopGetBalance();
4563
4662
  return () => {
4564
4663
  getBalanceListener.current && clearTimeout(getBalanceListener.current);
4565
4664
  };
4566
- }, [options?.address, options?.decimals]);
4665
+ }, [options.address, options.decimals]);
4567
4666
  return {
4568
4667
  /** orderly support chain dst */
4569
4668
  dst,
@@ -4586,64 +4685,190 @@ var useDeposit = (options) => {
4586
4685
  setQuantity
4587
4686
  };
4588
4687
  };
4589
- var useWalletSubscription = (options) => {
4590
- const ws = useWS();
4591
- return useSWRSubscription("wallet", (_, { next }) => {
4592
- const unsubscribe = ws.privateSubscribe(
4593
- {
4594
- id: "wallet",
4595
- event: "subscribe",
4596
- topic: "wallet",
4597
- ts: Date.now()
4598
- },
4599
- {
4600
- onMessage: (data) => {
4601
- options?.onMessage?.(data);
4602
- next(null, data);
4603
- }
4604
- }
4605
- );
4606
- return () => unsubscribe();
4607
- });
4608
- };
4609
- var useSettleSubscription = (options) => {
4610
- const ws = useWS();
4611
- return useSWRSubscription("settle", (_, { next }) => {
4612
- const unsubscribe = ws.privateSubscribe(
4613
- {
4614
- id: "settle",
4615
- event: "subscribe",
4616
- topic: "settle",
4617
- ts: getTimestamp()
4618
- },
4619
- {
4620
- onMessage: (data) => {
4621
- options?.onMessage?.(data);
4622
- next(data);
4623
- }
4624
- }
4625
- );
4626
- return () => unsubscribe();
4627
- });
4628
- };
4629
- var useSymbolPriceRange = (symbol, side, price) => {
4630
- const config = useSymbolsInfo();
4631
- const priceRange = config?.[symbol]("price_range");
4632
- const priceScrope = config?.[symbol]("price_scope");
4633
- const { data: prices } = useMarkPricesStream();
4634
- const markPrice = price || prices?.[symbol];
4635
- const range = useMemo(() => {
4636
- if (config === void 0 || markPrice === void 0) {
4637
- return void 0;
4638
- }
4639
- if (priceRange === void 0 || Number.isNaN(markPrice)) {
4640
- return void 0;
4688
+ var fetcher3 = (url, options) => {
4689
+ const init2 = {
4690
+ method: options.arg.method,
4691
+ headers: {
4692
+ ...options.arg.signature
4641
4693
  }
4642
- if (side === "BUY") {
4643
- return {
4644
- max: new Decimal(markPrice).mul(1 + priceRange).toNumber(),
4645
- min: new Decimal(markPrice).mul(1 - priceScrope).toNumber()
4646
- };
4694
+ };
4695
+ if (options.arg.data) {
4696
+ init2.body = JSON.stringify(options.arg.data);
4697
+ }
4698
+ if (typeof options.arg.params === "object" && Object.keys(options.arg.params).length) {
4699
+ const search = new URLSearchParams(options.arg.params);
4700
+ url = `${url}?${search.toString()}`;
4701
+ }
4702
+ return mutate$1(url, init2);
4703
+ };
4704
+ var useSubAccountMutation = (url, method = "POST", options) => {
4705
+ const { accountId, ...restOptions } = options || {};
4706
+ const apiBaseUrl = useConfig("apiBaseUrl");
4707
+ let fullUrl = url;
4708
+ if (!url.startsWith("http")) {
4709
+ fullUrl = `${apiBaseUrl}${url}`;
4710
+ }
4711
+ const account7 = useAccountInstance();
4712
+ const { trigger, reset, data, error, isMutating } = useSWRMutation(
4713
+ fullUrl,
4714
+ // method === "POST" ? fetcher : deleteFetcher,
4715
+ fetcher3,
4716
+ restOptions
4717
+ );
4718
+ const mutation = useCallback(
4719
+ async (data2, params, options2) => {
4720
+ const { accountId: _accountId, ...restOptions2 } = options2 || {};
4721
+ let newUrl = url;
4722
+ if (typeof params === "object" && Object.keys(params).length) {
4723
+ const search = new URLSearchParams(params);
4724
+ newUrl = `${url}?${search.toString()}`;
4725
+ }
4726
+ const payload = {
4727
+ method,
4728
+ url: newUrl,
4729
+ data: data2
4730
+ };
4731
+ const signer = account7.signer;
4732
+ const signature = await signer.sign(payload, getTimestamp());
4733
+ return trigger(
4734
+ {
4735
+ data: data2,
4736
+ params,
4737
+ method,
4738
+ signature: {
4739
+ ...signature,
4740
+ "orderly-account-id": accountId || _accountId || account7.accountId
4741
+ }
4742
+ },
4743
+ restOptions2
4744
+ );
4745
+ },
4746
+ [trigger, account7, accountId]
4747
+ );
4748
+ return [
4749
+ mutation,
4750
+ {
4751
+ data,
4752
+ error,
4753
+ reset,
4754
+ isMutating
4755
+ }
4756
+ ];
4757
+ };
4758
+
4759
+ // src/orderly/useTransfer.ts
4760
+ var useTransfer = (options) => {
4761
+ const { fromAccountId } = options || {};
4762
+ const { unsettledPnL, availableBalance, freeCollateral, holding } = useCollateral();
4763
+ const [doTransfer, { isMutating: submitting }] = useSubAccountMutation(
4764
+ "/v1/internal_transfer",
4765
+ "POST",
4766
+ {
4767
+ accountId: fromAccountId
4768
+ }
4769
+ );
4770
+ const transfer = useCallback(
4771
+ async (token, receivers) => {
4772
+ return doTransfer({
4773
+ token,
4774
+ receiver_list: Array.isArray(receivers) ? receivers : [receivers]
4775
+ }).then((res) => {
4776
+ if (res.success) {
4777
+ return res;
4778
+ }
4779
+ throw res;
4780
+ }).catch((err) => {
4781
+ throw err;
4782
+ });
4783
+ },
4784
+ [doTransfer]
4785
+ );
4786
+ const maxAmount = useMemo(() => {
4787
+ return freeCollateral;
4788
+ }, [freeCollateral]);
4789
+ const availableTransfer = useMemo(() => {
4790
+ if (unsettledPnL < 0) {
4791
+ return freeCollateral;
4792
+ } else {
4793
+ return freeCollateral - unsettledPnL;
4794
+ }
4795
+ }, [freeCollateral, unsettledPnL]);
4796
+ return {
4797
+ submitting,
4798
+ transfer,
4799
+ maxAmount,
4800
+ unsettledPnL,
4801
+ availableBalance,
4802
+ availableTransfer,
4803
+ holding
4804
+ };
4805
+ };
4806
+ var useWalletSubscription = (options) => {
4807
+ const ws = useWS();
4808
+ const { state } = useAccount();
4809
+ return useSWRSubscription(
4810
+ state.accountId ? ["wallet", state.accountId] : null,
4811
+ (_, { next }) => {
4812
+ const unsubscribe = ws.privateSubscribe(
4813
+ {
4814
+ id: "wallet",
4815
+ event: "subscribe",
4816
+ topic: "wallet",
4817
+ ts: Date.now()
4818
+ },
4819
+ {
4820
+ onMessage: (data) => {
4821
+ options?.onMessage?.(data);
4822
+ next(null, data);
4823
+ }
4824
+ }
4825
+ );
4826
+ return () => unsubscribe();
4827
+ }
4828
+ );
4829
+ };
4830
+ var useSettleSubscription = (options) => {
4831
+ const ws = useWS();
4832
+ const { state } = useAccount();
4833
+ return useSWRSubscription(
4834
+ state.accountId ? ["settle", state.accountId] : null,
4835
+ (_, { next }) => {
4836
+ const unsubscribe = ws.privateSubscribe(
4837
+ {
4838
+ id: "settle",
4839
+ event: "subscribe",
4840
+ topic: "settle",
4841
+ ts: getTimestamp()
4842
+ },
4843
+ {
4844
+ onMessage: (data) => {
4845
+ options?.onMessage?.(data);
4846
+ next(data);
4847
+ }
4848
+ }
4849
+ );
4850
+ return () => unsubscribe();
4851
+ }
4852
+ );
4853
+ };
4854
+ var useSymbolPriceRange = (symbol, side, price) => {
4855
+ const config = useSymbolsInfo();
4856
+ const priceRange = config?.[symbol]("price_range");
4857
+ const priceScrope = config?.[symbol]("price_scope");
4858
+ const { data: prices } = useMarkPricesStream();
4859
+ const markPrice = price || prices?.[symbol];
4860
+ const range = useMemo(() => {
4861
+ if (config === void 0 || markPrice === void 0) {
4862
+ return void 0;
4863
+ }
4864
+ if (priceRange === void 0 || Number.isNaN(markPrice)) {
4865
+ return void 0;
4866
+ }
4867
+ if (side === "BUY") {
4868
+ return {
4869
+ max: new Decimal(markPrice).mul(1 + priceRange).toNumber(),
4870
+ min: new Decimal(markPrice).mul(1 - priceScrope).toNumber()
4871
+ };
4647
4872
  }
4648
4873
  return {
4649
4874
  max: new Decimal(markPrice).mul(1 + priceScrope).toNumber(),
@@ -4652,357 +4877,114 @@ var useSymbolPriceRange = (symbol, side, price) => {
4652
4877
  }, [symbol, side, priceRange, markPrice]);
4653
4878
  return range;
4654
4879
  };
4655
- function offsetToPrice(inputs) {
4656
- const { offset, entryPrice, orderType, orderSide } = inputs;
4657
- if (!offset)
4658
- return;
4659
- if (orderSide === OrderSide.BUY) {
4660
- if (orderType === AlgoOrderType.TAKE_PROFIT) {
4661
- return new Decimal(entryPrice).add(new Decimal(offset)).toNumber();
4880
+ function getMinNotional(props) {
4881
+ const { price, base_tick, qty, min_notional, base_dp, quote_dp, quote_tick } = props;
4882
+ if (price !== void 0 && qty !== void 0 && min_notional !== void 0) {
4883
+ try {
4884
+ const calcNotional = new Decimal(price).mul(new Decimal(qty)).toNumber();
4885
+ const notional = Number.parseFloat(`${min_notional}`);
4886
+ if (calcNotional < notional) {
4887
+ let minQty = new Decimal(notional).div(price).toDecimalPlaces(base_dp, Decimal.ROUND_DOWN).add(base_tick ?? 0);
4888
+ if (base_tick && base_tick > 0) {
4889
+ minQty = new Decimal(
4890
+ getRoundedDownDivision(minQty.toNumber(), base_tick)
4891
+ );
4892
+ }
4893
+ const newMinNotional = minQty.mul(price).add(quote_tick ?? 0).toFixed(quote_dp);
4894
+ return newMinNotional;
4895
+ }
4896
+ } catch (e) {
4662
4897
  }
4663
- return new Decimal(entryPrice).minus(new Decimal(offset)).toNumber();
4664
4898
  }
4665
- if (orderSide === OrderSide.SELL) {
4666
- if (orderType === AlgoOrderType.TAKE_PROFIT) {
4667
- return new Decimal(entryPrice).minus(new Decimal(offset)).toNumber();
4899
+ }
4900
+ function checkNotional(props) {
4901
+ const { price, base_tick, qty, min_notional, base_dp, quote_dp, quote_tick } = props;
4902
+ if (price !== void 0 && qty !== void 0 && min_notional !== void 0) {
4903
+ try {
4904
+ const calcNotional = new Decimal(price).mul(new Decimal(qty)).toNumber();
4905
+ const notional = Number.parseFloat(`${min_notional}`);
4906
+ if (calcNotional < notional) {
4907
+ let minQty = new Decimal(notional).div(price).toDecimalPlaces(base_dp, Decimal.ROUND_DOWN).add(base_tick ?? 0);
4908
+ if (base_tick && base_tick > 0) {
4909
+ minQty = new Decimal(
4910
+ getRoundedDownDivision(minQty.toNumber(), base_tick)
4911
+ );
4912
+ }
4913
+ const newMinNotional = minQty.mul(price).add(quote_tick ?? 0).toFixed(quote_dp);
4914
+ return `The order value should be greater or equal to ${newMinNotional} USDC`;
4915
+ }
4916
+ return void 0;
4917
+ } catch (e) {
4918
+ return void 0;
4668
4919
  }
4669
- return new Decimal(entryPrice).add(new Decimal(offset)).toNumber();
4670
4920
  }
4921
+ return void 0;
4671
4922
  }
4672
- function priceToOffset(inputs, options = {}) {
4673
- const { price, entryPrice, orderType, orderSide } = inputs;
4674
- const { symbol } = options;
4675
- let decimal;
4676
- if (orderSide === OrderSide.BUY) {
4677
- if (orderType === AlgoOrderType.TAKE_PROFIT) {
4678
- decimal = new Decimal(price).minus(new Decimal(entryPrice));
4923
+ function getRoundedDownDivision(value, tick) {
4924
+ const decimalValue = new Decimal(value);
4925
+ const decimalTick = new Decimal(tick);
4926
+ const quotient = decimalValue.dividedToIntegerBy(decimalTick);
4927
+ return quotient.mul(decimalTick).toNumber();
4928
+ }
4929
+
4930
+ // src/services/orderCreator/orderValidation.ts
4931
+ var OrderValidation = class {
4932
+ static getLabel(key) {
4933
+ switch (key) {
4934
+ case "quantity":
4935
+ case "order_quantity":
4936
+ return "Quantity";
4937
+ case "order_price":
4938
+ return "Price";
4939
+ case "trigger_price":
4940
+ return "Trigger price";
4941
+ case "tp_trigger_price":
4942
+ return "TP price";
4943
+ case "sl_trigger_price":
4944
+ return "SL price";
4945
+ default:
4946
+ return key;
4679
4947
  }
4680
- decimal = new Decimal(price).minus(new Decimal(entryPrice));
4681
4948
  }
4682
- if (orderSide === OrderSide.SELL) {
4683
- if (orderType === AlgoOrderType.TAKE_PROFIT) {
4684
- decimal = new Decimal(price).minus(new Decimal(entryPrice));
4685
- }
4686
- decimal = new Decimal(entryPrice).minus(new Decimal(price));
4949
+ static required(key) {
4950
+ return {
4951
+ type: "required",
4952
+ message: `${this.getLabel(key)} is required`
4953
+ };
4687
4954
  }
4688
- if (symbol) {
4689
- return decimal.abs().todp(symbol.quote_dp, Decimal.ROUND_UP).toNumber();
4955
+ static min(key, value) {
4956
+ return {
4957
+ type: "min",
4958
+ message: `${this.getLabel(key)} must be greater than ${value}`,
4959
+ value
4960
+ };
4690
4961
  }
4691
- return decimal.abs().toNumber();
4692
- }
4693
- function offsetPercentageToPrice(inputs) {
4694
- const { percentage, entryPrice, orderType, orderSide } = inputs;
4695
- if (!percentage)
4696
- return;
4697
- if (orderSide === OrderSide.BUY) {
4698
- if (orderType === AlgoOrderType.TAKE_PROFIT) {
4699
- return new Decimal(1).add(new Decimal(percentage)).mul(new Decimal(entryPrice)).toNumber();
4700
- }
4701
- return new Decimal(1).minus(new Decimal(percentage)).mul(new Decimal(entryPrice)).toNumber();
4962
+ static max(key, value) {
4963
+ return {
4964
+ type: "max",
4965
+ message: `${this.getLabel(key)} must be less than ${value}`,
4966
+ value
4967
+ };
4702
4968
  }
4703
- if (orderSide === OrderSide.SELL) {
4704
- if (orderType === AlgoOrderType.TAKE_PROFIT) {
4705
- return new Decimal(1).minus(new Decimal(percentage)).mul(new Decimal(entryPrice)).toNumber();
4969
+ };
4970
+
4971
+ // src/services/orderCreator/baseCreator.ts
4972
+ var BaseOrderCreator = class {
4973
+ baseOrder(data) {
4974
+ const order = {
4975
+ symbol: data.symbol,
4976
+ order_type: data.order_type === OrderType.LIMIT ? !!data.order_type_ext ? data.order_type_ext : data.order_type : data.order_type,
4977
+ side: data.side,
4978
+ reduce_only: data.reduce_only,
4979
+ order_quantity: data.order_quantity,
4980
+ total: data.total
4981
+ // slippage: data.slippage,
4982
+ };
4983
+ if (data.order_type === OrderType.MARKET && !!data.slippage) {
4984
+ order.slippage = new Decimal(data.slippage).div(100).toNumber();
4706
4985
  }
4707
- return new Decimal(1).add(new Decimal(percentage)).mul(new Decimal(entryPrice)).toNumber();
4708
- }
4709
- }
4710
- function priceToOffsetPercentage(inputs) {
4711
- const { price, entryPrice, orderType, orderSide } = inputs;
4712
- if (orderSide === OrderSide.BUY) {
4713
- if (entryPrice === 0)
4714
- return 0;
4715
- if (orderType === AlgoOrderType.TAKE_PROFIT) {
4716
- return new Decimal(price).div(new Decimal(entryPrice)).minus(1).toDecimalPlaces(4, Decimal.ROUND_DOWN).toNumber();
4717
- }
4718
- return new Decimal(1).minus(new Decimal(price).div(new Decimal(entryPrice))).toDecimalPlaces(4, Decimal.ROUND_DOWN).toNumber();
4719
- }
4720
- if (orderSide === OrderSide.SELL) {
4721
- if (entryPrice === 0)
4722
- return 0;
4723
- if (orderType === AlgoOrderType.TAKE_PROFIT) {
4724
- return new Decimal(1).minus(new Decimal(price).div(new Decimal(entryPrice))).abs().toDecimalPlaces(4, Decimal.ROUND_DOWN).toNumber();
4725
- }
4726
- return new Decimal(price).div(new Decimal(entryPrice)).minus(1).toDecimalPlaces(4, Decimal.ROUND_DOWN).toNumber();
4727
- }
4728
- }
4729
- function pnlToPrice(inputs) {
4730
- const { qty, pnl, entryPrice, orderType, orderSide } = inputs;
4731
- if (!pnl) {
4732
- return;
4733
- }
4734
- if (qty === 0)
4735
- return;
4736
- if (orderSide === OrderSide.BUY) {
4737
- if (orderType === AlgoOrderType.TAKE_PROFIT) {
4738
- return new Decimal(entryPrice).plus(new Decimal(pnl).div(new Decimal(qty))).toNumber();
4739
- }
4740
- return new Decimal(entryPrice).add(new Decimal(pnl).div(new Decimal(qty))).toNumber();
4741
- }
4742
- if (orderSide === OrderSide.SELL) {
4743
- if (orderType === AlgoOrderType.TAKE_PROFIT) {
4744
- return new Decimal(entryPrice).add(new Decimal(pnl).div(new Decimal(qty))).toNumber();
4745
- }
4746
- return new Decimal(entryPrice).add(new Decimal(pnl).div(new Decimal(qty))).toNumber();
4747
- }
4748
- }
4749
- function priceToPnl(inputs, options = {}) {
4750
- const { qty, price, entryPrice, orderType, orderSide } = inputs;
4751
- const { symbol } = options;
4752
- let decimal = zero;
4753
- if (orderSide === OrderSide.BUY) {
4754
- if (orderType === AlgoOrderType.TAKE_PROFIT) {
4755
- decimal = new Decimal(qty).mul(
4756
- new Decimal(price).minus(new Decimal(entryPrice))
4757
- );
4758
- }
4759
- decimal = new Decimal(qty).mul(
4760
- new Decimal(price).minus(new Decimal(entryPrice))
4761
- );
4762
- }
4763
- if (orderSide === OrderSide.SELL) {
4764
- if (orderType === AlgoOrderType.TAKE_PROFIT) {
4765
- decimal = new Decimal(qty).mul(
4766
- new Decimal(price).minus(new Decimal(entryPrice))
4767
- );
4768
- }
4769
- decimal = new Decimal(qty).mul(
4770
- new Decimal(price).minus(new Decimal(entryPrice))
4771
- );
4772
- }
4773
- if (symbol) {
4774
- return decimal.todp(2, Decimal.ROUND_DOWN).toNumber();
4775
- }
4776
- return decimal.toNumber();
4777
- }
4778
- function calcTPSL_ROI(inputs) {
4779
- const qtyNum = Number(inputs.qty);
4780
- const priceNum = Number(inputs.price);
4781
- if (qtyNum === 0 || priceNum === 0)
4782
- return "0";
4783
- return new Decimal(inputs.pnl).div(new Decimal(qtyNum).abs().mul(new Decimal(priceNum))).toString();
4784
- }
4785
- function tpslCalculateHelper(key, inputs, options = {}) {
4786
- const { symbol } = options;
4787
- if (key !== "quantity" && key !== "tp_trigger_price" && key !== "sl_trigger_price" && key !== "tp_pnl" && key !== "sl_pnl" && key !== "tp_offset" && key !== "sl_offset" && key !== "tp_offset_percentage" && key !== "sl_offset_percentage") {
4788
- return {
4789
- [key]: inputs.value
4790
- };
4791
- }
4792
- const orderType = key.startsWith("tp_") ? AlgoOrderType.TAKE_PROFIT : AlgoOrderType.STOP_LOSS;
4793
- const keyPrefix = key.slice(0, 3);
4794
- let qty = Number(key === "quantity" ? inputs.value : inputs.qty);
4795
- if (qty === 0 && (key === "tp_pnl" || key === "sl_pnl" || key === "tp_trigger_price" || key === "sl_trigger_price")) {
4796
- return {
4797
- [`${keyPrefix}trigger_price`]: "",
4798
- // [`${keyPrefix}offset`]: "",
4799
- // [`${keyPrefix}offset_percentage`]: "",
4800
- [`${keyPrefix}pnl`]: "",
4801
- [key]: inputs.value
4802
- };
4803
- }
4804
- let trigger_price, offset, offset_percentage, pnl;
4805
- const entryPrice = new Decimal(inputs.entryPrice).todp(options.symbol?.quote_dp ?? 2, Decimal.ROUND_UP).toNumber();
4806
- switch (key) {
4807
- case "tp_trigger_price":
4808
- case "sl_trigger_price": {
4809
- trigger_price = inputs.value;
4810
- if (inputs.value === "") {
4811
- return {
4812
- [`${keyPrefix}trigger_price`]: trigger_price,
4813
- [`${keyPrefix}offset`]: "",
4814
- [`${keyPrefix}offset_percentage`]: "",
4815
- [`${keyPrefix}pnl`]: "",
4816
- [`${keyPrefix}ROI`]: ""
4817
- };
4818
- }
4819
- break;
4820
- }
4821
- case "tp_pnl":
4822
- case "sl_pnl": {
4823
- pnl = inputs.value;
4824
- trigger_price = pnlToPrice({
4825
- qty,
4826
- pnl: Number(inputs.value),
4827
- entryPrice,
4828
- orderSide: inputs.orderSide,
4829
- orderType
4830
- });
4831
- break;
4832
- }
4833
- case "tp_offset":
4834
- case "sl_offset": {
4835
- offset = inputs.value;
4836
- trigger_price = offsetToPrice({
4837
- offset: Number(inputs.value),
4838
- entryPrice,
4839
- orderSide: inputs.orderSide,
4840
- orderType: key === "tp_offset" ? AlgoOrderType.TAKE_PROFIT : AlgoOrderType.STOP_LOSS
4841
- });
4842
- break;
4843
- }
4844
- case "tp_offset_percentage":
4845
- case "sl_offset_percentage": {
4846
- offset_percentage = inputs.value;
4847
- trigger_price = offsetPercentageToPrice({
4848
- percentage: Number(`${inputs.value}`.replace(/\.0{0,2}$/, "")),
4849
- entryPrice,
4850
- orderSide: inputs.orderSide,
4851
- orderType
4852
- });
4853
- break;
4854
- }
4855
- }
4856
- if (!trigger_price)
4857
- return {
4858
- [`${keyPrefix}trigger_price`]: "",
4859
- [`${keyPrefix}offset`]: "",
4860
- [`${keyPrefix}offset_percentage`]: "",
4861
- [`${keyPrefix}pnl`]: "",
4862
- [`${keyPrefix}ROI`]: "",
4863
- [key]: inputs.value
4864
- };
4865
- return {
4866
- [`${keyPrefix}trigger_price`]: todpIfNeed(
4867
- trigger_price,
4868
- symbol?.quote_dp ?? 2
4869
- ),
4870
- [`${keyPrefix}offset`]: offset ?? priceToOffset(
4871
- {
4872
- price: Number(trigger_price),
4873
- entryPrice,
4874
- orderSide: inputs.orderSide,
4875
- orderType
4876
- },
4877
- options
4878
- ),
4879
- [`${keyPrefix}offset_percentage`]: offset_percentage ?? priceToOffsetPercentage({
4880
- price: Number(trigger_price),
4881
- entryPrice,
4882
- orderSide: inputs.orderSide,
4883
- orderType
4884
- }),
4885
- [`${keyPrefix}pnl`]: pnl ?? priceToPnl(
4886
- {
4887
- qty,
4888
- price: Number(trigger_price),
4889
- entryPrice,
4890
- orderSide: inputs.orderSide,
4891
- orderType
4892
- },
4893
- options
4894
- )
4895
- // [`${keyPrefix}ROI`]: calcROI({
4896
- // pnl: Number(pnl ?? 0),
4897
- // qty,
4898
- // price: Number(trigger_price!),
4899
- // }),
4900
- };
4901
- }
4902
- function getMinNotional(props) {
4903
- const { price, base_tick, qty, min_notional, base_dp, quote_dp, quote_tick } = props;
4904
- if (price !== void 0 && qty !== void 0 && min_notional !== void 0) {
4905
- try {
4906
- const calcNotional = new Decimal(price).mul(new Decimal(qty)).toNumber();
4907
- const notional = Number.parseFloat(`${min_notional}`);
4908
- if (calcNotional < notional) {
4909
- let minQty = new Decimal(notional).div(price).toDecimalPlaces(base_dp, Decimal.ROUND_DOWN).add(base_tick ?? 0);
4910
- if (base_tick && base_tick > 0) {
4911
- minQty = new Decimal(
4912
- getRoundedDownDivision(minQty.toNumber(), base_tick)
4913
- );
4914
- }
4915
- const newMinNotional = minQty.mul(price).add(quote_tick ?? 0).toFixed(quote_dp);
4916
- return newMinNotional;
4917
- }
4918
- } catch (e) {
4919
- }
4920
- }
4921
- }
4922
- function checkNotional(props) {
4923
- const { price, base_tick, qty, min_notional, base_dp, quote_dp, quote_tick } = props;
4924
- if (price !== void 0 && qty !== void 0 && min_notional !== void 0) {
4925
- try {
4926
- const calcNotional = new Decimal(price).mul(new Decimal(qty)).toNumber();
4927
- const notional = Number.parseFloat(`${min_notional}`);
4928
- if (calcNotional < notional) {
4929
- let minQty = new Decimal(notional).div(price).toDecimalPlaces(base_dp, Decimal.ROUND_DOWN).add(base_tick ?? 0);
4930
- if (base_tick && base_tick > 0) {
4931
- minQty = new Decimal(
4932
- getRoundedDownDivision(minQty.toNumber(), base_tick)
4933
- );
4934
- }
4935
- const newMinNotional = minQty.mul(price).add(quote_tick ?? 0).toFixed(quote_dp);
4936
- return `The order value should be greater or equal to ${newMinNotional} USDC`;
4937
- }
4938
- return void 0;
4939
- } catch (e) {
4940
- return void 0;
4941
- }
4942
- }
4943
- return void 0;
4944
- }
4945
- function getRoundedDownDivision(value, tick) {
4946
- const decimalValue = new Decimal(value);
4947
- const decimalTick = new Decimal(tick);
4948
- const quotient = decimalValue.dividedToIntegerBy(decimalTick);
4949
- return quotient.mul(decimalTick).toNumber();
4950
- }
4951
-
4952
- // src/services/orderCreator/orderValidation.ts
4953
- var OrderValidation = class {
4954
- static getLabel(key) {
4955
- switch (key) {
4956
- case "quantity":
4957
- case "order_quantity":
4958
- return "Quantity";
4959
- case "order_price":
4960
- return "Price";
4961
- case "trigger_price":
4962
- return "Trigger price";
4963
- case "tp_trigger_price":
4964
- return "TP price";
4965
- case "sl_trigger_price":
4966
- return "SL price";
4967
- default:
4968
- return key;
4969
- }
4970
- }
4971
- static required(key) {
4972
- return {
4973
- type: "required",
4974
- message: `${this.getLabel(key)} is required`
4975
- };
4976
- }
4977
- static min(key, value) {
4978
- return {
4979
- type: "min",
4980
- message: `${this.getLabel(key)} must be greater than ${value}`,
4981
- value
4982
- };
4983
- }
4984
- static max(key, value) {
4985
- return {
4986
- type: "max",
4987
- message: `${this.getLabel(key)} must be less than ${value}`,
4988
- value
4989
- };
4990
- }
4991
- };
4992
-
4993
- // src/services/orderCreator/baseCreator.ts
4994
- var BaseOrderCreator = class {
4995
- baseOrder(data) {
4996
- const order = {
4997
- symbol: data.symbol,
4998
- order_type: data.order_type === OrderType.LIMIT ? !!data.order_type_ext ? data.order_type_ext : data.order_type : data.order_type,
4999
- side: data.side,
5000
- reduce_only: data.reduce_only,
5001
- order_quantity: data.order_quantity,
5002
- total: data.total
5003
- };
5004
- if (data.visible_quantity === 0) {
5005
- order.visible_quantity = data.visible_quantity;
4986
+ if (data.visible_quantity === 0) {
4987
+ order.visible_quantity = data.visible_quantity;
5006
4988
  }
5007
4989
  const bracketOrder = this.parseBracketOrder(data);
5008
4990
  if (!bracketOrder) {
@@ -5199,7 +5181,21 @@ var MarketOrderCreator = class extends BaseOrderCreator {
5199
5181
  };
5200
5182
  }
5201
5183
  validate(values2, configs) {
5202
- return this.baseValidate(values2, configs);
5184
+ return this.baseValidate(values2, configs).then((result) => {
5185
+ const slippage = Number(values2.slippage);
5186
+ const estSlippage = Number.isNaN(configs.estSlippage) ? 0 : Number(configs.estSlippage) * 100;
5187
+ if (!isNaN(slippage) && estSlippage > slippage) {
5188
+ return {
5189
+ ...result,
5190
+ slippage: {
5191
+ type: "max",
5192
+ message: "Estimated slippage exceeds your maximum allowed slippage.",
5193
+ value: estSlippage
5194
+ }
5195
+ };
5196
+ }
5197
+ return result;
5198
+ });
5203
5199
  }
5204
5200
  };
5205
5201
  var { maxPrice, minPrice, scopePrice } = order;
@@ -5567,17 +5563,102 @@ var TPSLOrderCreator = class extends BaseAlgoOrderCreator {
5567
5563
  algo_type: AlgoOrderType.STOP_LOSS,
5568
5564
  reduce_only: true,
5569
5565
  side,
5570
- type: OrderType.MARKET,
5566
+ type: OrderType.MARKET,
5567
+ trigger_price: sl_trigger_price,
5568
+ symbol: values2.symbol,
5569
+ is_activated: !!values2.sl_trigger_price
5570
+ });
5571
+ }
5572
+ return {
5573
+ algo_type: AlgoOrderRootType.TP_SL,
5574
+ trigger_price_type: TriggerPriceType.MARK_PRICE,
5575
+ reduce_only: true,
5576
+ quantity: values2.quantity,
5577
+ symbol: values2.symbol,
5578
+ child_orders
5579
+ };
5580
+ }
5581
+ crateUpdateOrder(values2, oldValue, config) {
5582
+ const data = this.create(values2, config);
5583
+ const newData = [];
5584
+ const needUpdateQty = values2.quantity !== oldValue.quantity;
5585
+ data.child_orders.forEach((order) => {
5586
+ let _order = /* @__PURE__ */ Object.create(null);
5587
+ if (needUpdateQty) {
5588
+ _order["quantity"] = data.quantity;
5589
+ }
5590
+ const oldOrder = oldValue.child_orders?.find(
5591
+ (oldOrder2) => oldOrder2.algo_type === order.algo_type
5592
+ );
5593
+ if (oldOrder) {
5594
+ if (!order.is_activated) {
5595
+ _order["is_activated"] = false;
5596
+ } else if (oldOrder.trigger_price !== order.trigger_price) {
5597
+ _order["trigger_price"] = order.trigger_price;
5598
+ }
5599
+ if (Object.keys(_order).length > 0) {
5600
+ _order["order_id"] = Number(oldOrder.algo_order_id);
5601
+ newData.push(_order);
5602
+ }
5603
+ }
5604
+ });
5605
+ if (needUpdateQty && newData.length < 2) {
5606
+ const missingOrders = oldValue.child_orders.filter(
5607
+ (order) => order.algo_order_id !== newData[0].order_id
5608
+ );
5609
+ if (missingOrders.length) {
5610
+ newData.push({
5611
+ quantity: Number(data.quantity),
5612
+ order_id: missingOrders[0].algo_order_id
5613
+ });
5614
+ }
5615
+ }
5616
+ return [
5617
+ {
5618
+ child_orders: newData
5619
+ },
5620
+ data
5621
+ ];
5622
+ }
5623
+ };
5624
+ var TPSLPositionOrderCreator = class extends BaseAlgoOrderCreator {
5625
+ constructor() {
5626
+ super(...arguments);
5627
+ this.type = AlgoOrderRootType.POSITIONAL_TP_SL;
5628
+ }
5629
+ create(values2, config) {
5630
+ const side = values2.side === OrderSide.BUY ? OrderSide.SELL : OrderSide.BUY;
5631
+ const child_orders = [];
5632
+ if (typeof values2.tp_trigger_price !== "undefined") {
5633
+ const tp_trigger_price = !!values2.tp_trigger_price ? new Decimal(values2.tp_trigger_price).todp(config.symbol.quote_dp).toNumber() : values2.tp_trigger_price;
5634
+ child_orders.push({
5635
+ algo_type: AlgoOrderType.TAKE_PROFIT,
5636
+ reduce_only: true,
5637
+ side,
5638
+ type: OrderType.CLOSE_POSITION,
5639
+ trigger_price: tp_trigger_price,
5640
+ trigger_price_type: TriggerPriceType.MARK_PRICE,
5641
+ symbol: values2.symbol,
5642
+ is_activated: !!values2.tp_trigger_price
5643
+ });
5644
+ }
5645
+ if (typeof values2.sl_trigger_price !== "undefined") {
5646
+ const sl_trigger_price = !!values2.sl_trigger_price ? new Decimal(values2.sl_trigger_price).todp(config.symbol.quote_dp).toNumber() : values2.sl_trigger_price;
5647
+ child_orders.push({
5648
+ algo_type: AlgoOrderType.STOP_LOSS,
5649
+ reduce_only: true,
5650
+ side,
5651
+ type: OrderType.CLOSE_POSITION,
5571
5652
  trigger_price: sl_trigger_price,
5653
+ trigger_price_type: TriggerPriceType.MARK_PRICE,
5572
5654
  symbol: values2.symbol,
5573
5655
  is_activated: !!values2.sl_trigger_price
5574
5656
  });
5575
5657
  }
5576
5658
  return {
5577
- algo_type: AlgoOrderRootType.TP_SL,
5659
+ algo_type: AlgoOrderRootType.POSITIONAL_TP_SL,
5578
5660
  trigger_price_type: TriggerPriceType.MARK_PRICE,
5579
- reduce_only: true,
5580
- quantity: values2.quantity,
5661
+ // reduce_only: true,
5581
5662
  symbol: values2.symbol,
5582
5663
  child_orders
5583
5664
  };
@@ -5585,38 +5666,24 @@ var TPSLOrderCreator = class extends BaseAlgoOrderCreator {
5585
5666
  crateUpdateOrder(values2, oldValue, config) {
5586
5667
  const data = this.create(values2, config);
5587
5668
  const newData = [];
5588
- const needUpdateQty = values2.quantity !== oldValue.quantity;
5589
5669
  data.child_orders.forEach((order) => {
5590
- let _order = /* @__PURE__ */ Object.create(null);
5591
- if (needUpdateQty) {
5592
- _order["quantity"] = data.quantity;
5593
- }
5594
5670
  const oldOrder = oldValue.child_orders?.find(
5595
5671
  (oldOrder2) => oldOrder2.algo_type === order.algo_type
5596
5672
  );
5597
5673
  if (oldOrder) {
5598
5674
  if (!order.is_activated) {
5599
- _order["is_activated"] = false;
5675
+ newData.push({
5676
+ is_activated: false,
5677
+ order_id: Number(oldOrder.algo_order_id)
5678
+ });
5600
5679
  } else if (oldOrder.trigger_price !== order.trigger_price) {
5601
- _order["trigger_price"] = order.trigger_price;
5602
- }
5603
- if (Object.keys(_order).length > 0) {
5604
- _order["order_id"] = Number(oldOrder.algo_order_id);
5605
- newData.push(_order);
5680
+ newData.push({
5681
+ trigger_price: order.trigger_price,
5682
+ order_id: Number(oldOrder.algo_order_id)
5683
+ });
5606
5684
  }
5607
5685
  }
5608
5686
  });
5609
- if (needUpdateQty && newData.length < 2) {
5610
- const missingOrders = oldValue.child_orders.filter(
5611
- (order) => order.algo_order_id !== newData[0].order_id
5612
- );
5613
- if (missingOrders.length) {
5614
- newData.push({
5615
- quantity: Number(data.quantity),
5616
- order_id: missingOrders[0].algo_order_id
5617
- });
5618
- }
5619
- }
5620
5687
  return [
5621
5688
  {
5622
5689
  child_orders: newData
@@ -5624,271 +5691,827 @@ var TPSLOrderCreator = class extends BaseAlgoOrderCreator {
5624
5691
  data
5625
5692
  ];
5626
5693
  }
5627
- };
5628
- var TPSLPositionOrderCreator = class extends BaseAlgoOrderCreator {
5629
- constructor() {
5630
- super(...arguments);
5631
- this.type = AlgoOrderRootType.POSITIONAL_TP_SL;
5694
+ };
5695
+ async function bracketOrderValidator(values2, config) {
5696
+ const result = /* @__PURE__ */ Object.create(null);
5697
+ await Promise.resolve();
5698
+ const { tp_trigger_price, sl_trigger_price, side } = values2;
5699
+ const qty = Number(values2.quantity);
5700
+ const maxQty = config.maxQty;
5701
+ const type = values2.order_type;
5702
+ const { quote_max, quote_min, price_scope, quote_dp } = config.symbol ?? {};
5703
+ const mark_price = type === OrderType.MARKET ? config.markPrice : values2.order_price ? Number(values2.order_price) : void 0;
5704
+ if (!isNaN(qty) && qty > maxQty) {
5705
+ result.quantity = OrderValidation.max("quantity", config.maxQty);
5706
+ }
5707
+ if (Number(tp_trigger_price) < 0) {
5708
+ result.tp_trigger_price = OrderValidation.min("tp_trigger_price", 0);
5709
+ }
5710
+ if (Number(sl_trigger_price) < 0) {
5711
+ result.sl_trigger_price = OrderValidation.min("sl_trigger_price", 0);
5712
+ }
5713
+ if (side === OrderSide.BUY && mark_price) {
5714
+ const slTriggerPriceScope = new Decimal(mark_price * (1 - price_scope)).toDecimalPlaces(quote_dp, Decimal.ROUND_DOWN).toNumber();
5715
+ if (!!sl_trigger_price && Number(sl_trigger_price) < slTriggerPriceScope) {
5716
+ result.sl_trigger_price = OrderValidation.min(
5717
+ "sl_trigger_price",
5718
+ slTriggerPriceScope
5719
+ );
5720
+ }
5721
+ if (!!tp_trigger_price && Number(tp_trigger_price) <= mark_price) {
5722
+ result.tp_trigger_price = OrderValidation.min(
5723
+ "tp_trigger_price",
5724
+ mark_price
5725
+ );
5726
+ }
5727
+ if (!!tp_trigger_price && Number(tp_trigger_price) > quote_max) {
5728
+ result.tp_trigger_price = OrderValidation.max(
5729
+ "tp_trigger_price",
5730
+ quote_max
5731
+ );
5732
+ }
5733
+ if (!!sl_trigger_price && Number(sl_trigger_price) < quote_min) {
5734
+ result.sl_trigger_price = OrderValidation.min(
5735
+ "sl_trigger_price",
5736
+ quote_min
5737
+ );
5738
+ }
5739
+ }
5740
+ if (side === OrderSide.SELL && mark_price) {
5741
+ const slTriggerPriceScope = new Decimal(mark_price * (1 + price_scope)).toDecimalPlaces(quote_dp, Decimal.ROUND_DOWN).toNumber();
5742
+ if (!!sl_trigger_price && Number(sl_trigger_price) > slTriggerPriceScope) {
5743
+ result.sl_trigger_price = OrderValidation.max(
5744
+ "sl_trigger_price",
5745
+ slTriggerPriceScope
5746
+ );
5747
+ }
5748
+ if (!!tp_trigger_price && Number(tp_trigger_price) >= mark_price) {
5749
+ result.tp_trigger_price = OrderValidation.max(
5750
+ "tp_trigger_price",
5751
+ mark_price
5752
+ );
5753
+ }
5754
+ if (!!tp_trigger_price && Number(tp_trigger_price) > quote_max) {
5755
+ result.tp_trigger_price = OrderValidation.max(
5756
+ "tp_trigger_price",
5757
+ quote_max
5758
+ );
5759
+ }
5760
+ if (!!sl_trigger_price && Number(sl_trigger_price) < quote_min) {
5761
+ result.sl_trigger_price = OrderValidation.min(
5762
+ "sl_trigger_price",
5763
+ quote_min
5764
+ );
5765
+ }
5766
+ }
5767
+ return Object.keys(result).length > 0 ? result : null;
5768
+ }
5769
+
5770
+ // src/services/orderCreator/bracketLimitOrderCreator.ts
5771
+ var BracketLimitOrderCreator = class extends LimitOrderCreator {
5772
+ // orderType: OrderType;
5773
+ create(values2, config) {
5774
+ const order = super.create(values2, config);
5775
+ return {
5776
+ ...order,
5777
+ quantity: order.order_quantity,
5778
+ type: order.order_type,
5779
+ price: order.order_price
5780
+ };
5781
+ }
5782
+ async validate(values2, config) {
5783
+ const value = await super.validate(values2, config);
5784
+ const bracketData = await bracketOrderValidator(values2, config);
5785
+ return { ...value, ...bracketData };
5786
+ }
5787
+ };
5788
+ var BracketMarketOrderCreator = class extends MarketOrderCreator {
5789
+ constructor() {
5790
+ super(...arguments);
5791
+ this.orderType = OrderType.MARKET;
5792
+ }
5793
+ create(values2) {
5794
+ const order = super.create(values2);
5795
+ return {
5796
+ ...order,
5797
+ quantity: order.order_quantity,
5798
+ type: order.order_type,
5799
+ price: order.order_price
5800
+ };
5801
+ }
5802
+ async validate(values2, config) {
5803
+ const value = await super.validate(values2, config);
5804
+ const bracketData = await bracketOrderValidator(values2, config);
5805
+ return { ...value, ...bracketData };
5806
+ }
5807
+ };
5808
+ var BBOOrderCreator = class extends BaseOrderCreator {
5809
+ create(values2) {
5810
+ const order = {
5811
+ ...this.baseOrder(values2),
5812
+ level: values2.level
5813
+ };
5814
+ return pick(
5815
+ [
5816
+ "symbol",
5817
+ "order_quantity",
5818
+ "visible_quantity",
5819
+ "reduce_only",
5820
+ "side",
5821
+ "order_type",
5822
+ "level"
5823
+ ],
5824
+ order
5825
+ );
5826
+ }
5827
+ async validate(values2, configs) {
5828
+ return this.baseValidate(values2, configs).then((errors) => {
5829
+ delete errors["total"];
5830
+ let { order_quantity, order_price, reduce_only, level } = values2;
5831
+ const { symbol } = configs;
5832
+ const { min_notional, base_tick, quote_dp, quote_tick, base_dp } = symbol || {};
5833
+ const minNotional = getMinNotional({
5834
+ base_tick,
5835
+ quote_tick,
5836
+ price: order_price,
5837
+ qty: order_quantity,
5838
+ min_notional,
5839
+ quote_dp,
5840
+ base_dp
5841
+ });
5842
+ if (minNotional !== void 0 && !reduce_only) {
5843
+ errors.total = {
5844
+ type: "min",
5845
+ message: `The order value should be greater or equal to ${minNotional} USDC`,
5846
+ value: minNotional
5847
+ };
5848
+ }
5849
+ return errors;
5850
+ });
5851
+ }
5852
+ };
5853
+
5854
+ // src/services/orderCreator/factory.ts
5855
+ var OrderFactory = class {
5856
+ static create(type) {
5857
+ switch (type) {
5858
+ case `${AlgoOrderRootType.BRACKET}:${OrderType.LIMIT}`:
5859
+ return new BracketLimitOrderCreator();
5860
+ case `${AlgoOrderRootType.BRACKET}:${OrderType.MARKET}`:
5861
+ return new BracketMarketOrderCreator();
5862
+ case OrderType.LIMIT:
5863
+ return new LimitOrderCreator();
5864
+ case OrderType.MARKET:
5865
+ return new MarketOrderCreator();
5866
+ case OrderType.ASK:
5867
+ case OrderType.BID:
5868
+ return new BBOOrderCreator();
5869
+ case OrderType.IOC:
5870
+ return new IOCOrderCreator();
5871
+ case OrderType.FOK:
5872
+ return new FOKOrderCreator();
5873
+ case OrderType.POST_ONLY:
5874
+ return new PostOnlyOrderCreator();
5875
+ case OrderType.STOP_LIMIT:
5876
+ return new StopLimitOrderCreator();
5877
+ case OrderType.STOP_MARKET:
5878
+ return new StopMarketOrderCreator();
5879
+ case AlgoOrderRootType.TP_SL:
5880
+ return new TPSLOrderCreator();
5881
+ case AlgoOrderRootType.POSITIONAL_TP_SL:
5882
+ return new TPSLPositionOrderCreator();
5883
+ default:
5884
+ return new GeneralOrderCreator();
5885
+ }
5886
+ }
5887
+ };
5888
+ function useSubAccountQuery(query, options) {
5889
+ const { formatter, accountId, ...swrOptions } = options || {};
5890
+ const { state, account: account7 } = useAccount();
5891
+ const middleware = Array.isArray(options?.use) ? options?.use ?? [] : [];
5892
+ return useSWR__default(
5893
+ () => accountId && (state.status >= AccountStatusEnum.EnableTrading || state.status === AccountStatusEnum.EnableTradingWithoutConnected) ? [query, accountId] : null,
5894
+ (url, init2) => {
5895
+ return fetcher(url, init2, { formatter });
5896
+ },
5897
+ {
5898
+ ...swrOptions,
5899
+ use: [...middleware, signatureMiddleware2(account7, accountId)],
5900
+ onError: () => {
5901
+ }
5902
+ }
5903
+ );
5904
+ }
5905
+ function signatureMiddleware2(account7, accountId) {
5906
+ const apiBaseUrl = useConfig("apiBaseUrl");
5907
+ return (useSWRNext) => {
5908
+ return (key, fetcher4, config) => {
5909
+ try {
5910
+ const extendedFetcher = async (args) => {
5911
+ const url = Array.isArray(args) ? args[0] : args;
5912
+ const fullUrl = `${apiBaseUrl}${url}`;
5913
+ const signer = account7.signer;
5914
+ const payload = {
5915
+ method: "GET",
5916
+ url
5917
+ };
5918
+ const signature = await signer.sign(payload, getTimestamp());
5919
+ return fetcher4(fullUrl, {
5920
+ headers: {
5921
+ ...signature,
5922
+ "orderly-account-id": accountId
5923
+ }
5924
+ });
5925
+ };
5926
+ return useSWRNext(key, extendedFetcher, config);
5927
+ } catch (e) {
5928
+ throw e;
5929
+ }
5930
+ };
5931
+ };
5932
+ }
5933
+ function formatPortfolio(inputs) {
5934
+ const { holding, positions: positions3, markPrices, accountInfo, symbolsInfo } = inputs;
5935
+ if (!holding || !positions3 || !Array.isArray(positions3.rows) || !markPrices || !accountInfo || symbolsInfo?.isNil) {
5936
+ return null;
5937
+ }
5938
+ const unsettledPnL = pathOr(0, ["total_unsettled_pnl"])(positions3);
5939
+ const unrealizedPnL = pathOr(0, ["total_unreal_pnl"])(positions3);
5940
+ const [USDC_holding, nonUSDC] = parseHolding(holding, markPrices);
5941
+ const usdc = holding.find((item) => item.token === "USDC");
5942
+ const totalCollateral = account.totalCollateral({
5943
+ USDCHolding: USDC_holding,
5944
+ nonUSDCHolding: nonUSDC,
5945
+ unsettlementPnL: unsettledPnL
5946
+ });
5947
+ const totalValue = account.totalValue({
5948
+ totalUnsettlementPnL: unsettledPnL,
5949
+ USDCHolding: USDC_holding,
5950
+ nonUSDCHolding: nonUSDC
5951
+ });
5952
+ const totalUnrealizedROI = account.totalUnrealizedROI({
5953
+ totalUnrealizedPnL: unrealizedPnL,
5954
+ totalValue: totalValue.toNumber()
5955
+ });
5956
+ const totalInitialMarginWithOrders = account.totalInitialMarginWithQty({
5957
+ positions: positions3.rows,
5958
+ markPrices,
5959
+ IMR_Factors: accountInfo.imr_factor,
5960
+ maxLeverage: accountInfo.max_leverage,
5961
+ symbolInfo: symbolsInfo
5962
+ });
5963
+ const freeCollateral = account.freeCollateral({
5964
+ totalCollateral,
5965
+ totalInitialMarginWithOrders
5966
+ });
5967
+ const availableBalance = account.availableBalance({
5968
+ USDCHolding: usdc?.holding ?? 0,
5969
+ unsettlementPnL: positions3.total_unsettled_pnl ?? 0
5970
+ });
5971
+ return {
5972
+ totalCollateral,
5973
+ totalValue,
5974
+ totalUnrealizedROI,
5975
+ freeCollateral,
5976
+ availableBalance,
5977
+ unsettledPnL,
5978
+ holding
5979
+ };
5980
+ }
5981
+ function formatPositions(data, accountInfo, symbolsInfo, fundingRates) {
5982
+ if (!accountInfo || !fundingRates || !symbolsInfo) {
5983
+ return data;
5632
5984
  }
5633
- create(values2, config) {
5634
- const side = values2.side === OrderSide.BUY ? OrderSide.SELL : OrderSide.BUY;
5635
- const child_orders = [];
5636
- if (typeof values2.tp_trigger_price !== "undefined") {
5637
- const tp_trigger_price = !!values2.tp_trigger_price ? new Decimal(values2.tp_trigger_price).todp(config.symbol.quote_dp).toNumber() : values2.tp_trigger_price;
5638
- child_orders.push({
5639
- algo_type: AlgoOrderType.TAKE_PROFIT,
5640
- reduce_only: true,
5641
- side,
5642
- type: OrderType.CLOSE_POSITION,
5643
- trigger_price: tp_trigger_price,
5644
- trigger_price_type: TriggerPriceType.MARK_PRICE,
5645
- symbol: values2.symbol,
5646
- is_activated: !!values2.tp_trigger_price
5985
+ let unrealPnL_total = zero, unrealPnL_total_index = zero, notional_total = zero, unsettlementPnL_total = zero;
5986
+ const rows = data.rows.map((item) => {
5987
+ const info = symbolsInfo[item.symbol];
5988
+ const notional = positions.notional(item.position_qty, item.mark_price);
5989
+ const unrealPnl = positions.unrealizedPnL({
5990
+ qty: item.position_qty,
5991
+ openPrice: item?.average_open_price,
5992
+ // markPrice: unRealizedPrice,
5993
+ markPrice: item.mark_price
5994
+ });
5995
+ let unrealPnl_index = 0, unrealPnlROI_index = 0;
5996
+ const imr = account.IMR({
5997
+ maxLeverage: accountInfo.max_leverage,
5998
+ baseIMR: info?.("base_imr"),
5999
+ IMR_Factor: accountInfo.imr_factor[item.symbol],
6000
+ positionNotional: notional,
6001
+ ordersNotional: 0,
6002
+ IMR_factor_power: 4 / 5
6003
+ });
6004
+ const unrealPnlROI = positions.unrealizedPnLROI({
6005
+ positionQty: item.position_qty,
6006
+ openPrice: item.average_open_price,
6007
+ IMR: imr,
6008
+ unrealizedPnL: unrealPnl
6009
+ });
6010
+ if (item.index_price) {
6011
+ unrealPnl_index = positions.unrealizedPnL({
6012
+ qty: item.position_qty,
6013
+ openPrice: item?.average_open_price,
6014
+ // markPrice: unRealizedPrice,
6015
+ markPrice: item.index_price
5647
6016
  });
5648
- }
5649
- if (typeof values2.sl_trigger_price !== "undefined") {
5650
- const sl_trigger_price = !!values2.sl_trigger_price ? new Decimal(values2.sl_trigger_price).todp(config.symbol.quote_dp).toNumber() : values2.sl_trigger_price;
5651
- child_orders.push({
5652
- algo_type: AlgoOrderType.STOP_LOSS,
5653
- reduce_only: true,
5654
- side,
5655
- type: OrderType.CLOSE_POSITION,
5656
- trigger_price: sl_trigger_price,
5657
- trigger_price_type: TriggerPriceType.MARK_PRICE,
5658
- symbol: values2.symbol,
5659
- is_activated: !!values2.sl_trigger_price
6017
+ unrealPnlROI_index = positions.unrealizedPnLROI({
6018
+ positionQty: item.position_qty,
6019
+ openPrice: item.average_open_price,
6020
+ IMR: imr,
6021
+ unrealizedPnL: unrealPnl_index
5660
6022
  });
5661
6023
  }
6024
+ const unsettlementPnL2 = positions.unsettlementPnL({
6025
+ positionQty: item.position_qty,
6026
+ markPrice: item.mark_price,
6027
+ costPosition: item.cost_position,
6028
+ sumUnitaryFunding: propOr(
6029
+ 0,
6030
+ "sum_unitary_funding",
6031
+ fundingRates?.[item.symbol]
6032
+ ),
6033
+ lastSumUnitaryFunding: item.last_sum_unitary_funding
6034
+ });
6035
+ const MMR = positions.MMR({
6036
+ baseMMR: info?.("base_mmr"),
6037
+ baseIMR: info?.("base_imr"),
6038
+ IMRFactor: accountInfo.imr_factor[item.symbol],
6039
+ positionNotional: notional,
6040
+ IMR_factor_power: 4 / 5
6041
+ });
6042
+ unrealPnL_total = unrealPnL_total.add(unrealPnl);
6043
+ unrealPnL_total_index = unrealPnL_total_index.add(unrealPnl_index);
6044
+ notional_total = notional_total.add(notional);
6045
+ unsettlementPnL_total = unsettlementPnL_total.add(unsettlementPnL2);
5662
6046
  return {
5663
- algo_type: AlgoOrderRootType.POSITIONAL_TP_SL,
5664
- trigger_price_type: TriggerPriceType.MARK_PRICE,
5665
- // reduce_only: true,
5666
- symbol: values2.symbol,
5667
- child_orders
6047
+ ...item,
6048
+ mm: positions.maintenanceMargin({
6049
+ positionQty: item.position_qty,
6050
+ markPrice: item.mark_price,
6051
+ MMR
6052
+ }),
6053
+ mmr: MMR,
6054
+ notional,
6055
+ unsettlement_pnl: unsettlementPnL2,
6056
+ unrealized_pnl: unrealPnl,
6057
+ unrealized_pnl_index: unrealPnl_index,
6058
+ unrealized_pnl_ROI: unrealPnlROI,
6059
+ unrealized_pnl_ROI_index: unrealPnlROI_index
5668
6060
  };
6061
+ });
6062
+ const totalUnrealPnl = unrealPnL_total.toNumber();
6063
+ const totalUnrealPnl_index = unrealPnL_total_index.toNumber();
6064
+ const unsettlementPnL = unsettlementPnL_total.toNumber();
6065
+ return {
6066
+ ...data,
6067
+ unrealPnL: totalUnrealPnl,
6068
+ total_unreal_pnl: totalUnrealPnl,
6069
+ total_unreal_pnl_index: totalUnrealPnl_index,
6070
+ notional: notional_total.toNumber(),
6071
+ unsettledPnL: unsettlementPnL,
6072
+ total_unsettled_pnl: unsettlementPnL,
6073
+ rows
6074
+ };
6075
+ }
6076
+ function calcByPrice(positions3, markPrice, indexPrice) {
6077
+ if (!positions3 || !Array.isArray(positions3.rows) || !positions3.rows.length) {
6078
+ return positions3;
5669
6079
  }
5670
- crateUpdateOrder(values2, oldValue, config) {
5671
- const data = this.create(values2, config);
5672
- const newData = [];
5673
- data.child_orders.forEach((order) => {
5674
- const oldOrder = oldValue.child_orders?.find(
5675
- (oldOrder2) => oldOrder2.algo_type === order.algo_type
5676
- );
5677
- if (oldOrder) {
5678
- if (!order.is_activated) {
5679
- newData.push({
5680
- is_activated: false,
5681
- order_id: Number(oldOrder.algo_order_id)
5682
- });
5683
- } else if (oldOrder.trigger_price !== order.trigger_price) {
5684
- newData.push({
5685
- trigger_price: order.trigger_price,
5686
- order_id: Number(oldOrder.algo_order_id)
6080
+ return {
6081
+ ...positions3,
6082
+ rows: positions3.rows.map((item) => ({
6083
+ ...item,
6084
+ mark_price: markPrice?.[item.symbol] || item.mark_price,
6085
+ index_price: indexPrice?.[item.symbol] || item.index_price || item.mark_price
6086
+ }))
6087
+ };
6088
+ }
6089
+ var useSubAccountWS = (options) => {
6090
+ const { accountId } = options;
6091
+ const { configStore } = useContext(OrderlyContext);
6092
+ const { state, account: account7 } = useAccount();
6093
+ const websocketClient = useRef(
6094
+ new WS({
6095
+ networkId: configStore.get("networkId"),
6096
+ // not need to subscribe public socket
6097
+ // publicUrl: configStore.get("publicWsUrl"),
6098
+ privateUrl: configStore.get("privateWsUrl"),
6099
+ onSigntureRequest: async () => {
6100
+ const signer = account7.signer;
6101
+ const timestamp = getTimestamp();
6102
+ const result = await signer.signText(timestamp.toString());
6103
+ return { ...result, timestamp };
6104
+ }
6105
+ })
6106
+ );
6107
+ useEffect(() => {
6108
+ if (accountId && (state.status === AccountStatusEnum.EnableTrading || state.status === AccountStatusEnum.EnableTradingWithoutConnected)) {
6109
+ websocketClient.current.openPrivate(accountId);
6110
+ }
6111
+ return () => {
6112
+ websocketClient.current.closePrivate(1e3, "switch account");
6113
+ };
6114
+ }, [accountId, state.status]);
6115
+ return websocketClient.current;
6116
+ };
6117
+
6118
+ // src/subAccount/useSubAccountDataObserver.ts
6119
+ var useSubAccountDataObserver = (accountId) => {
6120
+ const ws = useSubAccountWS({ accountId });
6121
+ const { data: markPrices } = useMarkPricesStream();
6122
+ const { data: indexPrices } = useIndexPricesStream();
6123
+ const symbolsInfo = useSymbolsInfo();
6124
+ const fundingRates = useFundingRatesStore();
6125
+ const [holding, setHolding] = useState([]);
6126
+ const [positions3, setPositions] = useState(
6127
+ POSITION_EMPTY
6128
+ );
6129
+ const [portfolio, setportfolio] = useState();
6130
+ const { data: accountInfo } = useSubAccountQuery(
6131
+ "/v1/client/info",
6132
+ { accountId, revalidateOnFocus: false }
6133
+ );
6134
+ const { data: positionsInfo } = useSubAccountQuery(
6135
+ "/v1/positions",
6136
+ {
6137
+ accountId,
6138
+ formatter: (data) => data
6139
+ }
6140
+ );
6141
+ const { data: holdingRes } = useSubAccountQuery(
6142
+ "/v1/client/holding",
6143
+ {
6144
+ accountId,
6145
+ formatter: (data) => data.holding
6146
+ }
6147
+ );
6148
+ useEffect(() => {
6149
+ const portfolio2 = formatPortfolio({
6150
+ holding,
6151
+ positions: positions3,
6152
+ markPrices,
6153
+ accountInfo,
6154
+ symbolsInfo
6155
+ });
6156
+ setportfolio(portfolio2);
6157
+ }, [holding, positions3, markPrices, accountInfo, symbolsInfo]);
6158
+ useEffect(() => {
6159
+ if (!positionsInfo)
6160
+ return;
6161
+ if (positionsInfo.rows?.length === 0) {
6162
+ setPositions(positionsInfo);
6163
+ return;
6164
+ }
6165
+ const _positionsInfo = calcByPrice(positionsInfo, markPrices, indexPrices);
6166
+ const _positions = formatPositions(
6167
+ _positionsInfo,
6168
+ accountInfo,
6169
+ symbolsInfo,
6170
+ fundingRates
6171
+ );
6172
+ setPositions({
6173
+ ..._positions,
6174
+ rows: _positions.rows.filter(
6175
+ (item) => item.position_qty !== 0 || item.pending_long_qty !== 0 || item.pending_short_qty !== 0
6176
+ )
6177
+ });
6178
+ }, [
6179
+ positionsInfo,
6180
+ accountInfo,
6181
+ symbolsInfo,
6182
+ fundingRates,
6183
+ markPrices,
6184
+ indexPrices
6185
+ ]);
6186
+ useEffect(() => {
6187
+ if (holdingRes) {
6188
+ setHolding(holdingRes);
6189
+ }
6190
+ }, [holdingRes]);
6191
+ useEffect(() => {
6192
+ if (!accountId)
6193
+ return;
6194
+ const unsubscribe = ws.privateSubscribe(
6195
+ {
6196
+ id: "balance",
6197
+ event: "subscribe",
6198
+ topic: "balance",
6199
+ ts: Date.now()
6200
+ },
6201
+ {
6202
+ onMessage: (data) => {
6203
+ const holding2 = data?.balances ?? {};
6204
+ setHolding((prev) => {
6205
+ return prev.map((item) => {
6206
+ if (holding2[item.token]) {
6207
+ return { ...item, holding: holding2[item.token].holding };
6208
+ }
6209
+ return item;
6210
+ });
5687
6211
  });
5688
6212
  }
5689
6213
  }
6214
+ );
6215
+ return () => unsubscribe?.();
6216
+ }, [accountId]);
6217
+ useEffect(() => {
6218
+ if (!accountId)
6219
+ return;
6220
+ const key = ["/v1/positions", accountId];
6221
+ const unsubscribe = ws.privateSubscribe("position", {
6222
+ onMessage: (data) => {
6223
+ const { positions: nextPositions } = data;
6224
+ mutate(
6225
+ key,
6226
+ (prevPositions) => {
6227
+ if (!!prevPositions) {
6228
+ const newPositions = {
6229
+ ...prevPositions,
6230
+ rows: prevPositions.rows.map((row) => {
6231
+ const itemIndex = nextPositions.findIndex(
6232
+ (item) => item.symbol === row.symbol
6233
+ );
6234
+ if (itemIndex >= 0) {
6235
+ const itemArr = nextPositions.splice(itemIndex, 1);
6236
+ const item = itemArr[0];
6237
+ if (item.averageOpenPrice === 0 && item.positionQty !== 0) {
6238
+ return row;
6239
+ }
6240
+ return object2underscore(item);
6241
+ }
6242
+ return row;
6243
+ })
6244
+ };
6245
+ if (nextPositions.length > 0) {
6246
+ newPositions.rows = [
6247
+ ...newPositions.rows,
6248
+ ...nextPositions.map((item) => {
6249
+ return object2underscore(item);
6250
+ })
6251
+ ];
6252
+ }
6253
+ return newPositions;
6254
+ }
6255
+ },
6256
+ {
6257
+ revalidate: false
6258
+ }
6259
+ );
6260
+ }
5690
6261
  });
5691
- return [
5692
- {
5693
- child_orders: newData
5694
- },
5695
- data
5696
- ];
5697
- }
6262
+ return () => unsubscribe?.();
6263
+ }, [accountId]);
6264
+ return { portfolio, positions: positions3 };
5698
6265
  };
5699
- async function bracketOrderValidator(values2, config) {
5700
- const result = /* @__PURE__ */ Object.create(null);
5701
- await Promise.resolve();
5702
- const { tp_trigger_price, sl_trigger_price, side } = values2;
5703
- const qty = Number(values2.quantity);
5704
- const maxQty = config.maxQty;
5705
- const type = values2.order_type;
5706
- const { quote_max, quote_min, price_scope, quote_dp } = config.symbol ?? {};
5707
- const mark_price = type === OrderType.MARKET ? config.markPrice : values2.order_price ? Number(values2.order_price) : void 0;
5708
- if (!isNaN(qty) && qty > maxQty) {
5709
- result.quantity = OrderValidation.max("quantity", config.maxQty);
6266
+ function offsetToPrice(inputs) {
6267
+ const { offset, entryPrice, orderType, orderSide } = inputs;
6268
+ if (!offset)
6269
+ return;
6270
+ if (orderSide === OrderSide.BUY) {
6271
+ if (orderType === AlgoOrderType.TAKE_PROFIT) {
6272
+ return new Decimal(entryPrice).add(new Decimal(offset)).toNumber();
6273
+ }
6274
+ return new Decimal(entryPrice).minus(new Decimal(offset)).toNumber();
5710
6275
  }
5711
- if (Number(tp_trigger_price) < 0) {
5712
- result.tp_trigger_price = OrderValidation.min("tp_trigger_price", 0);
6276
+ if (orderSide === OrderSide.SELL) {
6277
+ if (orderType === AlgoOrderType.TAKE_PROFIT) {
6278
+ return new Decimal(entryPrice).minus(new Decimal(offset)).toNumber();
6279
+ }
6280
+ return new Decimal(entryPrice).add(new Decimal(offset)).toNumber();
5713
6281
  }
5714
- if (Number(sl_trigger_price) < 0) {
5715
- result.sl_trigger_price = OrderValidation.min("sl_trigger_price", 0);
6282
+ }
6283
+ function priceToOffset(inputs, options = {}) {
6284
+ const { price, entryPrice, orderType, orderSide } = inputs;
6285
+ const { symbol } = options;
6286
+ let decimal;
6287
+ if (orderSide === OrderSide.BUY) {
6288
+ if (orderType === AlgoOrderType.TAKE_PROFIT) {
6289
+ decimal = new Decimal(price).minus(new Decimal(entryPrice));
6290
+ }
6291
+ decimal = new Decimal(price).minus(new Decimal(entryPrice));
5716
6292
  }
5717
- if (side === OrderSide.BUY && mark_price) {
5718
- const slTriggerPriceScope = new Decimal(mark_price * (1 - price_scope)).toDecimalPlaces(quote_dp, Decimal.ROUND_DOWN).toNumber();
5719
- if (!!sl_trigger_price && Number(sl_trigger_price) < slTriggerPriceScope) {
5720
- result.sl_trigger_price = OrderValidation.min(
5721
- "sl_trigger_price",
5722
- slTriggerPriceScope
5723
- );
6293
+ if (orderSide === OrderSide.SELL) {
6294
+ if (orderType === AlgoOrderType.TAKE_PROFIT) {
6295
+ decimal = new Decimal(price).minus(new Decimal(entryPrice));
6296
+ }
6297
+ decimal = new Decimal(entryPrice).minus(new Decimal(price));
6298
+ }
6299
+ if (symbol) {
6300
+ return decimal.abs().todp(symbol.quote_dp, Decimal.ROUND_UP).toNumber();
6301
+ }
6302
+ return decimal.abs().toNumber();
6303
+ }
6304
+ function offsetPercentageToPrice(inputs) {
6305
+ const { percentage, entryPrice, orderType, orderSide } = inputs;
6306
+ if (!percentage)
6307
+ return;
6308
+ if (orderSide === OrderSide.BUY) {
6309
+ if (orderType === AlgoOrderType.TAKE_PROFIT) {
6310
+ return new Decimal(1).add(new Decimal(percentage)).mul(new Decimal(entryPrice)).toNumber();
5724
6311
  }
5725
- if (!!tp_trigger_price && Number(tp_trigger_price) <= mark_price) {
5726
- result.tp_trigger_price = OrderValidation.min(
5727
- "tp_trigger_price",
5728
- mark_price
5729
- );
6312
+ return new Decimal(1).minus(new Decimal(percentage)).mul(new Decimal(entryPrice)).toNumber();
6313
+ }
6314
+ if (orderSide === OrderSide.SELL) {
6315
+ if (orderType === AlgoOrderType.TAKE_PROFIT) {
6316
+ return new Decimal(1).minus(new Decimal(percentage)).mul(new Decimal(entryPrice)).toNumber();
5730
6317
  }
5731
- if (!!tp_trigger_price && Number(tp_trigger_price) > quote_max) {
5732
- result.tp_trigger_price = OrderValidation.max(
5733
- "tp_trigger_price",
5734
- quote_max
5735
- );
6318
+ return new Decimal(1).add(new Decimal(percentage)).mul(new Decimal(entryPrice)).toNumber();
6319
+ }
6320
+ }
6321
+ function priceToOffsetPercentage(inputs) {
6322
+ const { price, entryPrice, orderType, orderSide } = inputs;
6323
+ if (orderSide === OrderSide.BUY) {
6324
+ if (entryPrice === 0)
6325
+ return 0;
6326
+ if (orderType === AlgoOrderType.TAKE_PROFIT) {
6327
+ return new Decimal(price).div(new Decimal(entryPrice)).minus(1).toDecimalPlaces(4, Decimal.ROUND_DOWN).toNumber();
5736
6328
  }
5737
- if (!!sl_trigger_price && Number(sl_trigger_price) < quote_min) {
5738
- result.sl_trigger_price = OrderValidation.min(
5739
- "sl_trigger_price",
5740
- quote_min
5741
- );
6329
+ return new Decimal(1).minus(new Decimal(price).div(new Decimal(entryPrice))).toDecimalPlaces(4, Decimal.ROUND_DOWN).toNumber();
6330
+ }
6331
+ if (orderSide === OrderSide.SELL) {
6332
+ if (entryPrice === 0)
6333
+ return 0;
6334
+ if (orderType === AlgoOrderType.TAKE_PROFIT) {
6335
+ return new Decimal(1).minus(new Decimal(price).div(new Decimal(entryPrice))).abs().toDecimalPlaces(4, Decimal.ROUND_DOWN).toNumber();
5742
6336
  }
6337
+ return new Decimal(price).div(new Decimal(entryPrice)).minus(1).toDecimalPlaces(4, Decimal.ROUND_DOWN).toNumber();
5743
6338
  }
5744
- if (side === OrderSide.SELL && mark_price) {
5745
- const slTriggerPriceScope = new Decimal(mark_price * (1 + price_scope)).toDecimalPlaces(quote_dp, Decimal.ROUND_DOWN).toNumber();
5746
- if (!!sl_trigger_price && Number(sl_trigger_price) > slTriggerPriceScope) {
5747
- result.sl_trigger_price = OrderValidation.max(
5748
- "sl_trigger_price",
5749
- slTriggerPriceScope
5750
- );
6339
+ }
6340
+ function pnlToPrice(inputs) {
6341
+ const { qty, pnl, entryPrice, orderType, orderSide } = inputs;
6342
+ if (!pnl) {
6343
+ return;
6344
+ }
6345
+ if (qty === 0)
6346
+ return;
6347
+ if (orderSide === OrderSide.BUY) {
6348
+ if (orderType === AlgoOrderType.TAKE_PROFIT) {
6349
+ return new Decimal(entryPrice).plus(new Decimal(pnl).div(new Decimal(qty))).toNumber();
5751
6350
  }
5752
- if (!!tp_trigger_price && Number(tp_trigger_price) >= mark_price) {
5753
- result.tp_trigger_price = OrderValidation.max(
5754
- "tp_trigger_price",
5755
- mark_price
5756
- );
6351
+ return new Decimal(entryPrice).add(new Decimal(pnl).div(new Decimal(qty))).toNumber();
6352
+ }
6353
+ if (orderSide === OrderSide.SELL) {
6354
+ if (orderType === AlgoOrderType.TAKE_PROFIT) {
6355
+ return new Decimal(entryPrice).add(new Decimal(pnl).div(new Decimal(qty))).toNumber();
5757
6356
  }
5758
- if (!!tp_trigger_price && Number(tp_trigger_price) > quote_max) {
5759
- result.tp_trigger_price = OrderValidation.max(
5760
- "tp_trigger_price",
5761
- quote_max
6357
+ return new Decimal(entryPrice).add(new Decimal(pnl).div(new Decimal(qty))).toNumber();
6358
+ }
6359
+ }
6360
+ function priceToPnl(inputs, options = {}) {
6361
+ const { qty, price, entryPrice, orderType, orderSide } = inputs;
6362
+ const { symbol } = options;
6363
+ let decimal = zero;
6364
+ if (orderSide === OrderSide.BUY) {
6365
+ if (orderType === AlgoOrderType.TAKE_PROFIT) {
6366
+ decimal = new Decimal(qty).mul(
6367
+ new Decimal(price).minus(new Decimal(entryPrice))
5762
6368
  );
5763
6369
  }
5764
- if (!!sl_trigger_price && Number(sl_trigger_price) < quote_min) {
5765
- result.sl_trigger_price = OrderValidation.min(
5766
- "sl_trigger_price",
5767
- quote_min
6370
+ decimal = new Decimal(qty).mul(
6371
+ new Decimal(price).minus(new Decimal(entryPrice))
6372
+ );
6373
+ }
6374
+ if (orderSide === OrderSide.SELL) {
6375
+ if (orderType === AlgoOrderType.TAKE_PROFIT) {
6376
+ decimal = new Decimal(qty).mul(
6377
+ new Decimal(price).minus(new Decimal(entryPrice))
5768
6378
  );
5769
6379
  }
6380
+ decimal = new Decimal(qty).mul(
6381
+ new Decimal(price).minus(new Decimal(entryPrice))
6382
+ );
5770
6383
  }
5771
- return Object.keys(result).length > 0 ? result : null;
6384
+ if (symbol) {
6385
+ return decimal.todp(2, Decimal.ROUND_DOWN).toNumber();
6386
+ }
6387
+ return decimal.toNumber();
5772
6388
  }
5773
-
5774
- // src/services/orderCreator/bracketLimitOrderCreator.ts
5775
- var BracketLimitOrderCreator = class extends LimitOrderCreator {
5776
- // orderType: OrderType;
5777
- create(values2, config) {
5778
- const order = super.create(values2, config);
6389
+ function calcTPSL_ROI(inputs) {
6390
+ const qtyNum = Number(inputs.qty);
6391
+ const priceNum = Number(inputs.price);
6392
+ if (qtyNum === 0 || priceNum === 0)
6393
+ return "0";
6394
+ return new Decimal(inputs.pnl).div(new Decimal(qtyNum).abs().mul(new Decimal(priceNum))).toString();
6395
+ }
6396
+ function tpslCalculateHelper(key, inputs, options = {}) {
6397
+ const { symbol } = options;
6398
+ if (key !== "quantity" && key !== "tp_trigger_price" && key !== "sl_trigger_price" && key !== "tp_pnl" && key !== "sl_pnl" && key !== "tp_offset" && key !== "sl_offset" && key !== "tp_offset_percentage" && key !== "sl_offset_percentage") {
5779
6399
  return {
5780
- ...order,
5781
- quantity: order.order_quantity,
5782
- type: order.order_type,
5783
- price: order.order_price
6400
+ [key]: inputs.value
5784
6401
  };
5785
6402
  }
5786
- async validate(values2, config) {
5787
- const value = await super.validate(values2, config);
5788
- const bracketData = await bracketOrderValidator(values2, config);
5789
- return { ...value, ...bracketData };
5790
- }
5791
- };
5792
- var BracketMarketOrderCreator = class extends MarketOrderCreator {
5793
- constructor() {
5794
- super(...arguments);
5795
- this.orderType = OrderType.MARKET;
5796
- }
5797
- create(values2) {
5798
- const order = super.create(values2);
6403
+ const orderType = key.startsWith("tp_") ? AlgoOrderType.TAKE_PROFIT : AlgoOrderType.STOP_LOSS;
6404
+ const keyPrefix = key.slice(0, 3);
6405
+ let qty = Number(key === "quantity" ? inputs.value : inputs.qty);
6406
+ if (qty === 0 && (key === "tp_pnl" || key === "sl_pnl" || key === "tp_trigger_price" || key === "sl_trigger_price")) {
5799
6407
  return {
5800
- ...order,
5801
- quantity: order.order_quantity,
5802
- type: order.order_type,
5803
- price: order.order_price
5804
- };
5805
- }
5806
- async validate(values2, config) {
5807
- const value = await super.validate(values2, config);
5808
- const bracketData = await bracketOrderValidator(values2, config);
5809
- return { ...value, ...bracketData };
5810
- }
5811
- };
5812
- var BBOOrderCreator = class extends BaseOrderCreator {
5813
- create(values2) {
5814
- const order = {
5815
- ...this.baseOrder(values2),
5816
- level: values2.level
6408
+ [`${keyPrefix}trigger_price`]: "",
6409
+ // [`${keyPrefix}offset`]: "",
6410
+ // [`${keyPrefix}offset_percentage`]: "",
6411
+ [`${keyPrefix}pnl`]: "",
6412
+ [key]: inputs.value
5817
6413
  };
5818
- return pick(
5819
- [
5820
- "symbol",
5821
- "order_quantity",
5822
- "visible_quantity",
5823
- "reduce_only",
5824
- "side",
5825
- "order_type",
5826
- "level"
5827
- ],
5828
- order
5829
- );
5830
- }
5831
- async validate(values2, configs) {
5832
- return this.baseValidate(values2, configs).then((errors) => {
5833
- delete errors["total"];
5834
- let { order_quantity, order_price, reduce_only, level } = values2;
5835
- const { symbol } = configs;
5836
- const { min_notional, base_tick, quote_dp, quote_tick, base_dp } = symbol || {};
5837
- const minNotional = getMinNotional({
5838
- base_tick,
5839
- quote_tick,
5840
- price: order_price,
5841
- qty: order_quantity,
5842
- min_notional,
5843
- quote_dp,
5844
- base_dp
5845
- });
5846
- if (minNotional !== void 0 && !reduce_only) {
5847
- errors.total = {
5848
- type: "min",
5849
- message: `The order value should be greater or equal to ${minNotional} USDC`,
5850
- value: minNotional
5851
- };
5852
- }
5853
- return errors;
5854
- });
5855
6414
  }
5856
- };
5857
-
5858
- // src/services/orderCreator/factory.ts
5859
- var OrderFactory = class {
5860
- static create(type) {
5861
- switch (type) {
5862
- case `${AlgoOrderRootType.BRACKET}:${OrderType.LIMIT}`:
5863
- return new BracketLimitOrderCreator();
5864
- case `${AlgoOrderRootType.BRACKET}:${OrderType.MARKET}`:
5865
- return new BracketMarketOrderCreator();
5866
- case OrderType.LIMIT:
5867
- return new LimitOrderCreator();
5868
- case OrderType.MARKET:
5869
- return new MarketOrderCreator();
5870
- case OrderType.ASK:
5871
- case OrderType.BID:
5872
- return new BBOOrderCreator();
5873
- case OrderType.IOC:
5874
- return new IOCOrderCreator();
5875
- case OrderType.FOK:
5876
- return new FOKOrderCreator();
5877
- case OrderType.POST_ONLY:
5878
- return new PostOnlyOrderCreator();
5879
- case OrderType.STOP_LIMIT:
5880
- return new StopLimitOrderCreator();
5881
- case OrderType.STOP_MARKET:
5882
- return new StopMarketOrderCreator();
5883
- case AlgoOrderRootType.TP_SL:
5884
- return new TPSLOrderCreator();
5885
- case AlgoOrderRootType.POSITIONAL_TP_SL:
5886
- return new TPSLPositionOrderCreator();
5887
- default:
5888
- return new GeneralOrderCreator();
6415
+ let trigger_price, offset, offset_percentage, pnl;
6416
+ const entryPrice = new Decimal(inputs.entryPrice).todp(options.symbol?.quote_dp ?? 2, Decimal.ROUND_UP).toNumber();
6417
+ switch (key) {
6418
+ case "tp_trigger_price":
6419
+ case "sl_trigger_price": {
6420
+ trigger_price = inputs.value;
6421
+ if (inputs.value === "") {
6422
+ return {
6423
+ [`${keyPrefix}trigger_price`]: trigger_price,
6424
+ [`${keyPrefix}offset`]: "",
6425
+ [`${keyPrefix}offset_percentage`]: "",
6426
+ [`${keyPrefix}pnl`]: "",
6427
+ [`${keyPrefix}ROI`]: ""
6428
+ };
6429
+ }
6430
+ break;
6431
+ }
6432
+ case "tp_pnl":
6433
+ case "sl_pnl": {
6434
+ pnl = inputs.value;
6435
+ trigger_price = pnlToPrice({
6436
+ qty,
6437
+ pnl: Number(inputs.value),
6438
+ entryPrice,
6439
+ orderSide: inputs.orderSide,
6440
+ orderType
6441
+ });
6442
+ break;
6443
+ }
6444
+ case "tp_offset":
6445
+ case "sl_offset": {
6446
+ offset = inputs.value;
6447
+ trigger_price = offsetToPrice({
6448
+ offset: Number(inputs.value),
6449
+ entryPrice,
6450
+ orderSide: inputs.orderSide,
6451
+ orderType: key === "tp_offset" ? AlgoOrderType.TAKE_PROFIT : AlgoOrderType.STOP_LOSS
6452
+ });
6453
+ break;
6454
+ }
6455
+ case "tp_offset_percentage":
6456
+ case "sl_offset_percentage": {
6457
+ offset_percentage = inputs.value;
6458
+ trigger_price = offsetPercentageToPrice({
6459
+ percentage: Number(`${inputs.value}`.replace(/\.0{0,2}$/, "")),
6460
+ entryPrice,
6461
+ orderSide: inputs.orderSide,
6462
+ orderType
6463
+ });
6464
+ break;
5889
6465
  }
5890
6466
  }
5891
- };
6467
+ if (!trigger_price)
6468
+ return {
6469
+ [`${keyPrefix}trigger_price`]: "",
6470
+ [`${keyPrefix}offset`]: "",
6471
+ [`${keyPrefix}offset_percentage`]: "",
6472
+ [`${keyPrefix}pnl`]: "",
6473
+ [`${keyPrefix}ROI`]: "",
6474
+ [key]: inputs.value
6475
+ };
6476
+ return {
6477
+ [`${keyPrefix}trigger_price`]: todpIfNeed(
6478
+ trigger_price,
6479
+ symbol?.quote_dp ?? 2
6480
+ ),
6481
+ [`${keyPrefix}offset`]: offset ?? priceToOffset(
6482
+ {
6483
+ price: Number(trigger_price),
6484
+ entryPrice,
6485
+ orderSide: inputs.orderSide,
6486
+ orderType
6487
+ },
6488
+ options
6489
+ ),
6490
+ [`${keyPrefix}offset_percentage`]: offset_percentage ?? priceToOffsetPercentage({
6491
+ price: Number(trigger_price),
6492
+ entryPrice,
6493
+ orderSide: inputs.orderSide,
6494
+ orderType
6495
+ }),
6496
+ [`${keyPrefix}pnl`]: pnl ?? priceToPnl(
6497
+ {
6498
+ qty,
6499
+ price: Number(trigger_price),
6500
+ entryPrice,
6501
+ orderSide: inputs.orderSide,
6502
+ orderType
6503
+ },
6504
+ options
6505
+ )
6506
+ // [`${keyPrefix}ROI`]: calcROI({
6507
+ // pnl: Number(pnl ?? 0),
6508
+ // qty,
6509
+ // price: Number(trigger_price!),
6510
+ // }),
6511
+ };
6512
+ }
6513
+
6514
+ // src/orderly/useTakeProfitAndStopLoss/useTPSL.ts
5892
6515
  var useTaskProfitAndStopLossInternal = (position, options) => {
5893
6516
  const isEditing = typeof options?.isEditing !== "undefined" ? options.isEditing : !!options?.defaultOrder;
5894
6517
  const [order, setOrder] = useState({
@@ -5902,11 +6525,8 @@ var useTaskProfitAndStopLossInternal = (position, options) => {
5902
6525
  });
5903
6526
  const symbolInfo = useSymbolsInfo()[position.symbol]();
5904
6527
  const { data: markPrice } = useMarkPrice(order.symbol);
5905
- const [doCreateOrder, { isMutating: isCreateMutating }] = useMutation("/v1/algo/order");
5906
- const [doUpdateOrder, { isMutating: isUpdateMutating }] = useMutation(
5907
- "/v1/algo/order",
5908
- "PUT"
5909
- );
6528
+ const [doCreateOrder, { isMutating: isCreateMutating }] = useSubAccountMutation("/v1/algo/order");
6529
+ const [doUpdateOrder, { isMutating: isUpdateMutating }] = useSubAccountMutation("/v1/algo/order", "PUT");
5910
6530
  const [doDeleteOrder] = useMutation("/v1/algo/order", "DELETE");
5911
6531
  const [errors, setErrors] = useState(null);
5912
6532
  useEffect(() => {
@@ -6022,22 +6642,22 @@ var useTaskProfitAndStopLossInternal = (position, options) => {
6022
6642
  compare() ? AlgoOrderRootType.POSITIONAL_TP_SL : AlgoOrderRootType.TP_SL
6023
6643
  );
6024
6644
  };
6025
- const submit = async () => {
6645
+ const submit = async (params) => {
6026
6646
  const defaultOrder = options?.defaultOrder;
6027
6647
  const orderId = defaultOrder?.algo_order_id;
6028
6648
  const algoType = defaultOrder?.algo_type;
6029
6649
  if (!orderId) {
6030
- return createOrder();
6650
+ return createOrder(params);
6031
6651
  }
6032
6652
  if (algoType === AlgoOrderRootType.POSITIONAL_TP_SL) {
6033
6653
  if (compare()) {
6034
- return updateOrder(orderId);
6654
+ return updateOrder(orderId, params);
6035
6655
  }
6036
- return createOrder();
6656
+ return createOrder(params);
6037
6657
  }
6038
- return updateOrder(orderId);
6658
+ return updateOrder(orderId, params);
6039
6659
  };
6040
- const createOrder = () => {
6660
+ const createOrder = (params) => {
6041
6661
  const orderCreator = getOrderCreator2();
6042
6662
  const orderBody = orderCreator.create(
6043
6663
  order,
@@ -6049,7 +6669,7 @@ var useTaskProfitAndStopLossInternal = (position, options) => {
6049
6669
  orderBody.child_orders = orderBody.child_orders.filter(
6050
6670
  (order2) => order2.is_activated
6051
6671
  );
6052
- return doCreateOrder(orderBody);
6672
+ return doCreateOrder(orderBody, {}, params);
6053
6673
  };
6054
6674
  const deleteOrder = (orderId, symbol) => {
6055
6675
  return doDeleteOrder(null, {
@@ -6057,7 +6677,7 @@ var useTaskProfitAndStopLossInternal = (position, options) => {
6057
6677
  symbol
6058
6678
  });
6059
6679
  };
6060
- const updateOrder = (orderId) => {
6680
+ const updateOrder = (orderId, params) => {
6061
6681
  const orderCreator = getOrderCreator2();
6062
6682
  const [updatedOrderEntity, orderEntity] = orderCreator.crateUpdateOrder(
6063
6683
  // @ts-ignore
@@ -6074,10 +6694,14 @@ var useTaskProfitAndStopLossInternal = (position, options) => {
6074
6694
  if (needDelete) {
6075
6695
  return deleteOrder(orderId, order.symbol);
6076
6696
  }
6077
- return doUpdateOrder({
6078
- order_id: orderId,
6079
- ...updatedOrderEntity
6080
- });
6697
+ return doUpdateOrder(
6698
+ {
6699
+ order_id: orderId,
6700
+ ...updatedOrderEntity
6701
+ },
6702
+ {},
6703
+ params
6704
+ );
6081
6705
  };
6082
6706
  return [
6083
6707
  omit(["ignoreValidate"], order),
@@ -6120,6 +6744,7 @@ var useSymbolLeverage = (symbol) => {
6120
6744
  const maxAccountLeverage = info?.max_leverage;
6121
6745
  const res = useQuery(`/v1/public/info/${symbol}`, {
6122
6746
  dedupingInterval: 1e3 * 60 * 60 * 24,
6747
+ // 24 hours
6123
6748
  revalidateOnFocus: false,
6124
6749
  errorRetryCount: 2,
6125
6750
  errorRetryInterval: 200
@@ -6161,7 +6786,7 @@ var useAssetsHistory = (options) => {
6161
6786
  searchParams.set("end_t", options.endTime);
6162
6787
  return `/v1/asset/history?${searchParams.toString()}`;
6163
6788
  };
6164
- const { data, isLoading, mutate: mutate3 } = usePrivateQuery(
6789
+ const { data, isLoading, mutate: mutate5 } = usePrivateQuery(
6165
6790
  getKey(),
6166
6791
  {
6167
6792
  formatter: (data2) => data2,
@@ -6171,7 +6796,7 @@ var useAssetsHistory = (options) => {
6171
6796
  );
6172
6797
  const updateList = useDebouncedCallback(
6173
6798
  (data2) => {
6174
- mutate3();
6799
+ mutate5();
6175
6800
  },
6176
6801
  // delay in ms
6177
6802
  300
@@ -6293,7 +6918,7 @@ var useFundingFeeHistory = (params, options) => {
6293
6918
  ];
6294
6919
  };
6295
6920
  var useDistributionHistory = (parmas) => {
6296
- let { type, dataRange, page, pageSize } = parmas;
6921
+ const { type, dataRange, page, pageSize } = parmas;
6297
6922
  const infos = useSymbolsInfo();
6298
6923
  const getKey = () => {
6299
6924
  const search = new URLSearchParams();
@@ -6326,14 +6951,39 @@ var useDistributionHistory = (parmas) => {
6326
6951
  };
6327
6952
  });
6328
6953
  }, [data, infos]);
6329
- return [
6330
- parsedData,
6954
+ return [parsedData, { meta: data?.meta, isLoading, isValidating }];
6955
+ };
6956
+ var useTransferHistory = (parmas) => {
6957
+ const { dataRange, page, size, side, fromId, toId } = parmas;
6958
+ const infos = useSymbolsInfo();
6959
+ const memoizedQueryKey = React.useMemo(() => {
6960
+ const search = new URLSearchParams();
6961
+ search.set("page", page.toString());
6962
+ search.set("size", size.toString());
6963
+ search.set("side", side);
6964
+ search.set("main_sub_only", `${true}`);
6965
+ if (dataRange) {
6966
+ search.set("start_t", dataRange[0].toString());
6967
+ search.set("end_t", dataRange[1].toString());
6968
+ }
6969
+ return `/v1/internal_transfer_history?${search.toString()}`;
6970
+ }, [page, size, fromId, toId, dataRange]);
6971
+ const { data, isLoading } = usePrivateQuery(
6972
+ memoizedQueryKey,
6331
6973
  {
6332
- meta: data?.meta,
6333
- isLoading,
6334
- isValidating
6974
+ // initialSize: 1,
6975
+ formatter: (data2) => data2,
6976
+ revalidateOnFocus: false,
6977
+ errorRetryCount: 3
6335
6978
  }
6336
- ];
6979
+ );
6980
+ const parsedData = React.useMemo(() => {
6981
+ if (!Array.isArray(data?.rows) || !data?.rows.length || infos.isNil) {
6982
+ return [];
6983
+ }
6984
+ return data.rows;
6985
+ }, [data, infos]);
6986
+ return [parsedData, { meta: data?.meta, isLoading }];
6337
6987
  };
6338
6988
  var MaintenanceStatus = /* @__PURE__ */ ((MaintenanceStatus2) => {
6339
6989
  MaintenanceStatus2[MaintenanceStatus2["None"] = 0] = "None";
@@ -6345,7 +6995,7 @@ function useMaintenanceStatus() {
6345
6995
  const [startTime, setStartTime] = useState();
6346
6996
  const [endTime, setEndTime] = useState();
6347
6997
  const [brokerName, setBrokerName] = useState("Orderly network");
6348
- const { data: systemInfo, mutate: mutate3 } = useQuery(
6998
+ const { data: systemInfo, mutate: mutate5 } = useQuery(
6349
6999
  `/v1/public/system_info?source=maintenance`,
6350
7000
  {
6351
7001
  revalidateOnFocus: false,
@@ -6405,23 +7055,30 @@ var useStorageLedgerAddress = () => {
6405
7055
  ledgerWallet
6406
7056
  };
6407
7057
  };
7058
+
7059
+ // src/orderly/usePrivateDataObserver.ts
6408
7060
  var usePrivateDataObserver = (options) => {
6409
7061
  const ws = useWS();
6410
7062
  const ee = useEventEmitter();
6411
- const { state, account: account5 } = useAccount();
7063
+ const { state, account: account7 } = useAccount();
6412
7064
  const { setAccountInfo, restoreHolding, cleanAll } = useAppStore(
6413
7065
  (state2) => state2.actions
6414
7066
  );
6415
7067
  const statusActions = useApiStatusActions();
6416
7068
  const calculatorService = useCalculatorService();
6417
7069
  const positionsActions = usePositionActions();
6418
- const { data: clientInfo } = usePrivateQuery("/v1/client/info");
7070
+ const { data: clientInfo } = usePrivateQuery(
7071
+ "/v1/client/info",
7072
+ {
7073
+ revalidateOnFocus: false
7074
+ }
7075
+ );
6419
7076
  useEffect(() => {
6420
7077
  if (clientInfo) {
6421
7078
  setAccountInfo(clientInfo);
6422
7079
  }
6423
7080
  }, [clientInfo, setAccountInfo]);
6424
- const { data: positions2, isLoading: isPositionLoading } = usePrivateQuery("/v1/positions", {
7081
+ const { data: positions3, isLoading: isPositionLoading } = usePrivateQuery("/v1/positions", {
6425
7082
  formatter: (data) => data,
6426
7083
  onError: (error) => {
6427
7084
  statusActions.updateApiError("positions", error.message);
@@ -6436,9 +7093,9 @@ var usePrivateDataObserver = (options) => {
6436
7093
  positionsActions.clearAll();
6437
7094
  }
6438
7095
  };
6439
- account5.on(EVENT_NAMES.statusChanged, handler);
7096
+ account7.on(EVENT_NAMES.statusChanged, handler);
6440
7097
  return () => {
6441
- account5.off(EVENT_NAMES.statusChanged, handler);
7098
+ account7.off(EVENT_NAMES.statusChanged, handler);
6442
7099
  };
6443
7100
  }, []);
6444
7101
  useEffect(() => {
@@ -6447,10 +7104,10 @@ var usePrivateDataObserver = (options) => {
6447
7104
  }
6448
7105
  }, [isPositionLoading, statusActions]);
6449
7106
  useEffect(() => {
6450
- if (positions2 && Array.isArray(positions2.rows)) {
6451
- calculatorService.calc("position" /* POSITION */, positions2);
7107
+ if (positions3 && Array.isArray(positions3.rows)) {
7108
+ calculatorService.calc("position" /* POSITION */, positions3);
6452
7109
  }
6453
- }, [calculatorService, positions2]);
7110
+ }, [calculatorService, positions3]);
6454
7111
  const { data: holding } = usePrivateQuery(
6455
7112
  "/v1/client/holding",
6456
7113
  {
@@ -6459,6 +7116,8 @@ var usePrivateDataObserver = (options) => {
6459
7116
  }
6460
7117
  );
6461
7118
  useEffect(() => {
7119
+ if (!account7.accountId)
7120
+ return;
6462
7121
  const unsubscribe = ws.privateSubscribe(
6463
7122
  {
6464
7123
  id: "balance",
@@ -6475,20 +7134,32 @@ var usePrivateDataObserver = (options) => {
6475
7134
  }
6476
7135
  }
6477
7136
  );
6478
- return () => unsubscribe();
6479
- }, []);
7137
+ return () => unsubscribe?.();
7138
+ }, [account7.accountId]);
7139
+ const isHoldingInit = useRef(false);
6480
7140
  useEffect(() => {
6481
- if (holding) {
7141
+ if (!holding) {
7142
+ return;
7143
+ }
7144
+ if (isHoldingInit.current) {
7145
+ calculatorService.calc("portfolio" /* PORTFOLIO */, { holding });
7146
+ } else {
6482
7147
  restoreHolding(holding);
6483
7148
  }
7149
+ isHoldingInit.current = true;
6484
7150
  }, [holding]);
6485
- const [subOrder, setSubOrder] = useLocalStorage(
6486
- "orderly_subscribe_order",
6487
- true
6488
- );
7151
+ const [subOrder] = useLocalStorage("orderly_subscribe_order", true);
6489
7152
  const updateOrders = (data, isAlgoOrder) => {
6490
7153
  const keysMap = options.getKeysMap("orders");
6491
- keysMap.forEach((getKey, key) => {
7154
+ const filteredKeys = /* @__PURE__ */ new Map();
7155
+ const keyStartWith = isAlgoOrder ? "algoOrders" : "orders";
7156
+ const keys = keysMap.keys();
7157
+ for (const key of keys) {
7158
+ if (key.startsWith(keyStartWith)) {
7159
+ filteredKeys.set(key, keysMap.get(key));
7160
+ }
7161
+ }
7162
+ filteredKeys.forEach((getKey, key) => {
6492
7163
  mutate(
6493
7164
  unstable_serialize((index, prevData) => [
6494
7165
  getKey(index, prevData),
@@ -6521,10 +7192,12 @@ var usePrivateDataObserver = (options) => {
6521
7192
  });
6522
7193
  };
6523
7194
  useEffect(() => {
6524
- if (!state.accountId)
7195
+ if (!state.accountId) {
6525
7196
  return;
6526
- if (subOrder !== true)
7197
+ }
7198
+ if (subOrder !== true) {
6527
7199
  return;
7200
+ }
6528
7201
  const unsubscribe = ws.privateSubscribe("executionreport", {
6529
7202
  onMessage: (data) => {
6530
7203
  updateOrders(data, false);
@@ -6545,8 +7218,9 @@ var usePrivateDataObserver = (options) => {
6545
7218
  return () => unsubscribe?.();
6546
7219
  }, [state.accountId, subOrder]);
6547
7220
  useEffect(() => {
6548
- if (!state.accountId)
7221
+ if (!state.accountId) {
6549
7222
  return;
7223
+ }
6550
7224
  const key = ["/v1/positions", state.accountId];
6551
7225
  const unsubscribe = ws.privateSubscribe("position", {
6552
7226
  onMessage: (data) => {
@@ -6575,9 +7249,7 @@ var usePrivateDataObserver = (options) => {
6575
7249
  if (nextPositions.length > 0) {
6576
7250
  newPositions.rows = [
6577
7251
  ...newPositions.rows,
6578
- ...nextPositions.map((item) => {
6579
- return object2underscore(item);
6580
- })
7252
+ ...nextPositions.map(object2underscore)
6581
7253
  ];
6582
7254
  }
6583
7255
  return newPositions;
@@ -6594,43 +7266,6 @@ var usePrivateDataObserver = (options) => {
6594
7266
  };
6595
7267
  }, [state.accountId]);
6596
7268
  };
6597
- var useWSObserver = (calculatorService) => {
6598
- const ws = useWS();
6599
- useEffect(() => {
6600
- const markPriceSubscription = ws.subscribe("markprices", {
6601
- onMessage: (message) => {
6602
- const data = /* @__PURE__ */ Object.create(null);
6603
- for (let index = 0; index < message.length; index++) {
6604
- const element = message[index];
6605
- data[element.symbol] = element.price;
6606
- }
6607
- calculatorService.calc("markPrice" /* MARK_PRICE */, data, {
6608
- skipWhenOnPause: true
6609
- });
6610
- },
6611
- onError: (error) => {
6612
- }
6613
- });
6614
- const indexPriceSubscription = ws.subscribe("indexprices", {
6615
- onMessage: (message) => {
6616
- if (!Array.isArray(message))
6617
- return;
6618
- const prices = /* @__PURE__ */ Object.create(null);
6619
- for (let index = 0; index < message.length; index++) {
6620
- const element = message[index];
6621
- prices[element.symbol.replace("SPOT", "PERP")] = element.price;
6622
- }
6623
- calculatorService.calc("indexPrice" /* INDEX_PRICE */, prices, {
6624
- skipWhenOnPause: true
6625
- });
6626
- }
6627
- });
6628
- return () => {
6629
- markPriceSubscription?.();
6630
- indexPriceSubscription?.();
6631
- };
6632
- }, []);
6633
- };
6634
7269
  var useMarketStore = create(
6635
7270
  (set, get3) => ({
6636
7271
  market: [],
@@ -6736,7 +7371,9 @@ var DataCenterContext = createContext(
6736
7371
  {}
6737
7372
  );
6738
7373
  var useDataCenterContext = () => useContext(DataCenterContext);
6739
- var DataCenterProvider = ({ children }) => {
7374
+ var DataCenterProvider = ({
7375
+ children
7376
+ }) => {
6740
7377
  const { error, done } = usePreLoadData();
6741
7378
  const calculatorService = useCalculatorService();
6742
7379
  usePublicDataObserver();
@@ -6750,8 +7387,9 @@ var DataCenterProvider = ({ children }) => {
6750
7387
  if (error) {
6751
7388
  return /* @__PURE__ */ jsx("div", { children: "Data load failed" });
6752
7389
  }
6753
- if (!done)
7390
+ if (!done) {
6754
7391
  return null;
7392
+ }
6755
7393
  return /* @__PURE__ */ jsx(
6756
7394
  DataCenterContext.Provider,
6757
7395
  {
@@ -6833,7 +7471,7 @@ var ExtendedConfigStore = class extends DefaultConfigStore {
6833
7471
  }
6834
7472
  };
6835
7473
  var OrderlyConfigProvider = (props) => {
6836
- const [account5, setAccount] = React.useState(null);
7474
+ const [account7, setAccount] = React.useState(null);
6837
7475
  const {
6838
7476
  configStore,
6839
7477
  keyStore,
@@ -6871,9 +7509,9 @@ var OrderlyConfigProvider = (props) => {
6871
7509
  ];
6872
7510
  }, [walletAdapters]);
6873
7511
  useLayoutEffect(() => {
6874
- let account6 = SimpleDI.get(Account.instanceName);
6875
- if (!account6) {
6876
- account6 = new Account(
7512
+ let account8 = SimpleDI.get(Account.instanceName);
7513
+ if (!account8) {
7514
+ account8 = new Account(
6877
7515
  innerConfigStore,
6878
7516
  innerKeyStore,
6879
7517
  // innerGetWalletAdapter,
@@ -6882,9 +7520,9 @@ var OrderlyConfigProvider = (props) => {
6882
7520
  contracts
6883
7521
  }
6884
7522
  );
6885
- SimpleDI.registerByName(Account.instanceName, account6);
7523
+ SimpleDI.registerByName(Account.instanceName, account8);
6886
7524
  }
6887
- setAccount(account6);
7525
+ setAccount(account8);
6888
7526
  }, []);
6889
7527
  const filteredChains = useMemo(() => {
6890
7528
  if (typeof chainFilter === "function") {
@@ -6892,7 +7530,7 @@ var OrderlyConfigProvider = (props) => {
6892
7530
  }
6893
7531
  return chainFilter;
6894
7532
  }, [props.chainFilter, innerConfigStore]);
6895
- if (!account5) {
7533
+ if (!account7) {
6896
7534
  return null;
6897
7535
  }
6898
7536
  return /* @__PURE__ */ jsx(
@@ -7149,6 +7787,16 @@ function formatNumber(qty, dp) {
7149
7787
  return void 0;
7150
7788
  }
7151
7789
  }
7790
+ function calculate(values2, fieldName, value, markPrice, config) {
7791
+ const fieldHandler = getCalculateHandler(fieldName);
7792
+ const newValues = compose(
7793
+ head,
7794
+ // orderEntityFormatHandle(baseDP, quoteDP),
7795
+ fieldHandler,
7796
+ baseInputHandle
7797
+ )([values2, fieldName, value, markPrice, config]);
7798
+ return newValues;
7799
+ }
7152
7800
  function useOrderEntry(symbolOrOrder, sideOrOptions, reduceOnly, options) {
7153
7801
  let isNewVersion = false;
7154
7802
  if (typeof symbolOrOrder === "object") {
@@ -7168,7 +7816,7 @@ function useOrderEntry(symbolOrOrder, sideOrOptions, reduceOnly, options) {
7168
7816
  const notSupportData = useRef({});
7169
7817
  const [errors, setErrors] = useState(null);
7170
7818
  const ee = useEventEmitter();
7171
- const positions2 = usePositions();
7819
+ const positions3 = usePositions();
7172
7820
  const fieldDirty = useRef({});
7173
7821
  const submitted = useRef(false);
7174
7822
  const askAndBid = useRef([]);
@@ -7391,7 +8039,7 @@ function useOrderEntry(symbolOrOrder, sideOrOptions, reduceOnly, options) {
7391
8039
  }
7392
8040
  return createOrder(parsedData);
7393
8041
  }, [parsedData]);
7394
- const calculate = useCallback(
8042
+ const calculate2 = useCallback(
7395
8043
  (values2, field, value) => {
7396
8044
  const fieldHandler = getCalculateHandler(field);
7397
8045
  const newValues = compose(
@@ -7441,7 +8089,7 @@ function useOrderEntry(symbolOrOrder, sideOrOptions, reduceOnly, options) {
7441
8089
  if (typeof parsedData.order_quantity !== "undefined") {
7442
8090
  fieldDirty.current.order_quantity = true;
7443
8091
  }
7444
- const values2 = calculate(parsedData, item.key, item.value);
8092
+ const values2 = calculate2(parsedData, item.key, item.value);
7445
8093
  values2.isStopOrder = values2.order_type?.startsWith("STOP") || false;
7446
8094
  values2.total = values2.total || "";
7447
8095
  prevOrderData.current = parsedData;
@@ -7542,7 +8190,7 @@ function useOrderEntry(symbolOrOrder, sideOrOptions, reduceOnly, options) {
7542
8190
  baseIMR,
7543
8191
  baseMMR,
7544
8192
  totalCollateral,
7545
- positions: positions2 == null ? [] : positions2,
8193
+ positions: positions3 == null ? [] : positions3,
7546
8194
  IMR_Factor: accountInfo["imr_factor"][symbol],
7547
8195
  orderFee,
7548
8196
  newOrder: {
@@ -7573,7 +8221,7 @@ function useOrderEntry(symbolOrOrder, sideOrOptions, reduceOnly, options) {
7573
8221
  return null;
7574
8222
  const leverage = order.estLeverage({
7575
8223
  totalCollateral,
7576
- positions: positions2 === null ? [] : positions2,
8224
+ positions: positions3 === null ? [] : positions3,
7577
8225
  newOrder: {
7578
8226
  symbol: parsedData.symbol,
7579
8227
  qty: result.quantity,
@@ -7585,7 +8233,7 @@ function useOrderEntry(symbolOrOrder, sideOrOptions, reduceOnly, options) {
7585
8233
  baseIMR,
7586
8234
  baseMMR,
7587
8235
  totalCollateral,
7588
- positions2,
8236
+ positions3,
7589
8237
  formattedOrder?.order_price,
7590
8238
  formattedOrder?.order_quantity,
7591
8239
  formattedOrder?.total,
@@ -7604,7 +8252,7 @@ function useOrderEntry(symbolOrOrder, sideOrOptions, reduceOnly, options) {
7604
8252
  estLeverage,
7605
8253
  helper: {
7606
8254
  //@ts-ignore
7607
- calculate,
8255
+ calculate: calculate2,
7608
8256
  validator
7609
8257
  // clearErrors,
7610
8258
  },
@@ -8439,12 +9087,12 @@ var useDaily = (options) => {
8439
9087
  start_date,
8440
9088
  end_date
8441
9089
  )}`;
8442
- const { data: dailyVolume, mutate: mutate3 } = usePrivateQuery(url, {
9090
+ const { data: dailyVolume, mutate: mutate5 } = usePrivateQuery(url, {
8443
9091
  revalidateOnFocus: true
8444
9092
  });
8445
9093
  return {
8446
9094
  data: dailyVolume,
8447
- mutate: mutate3
9095
+ mutate: mutate5
8448
9096
  };
8449
9097
  };
8450
9098
  var useReferralRebateSummary = (params) => {
@@ -8556,14 +9204,14 @@ var useRefereeRebateSummary = (params) => {
8556
9204
  }
8557
9205
  const {
8558
9206
  data,
8559
- mutate: mutate3,
9207
+ mutate: mutate5,
8560
9208
  isLoading
8561
9209
  } = usePrivateQuery(url, {
8562
9210
  revalidateOnFocus: true
8563
9211
  });
8564
9212
  return {
8565
9213
  data,
8566
- mutate: mutate3,
9214
+ mutate: mutate5,
8567
9215
  isLoading
8568
9216
  };
8569
9217
  };
@@ -8612,12 +9260,9 @@ var useGetReferralCode = (accountId) => {
8612
9260
  };
8613
9261
  };
8614
9262
  var useReferralInfo = () => {
8615
- const {
8616
- data,
8617
- mutate: mutate3,
8618
- isLoading,
8619
- error
8620
- } = usePrivateQuery("/v1/referral/info", {
9263
+ const { state } = useAccount();
9264
+ const { data, isLoading, error } = useSubAccountQuery("/v1/referral/info", {
9265
+ accountId: state?.mainAccountId,
8621
9266
  revalidateOnFocus: true
8622
9267
  });
8623
9268
  const isTrader = useMemo(() => {
@@ -8630,7 +9275,10 @@ var useReferralInfo = () => {
8630
9275
  return void 0;
8631
9276
  return (data?.referrer_info?.referral_codes?.length || 0) > 0;
8632
9277
  }, [data?.referrer_info]);
8633
- const [pinCodes] = useLocalStorage("orderly_referral_codes", []);
9278
+ const [pinCodes] = useLocalStorage(
9279
+ "orderly_referral_codes",
9280
+ []
9281
+ );
8634
9282
  const getFirstRefCode = useCallback(() => {
8635
9283
  if (!data?.referrer_info.referral_codes)
8636
9284
  return void 0;
@@ -8721,9 +9369,9 @@ var useAllBrokers = () => {
8721
9369
  };
8722
9370
  var useCurEpochEstimate = (type) => {
8723
9371
  const [data, setData] = useState(void 0);
8724
- const { account: account5 } = useAccount();
9372
+ const { account: account7 } = useAccount();
8725
9373
  const brokers = useAllBrokers();
8726
- const address = account5.address;
9374
+ const address = account7.address;
8727
9375
  const path2 = type === "normal" /* normal */ ? `/v1/public/trading_rewards/current_epoch_estimate?address=${address}` : `/v1/public/market_making_rewards/current_epoch_estimate?address=${address}`;
8728
9376
  const { data: estimateData } = useQuery(address !== void 0 ? path2 : "", {
8729
9377
  formatter: (res) => {
@@ -13683,14 +14331,14 @@ var DistributionId = /* @__PURE__ */ ((DistributionId2) => {
13683
14331
  })(DistributionId || {});
13684
14332
  var useGetClaimed = (id) => {
13685
14333
  const [data, setData] = useState(0);
13686
- const { account: account5 } = useAccount();
13687
- const address = account5.address;
14334
+ const { account: account7 } = useAccount();
14335
+ const address = account7.address;
13688
14336
  const env = useGetEnv();
13689
14337
  const refresh = useCallback(() => {
13690
14338
  const params = getContractByEnv(env);
13691
14339
  if (typeof address === "undefined")
13692
14340
  return;
13693
- account5.walletAdapter?.callOnChain(
14341
+ account7.walletAdapter?.callOnChain(
13694
14342
  // @ts-ignore
13695
14343
  { public_rpc_url: params.orderlyChainRpcUrl },
13696
14344
  params.orderlyContract,
@@ -13715,8 +14363,8 @@ var useGetClaimed = (id) => {
13715
14363
 
13716
14364
  // src/trading-rewards/useWalletRewardsHistory.ts
13717
14365
  var useWalletRewardsHistory = (type) => {
13718
- const { account: account5 } = useAccount();
13719
- const address = account5.address;
14366
+ const { account: account7 } = useAccount();
14367
+ const address = account7.address;
13720
14368
  const path2 = type === "normal" /* normal */ ? `/v1/public/trading_rewards/wallet_rewards_history?address=${address}` : `/v1/public/market_making_rewards/group_rewards_history?address=${address}`;
13721
14369
  const {
13722
14370
  data,
@@ -13738,11 +14386,36 @@ var useWalletRewardsHistory = (type) => {
13738
14386
  });
13739
14387
  return [data, { refresh, error }];
13740
14388
  };
14389
+
14390
+ // src/trading-rewards/useTradingRwardsStatus.tsx
14391
+ var EpochStatus = /* @__PURE__ */ ((EpochStatus2) => {
14392
+ EpochStatus2["active"] = "Active";
14393
+ EpochStatus2["paused"] = "Paused";
14394
+ EpochStatus2["ended"] = "Ended";
14395
+ return EpochStatus2;
14396
+ })(EpochStatus || {});
14397
+ function useTradingRewardsStatus(isMMRewards) {
14398
+ const path2 = isMMRewards ? "/v1/public/market_making_rewards/status" : "/v1/public/trading_rewards/status";
14399
+ const { data: statusInfo } = useQuery(path2, {
14400
+ formatter: (res) => {
14401
+ const data = {
14402
+ ...res,
14403
+ epochStatus: res.epoch_status,
14404
+ currentEpoch: res.current_epoch,
14405
+ lastCompletedEpoch: res.last_completed_epoch
14406
+ };
14407
+ return data;
14408
+ }
14409
+ });
14410
+ return {
14411
+ statusInfo
14412
+ };
14413
+ }
13741
14414
  var useApiKeyManager = (queryParams) => {
13742
- const { account: account5 } = useAccount();
14415
+ const { account: account7, state, isSubAccount } = useAccount();
13743
14416
  const { keyInfo } = queryParams || {};
13744
14417
  const keyInfoPrams = getQueryParamsFromObject(keyInfo);
13745
- const { data, mutate: mutate3, error, isLoading } = usePrivateQuery(
14418
+ const { data, mutate: mutate5, error, isLoading } = usePrivateQuery(
13746
14419
  `/v1/client/key_info${keyInfoPrams.length > 0 ? `?${keyInfoPrams}` : ""}`,
13747
14420
  {
13748
14421
  formatter: (data2) => data2?.rows
@@ -13775,7 +14448,14 @@ var useApiKeyManager = (queryParams) => {
13775
14448
  });
13776
14449
  }, []);
13777
14450
  const generateOrderlyKey = (scope) => {
13778
- return account5?.createApiKey(365, {
14451
+ if (isSubAccount) {
14452
+ return account7?.createSubAccountApiKey(365, {
14453
+ tag: "manualCreated",
14454
+ scope,
14455
+ subAccountId: state.accountId
14456
+ });
14457
+ }
14458
+ return account7?.createApiKey(365, {
13779
14459
  tag: "manualCreated",
13780
14460
  scope
13781
14461
  });
@@ -13789,7 +14469,7 @@ var useApiKeyManager = (queryParams) => {
13789
14469
  return [
13790
14470
  data,
13791
14471
  {
13792
- refresh: mutate3,
14472
+ refresh: mutate5,
13793
14473
  error,
13794
14474
  isLoading,
13795
14475
  generateOrderlyKey,
@@ -13900,7 +14580,7 @@ var calcEstLiqPrice = (order$1, askAndBid, inputs) => {
13900
14580
  markPrice,
13901
14581
  totalCollateral,
13902
14582
  futures_taker_fee_rate,
13903
- positions: positions2
14583
+ positions: positions3
13904
14584
  } = inputs;
13905
14585
  const orderFee = order.orderFee({
13906
14586
  qty: quantity,
@@ -13912,7 +14592,7 @@ var calcEstLiqPrice = (order$1, askAndBid, inputs) => {
13912
14592
  baseIMR,
13913
14593
  baseMMR,
13914
14594
  totalCollateral,
13915
- positions: positions2 == null ? [] : positions2,
14595
+ positions: positions3 == null ? [] : positions3,
13916
14596
  IMR_Factor: imr_factor,
13917
14597
  orderFee,
13918
14598
  newOrder: {
@@ -13927,7 +14607,7 @@ var calcEstLiqPrice = (order$1, askAndBid, inputs) => {
13927
14607
  };
13928
14608
  var calcEstLeverage = (order$1, askAndBid, inputs) => {
13929
14609
  const result = getPriceAndQty(order$1, askAndBid);
13930
- const { totalCollateral, positions: positions2, symbol } = inputs;
14610
+ const { totalCollateral, positions: positions3, symbol } = inputs;
13931
14611
  if (!result)
13932
14612
  return null;
13933
14613
  const { price, quantity } = result;
@@ -13935,7 +14615,7 @@ var calcEstLeverage = (order$1, askAndBid, inputs) => {
13935
14615
  return null;
13936
14616
  return order.estLeverage({
13937
14617
  totalCollateral,
13938
- positions: positions2,
14618
+ positions: positions3,
13939
14619
  newOrder: {
13940
14620
  symbol,
13941
14621
  qty: result.quantity,
@@ -14029,7 +14709,7 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
14029
14709
  ...options.initialOrder
14030
14710
  };
14031
14711
  const { actions: orderEntryActions, entry: orderEntity } = useOrderStore(initialOrder);
14032
- const calculate = useCallback(
14712
+ const calculate2 = useCallback(
14033
14713
  (values2, fieldName, value, markPrice, config) => {
14034
14714
  const fieldHandler = getCalculateHandler(fieldName);
14035
14715
  const newValues = compose(
@@ -14051,7 +14731,7 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
14051
14731
  return;
14052
14732
  }
14053
14733
  const { markPrice } = additional ?? { markPrice: 0 };
14054
- let newValues = calculate(
14734
+ let newValues = calculate2(
14055
14735
  { ...orderEntity },
14056
14736
  key,
14057
14737
  value,
@@ -14060,7 +14740,7 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
14060
14740
  );
14061
14741
  if (key === "order_type") {
14062
14742
  if (value === OrderType.MARKET || value === OrderType.STOP_MARKET) {
14063
- newValues = calculate(
14743
+ newValues = calculate2(
14064
14744
  newValues,
14065
14745
  "order_price",
14066
14746
  markPrice,
@@ -14094,7 +14774,7 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
14094
14774
  const calculateTPSL = (key, newValues, markPrice, symbolInfo2) => {
14095
14775
  if (key === "order_price") {
14096
14776
  if (typeof newValues.tp_pnl !== "undefined") {
14097
- newValues = calculate(
14777
+ newValues = calculate2(
14098
14778
  newValues,
14099
14779
  "tp_pnl",
14100
14780
  newValues.tp_pnl,
@@ -14103,7 +14783,7 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
14103
14783
  );
14104
14784
  }
14105
14785
  if (typeof newValues.sl_pnl !== "undefined") {
14106
- newValues = calculate(
14786
+ newValues = calculate2(
14107
14787
  newValues,
14108
14788
  "sl_pnl",
14109
14789
  newValues.sl_pnl,
@@ -14113,7 +14793,7 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
14113
14793
  }
14114
14794
  } else {
14115
14795
  if (typeof newValues.tp_trigger_price !== "undefined") {
14116
- newValues = calculate(
14796
+ newValues = calculate2(
14117
14797
  newValues,
14118
14798
  "tp_trigger_price",
14119
14799
  newValues.tp_trigger_price,
@@ -14122,7 +14802,7 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
14122
14802
  );
14123
14803
  }
14124
14804
  if (typeof newValues.sl_trigger_price !== "undefined") {
14125
- newValues = calculate(
14805
+ newValues = calculate2(
14126
14806
  newValues,
14127
14807
  "sl_trigger_price",
14128
14808
  newValues.sl_trigger_price,
@@ -14140,7 +14820,7 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
14140
14820
  }
14141
14821
  let newValues = { ...orderEntity };
14142
14822
  Object.keys(values2).forEach((key) => {
14143
- newValues = calculate(
14823
+ newValues = calculate2(
14144
14824
  newValues,
14145
14825
  key,
14146
14826
  values2[key],
@@ -14157,7 +14837,7 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
14157
14837
  return;
14158
14838
  let newValues = { ...orderEntity };
14159
14839
  if (baseOn.length === 0) {
14160
- newValues = calculate(
14840
+ newValues = calculate2(
14161
14841
  { ...orderEntity },
14162
14842
  "order_price",
14163
14843
  markPrice,
@@ -14166,7 +14846,7 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
14166
14846
  );
14167
14847
  } else {
14168
14848
  baseOn.forEach((key) => {
14169
- newValues = calculate(
14849
+ newValues = calculate2(
14170
14850
  { ...newValues },
14171
14851
  key,
14172
14852
  orderEntity[key],
@@ -14193,14 +14873,15 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
14193
14873
  }
14194
14874
  orderEntryActions.updateOrder(newValues);
14195
14875
  },
14196
- [calculate, options.symbolInfo, orderEntity, orderEntryActions]
14876
+ [calculate2, options.symbolInfo, orderEntity, orderEntryActions]
14197
14877
  );
14198
14878
  const validate = (order, creator, options2) => {
14199
- const { markPrice, maxQty } = options2;
14879
+ const { markPrice, maxQty, estSlippage } = options2;
14200
14880
  return creator?.validate(order, {
14201
14881
  symbol: symbolInfo,
14202
14882
  maxQty,
14203
- markPrice
14883
+ markPrice,
14884
+ estSlippage
14204
14885
  });
14205
14886
  };
14206
14887
  const generateOrder = (creator, options2) => {
@@ -14251,7 +14932,7 @@ var useOrderEntry2 = (symbol, options = {}) => {
14251
14932
  const actions = useMarkPriceActions();
14252
14933
  const symbolConfig = useSymbolsInfo();
14253
14934
  const accountInfo = useAccountInfo();
14254
- const positions2 = usePositions();
14935
+ const positions3 = usePositions();
14255
14936
  const symbolInfo = symbolConfig[symbol]();
14256
14937
  const markPrice = actions.getMarkPriceBySymbol(symbol);
14257
14938
  const {
@@ -14267,6 +14948,7 @@ var useOrderEntry2 = (symbol, options = {}) => {
14267
14948
  ...options,
14268
14949
  symbolInfo
14269
14950
  });
14951
+ const [estSlippage, setEstSlippage] = useState(null);
14270
14952
  const [doCreateOrder, { isMutating }] = useMutation(
14271
14953
  getCreateOrderUrl(formattedOrder)
14272
14954
  );
@@ -14300,12 +14982,61 @@ var useOrderEntry2 = (symbol, options = {}) => {
14300
14982
  updateOrderPrice();
14301
14983
  }
14302
14984
  };
14985
+ const updateEstSlippage = (orderBook) => {
14986
+ if (formattedOrder.order_type !== OrderType.MARKET || !formattedOrder.order_quantity) {
14987
+ setEstSlippage(null);
14988
+ return;
14989
+ }
14990
+ const { order_quantity, side } = formattedOrder;
14991
+ let avgExecutionPrice;
14992
+ let book;
14993
+ const filledBorders = [];
14994
+ let orderQuantity = new Decimal(order_quantity);
14995
+ if (side === OrderSide.BUY) {
14996
+ book = orderBook.asks.reverse();
14997
+ } else {
14998
+ book = orderBook.bids;
14999
+ }
15000
+ for (let i = 0; i < book.length; i++) {
15001
+ const price = book[i][0];
15002
+ const quantity = book[i][1];
15003
+ if (isNaN(price) || isNaN(quantity)) {
15004
+ continue;
15005
+ }
15006
+ if (orderQuantity.gt(quantity)) {
15007
+ orderQuantity = orderQuantity.minus(quantity);
15008
+ filledBorders.push([price, quantity]);
15009
+ } else {
15010
+ filledBorders.push([price, orderQuantity.toNumber()]);
15011
+ break;
15012
+ }
15013
+ }
15014
+ if (filledBorders.length > 0) {
15015
+ const sumPrice = filledBorders.reduce((acc, curr) => {
15016
+ return acc.plus(new Decimal(curr[0]).mul(curr[1]));
15017
+ }, zero);
15018
+ avgExecutionPrice = sumPrice.div(order_quantity);
15019
+ }
15020
+ if (avgExecutionPrice) {
15021
+ const bestPrice = book[0][0];
15022
+ const estSlippage2 = avgExecutionPrice.minus(bestPrice).abs().div(bestPrice).toNumber();
15023
+ setEstSlippage(estSlippage2);
15024
+ }
15025
+ };
14303
15026
  useEffect(() => {
14304
15027
  updateOrderPrice();
14305
15028
  }, [formattedOrder.order_type_ext, formattedOrder.level]);
14306
15029
  const onOrderBookUpdate = useDebouncedCallback((data) => {
14307
- askAndBid.current = data;
15030
+ const parsedData = [
15031
+ [data.asks?.[data.asks.length - 1]?.[0], data.bids?.[0]?.[0]],
15032
+ [data.asks?.[data.asks.length - 2]?.[0], data.bids?.[1]?.[0]],
15033
+ [data.asks?.[data.asks.length - 3]?.[0], data.bids?.[2]?.[0]],
15034
+ [data.asks?.[data.asks.length - 4]?.[0], data.bids?.[3]?.[0]],
15035
+ [data.asks?.[data.asks.length - 5]?.[0], data.bids?.[4]?.[0]]
15036
+ ];
15037
+ askAndBid.current = parsedData;
14308
15038
  updateOrderPriceByOrderBook();
15039
+ updateEstSlippage(data);
14309
15040
  }, 200);
14310
15041
  useEffect(() => {
14311
15042
  ee.on("orderbook:update", onOrderBookUpdate);
@@ -14331,9 +15062,10 @@ var useOrderEntry2 = (symbol, options = {}) => {
14331
15062
  const prepareData = useCallback(() => {
14332
15063
  return {
14333
15064
  markPrice: actions.getMarkPriceBySymbol(symbol),
14334
- maxQty
15065
+ maxQty,
15066
+ estSlippage
14335
15067
  };
14336
- }, [maxQty, symbol]);
15068
+ }, [maxQty, symbol, estSlippage]);
14337
15069
  const interactiveValidate = (order) => {
14338
15070
  validateFunc(order).then((errors) => {
14339
15071
  const keys = Object.keys(errors);
@@ -14445,10 +15177,10 @@ var useOrderEntry2 = (symbol, options = {}) => {
14445
15177
  futures_taker_fee_rate: accountInfo.futures_taker_fee_rate,
14446
15178
  imr_factor: accountInfo.imr_factor[symbol],
14447
15179
  symbol,
14448
- positions: positions2
15180
+ positions: positions3
14449
15181
  });
14450
15182
  return estLiqPrice2;
14451
- }, [formattedOrder, accountInfo, positions2, totalCollateral, symbol, maxQty]);
15183
+ }, [formattedOrder, accountInfo, positions3, totalCollateral, symbol, maxQty]);
14452
15184
  const estLeverage = useMemo(() => {
14453
15185
  const orderQuantity = Number(formattedOrder.order_quantity);
14454
15186
  if (orderQuantity === 0 || orderQuantity > maxQty) {
@@ -14456,10 +15188,10 @@ var useOrderEntry2 = (symbol, options = {}) => {
14456
15188
  }
14457
15189
  return calcEstLeverage(formattedOrder, askAndBid.current[0], {
14458
15190
  totalCollateral,
14459
- positions: positions2,
15191
+ positions: positions3,
14460
15192
  symbol
14461
15193
  });
14462
- }, [formattedOrder, accountInfo, positions2, totalCollateral, symbol, maxQty]);
15194
+ }, [formattedOrder, accountInfo, positions3, totalCollateral, symbol, maxQty]);
14463
15195
  const resetErrors = () => {
14464
15196
  setMeta(
14465
15197
  produce((draft) => {
@@ -14521,6 +15253,7 @@ var useOrderEntry2 = (symbol, options = {}) => {
14521
15253
  maxQty,
14522
15254
  estLiqPrice,
14523
15255
  estLeverage,
15256
+ estSlippage,
14524
15257
  helper: {
14525
15258
  /**
14526
15259
  * @deprecated use validate instead
@@ -14751,7 +15484,96 @@ var useRestrictedInfo = (options) => {
14751
15484
  content
14752
15485
  };
14753
15486
  };
15487
+ var usePositionClose = (options) => {
15488
+ const { position, order: initialOrder } = options;
15489
+ const { type, quantity, price } = initialOrder;
15490
+ const symbol = position.symbol;
15491
+ const [errors, setErrors] = useState(null);
15492
+ const symbolsInfo = useSymbolsInfo();
15493
+ const { data: markPrices } = useMarkPricesStream();
15494
+ const [doCreateOrder, { isMutating }] = useSubAccountMutation(
15495
+ "/v1/order",
15496
+ "POST",
15497
+ {
15498
+ accountId: position.account_id
15499
+ }
15500
+ );
15501
+ const side = position.position_qty > 0 ? OrderSide.SELL : OrderSide.BUY;
15502
+ const closeOrderData = useMemo(() => {
15503
+ const data = {
15504
+ order_quantity: quantity,
15505
+ symbol,
15506
+ order_type: type,
15507
+ side,
15508
+ reduce_only: true
15509
+ };
15510
+ if (type === OrderType.LIMIT) {
15511
+ data.order_price = price;
15512
+ }
15513
+ return data;
15514
+ }, [symbol, price, type, quantity]);
15515
+ const maxQty = useMemo(() => {
15516
+ if (!position) {
15517
+ return 0;
15518
+ }
15519
+ const positionQty = position.position_qty;
15520
+ if (positionQty > 0) {
15521
+ if (side === OrderSide.BUY) {
15522
+ return 0;
15523
+ } else {
15524
+ return Math.abs(positionQty);
15525
+ }
15526
+ }
15527
+ if (positionQty < 0) {
15528
+ if (side === OrderSide.BUY) {
15529
+ return Math.abs(positionQty);
15530
+ } else {
15531
+ return 0;
15532
+ }
15533
+ }
15534
+ return 0;
15535
+ }, [position, side]);
15536
+ const validate = useCallback(
15537
+ async (data) => {
15538
+ const creator = getOrderCreator(data);
15539
+ const errors2 = await creator.validate(data, {
15540
+ symbol: symbolsInfo[symbol](),
15541
+ maxQty,
15542
+ markPrice: markPrices[symbol]
15543
+ });
15544
+ return errors2;
15545
+ },
15546
+ [markPrices, maxQty, symbol, symbolsInfo]
15547
+ );
15548
+ useEffect(() => {
15549
+ validate(closeOrderData).then((errors2) => {
15550
+ setErrors(errors2);
15551
+ });
15552
+ }, [validate, closeOrderData]);
15553
+ const submit = useCallback(async () => {
15554
+ const errors2 = await validate(closeOrderData);
15555
+ if (Object.keys(errors2).length > 0) {
15556
+ throw errors2;
15557
+ }
15558
+ return doCreateOrder(closeOrderData).then((res) => {
15559
+ if (res.success) {
15560
+ return res;
15561
+ }
15562
+ throw res;
15563
+ }).catch((err) => {
15564
+ throw err;
15565
+ });
15566
+ }, [validate, doCreateOrder, closeOrderData]);
15567
+ return {
15568
+ submit,
15569
+ isMutating,
15570
+ side,
15571
+ closeOrderData,
15572
+ errors,
15573
+ calculate
15574
+ };
15575
+ };
14754
15576
 
14755
- export { AssetHistoryStatusEnum, DefaultLayoutConfig, DistributionId, ENVType2 as ENVType, ExtendedConfigStore, MaintenanceStatus, MarketsStorageKey, MarketsType, OrderlyConfigProvider, OrderlyContext, OrderlyProvider, StatusContext, StatusProvider, TWType, WalletConnectorContext, WsNetworkStatus, checkNotional, cleanStringStyle, getMinNotional, 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, useInfiniteQuery, 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, useRestrictedInfo, useSessionStorage, useSettleSubscription, useSimpleDI, useStatisticsDaily, useStorageChain, useStorageLedgerAddress, useSymbolLeverage, useSymbolPriceRange, useSymbolsInfo, useTPSLOrder, useTickerStream, useTrack, useTrackingInstance, useWS, useWalletConnector, useWalletRewardsHistory, useWalletSubscription, useWithdraw, useWsStatus, utils_exports as utils, version_default as version };
15577
+ export { AssetHistoryStatusEnum, DefaultLayoutConfig, DistributionId, ENVType2 as ENVType, EpochStatus, ExtendedConfigStore, MaintenanceStatus, MarketsStorageKey, MarketsType, OrderlyConfigProvider, OrderlyContext, OrderlyProvider, StatusContext, StatusProvider, TWType, WalletConnectorContext, WsNetworkStatus, checkNotional, cleanStringStyle, fetcher, getMinNotional, 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, useFundingRatesStore, useGetClaimed, useGetEnv, useGetReferralCode, useHoldingStream, useIndexPrice, useIndexPricesStream, useInfiniteQuery, 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, usePositionClose, usePositionStream, usePoster, usePreLoadData, usePrivateDataObserver, usePrivateInfiniteQuery, usePrivateQuery, useQuery, useRefereeHistory, useRefereeInfo, useRefereeRebateSummary, useReferralInfo, useReferralRebateSummary, useRestrictedInfo, useSessionStorage, useSettleSubscription, useSimpleDI, useStatisticsDaily, useStorageChain, useStorageLedgerAddress, useSubAccountDataObserver, useSubAccountMutation, useSubAccountQuery, useSubAccountWS, useSymbolLeverage, useSymbolPriceRange, useSymbolsInfo, useSymbolsInfoStore, useTPSLOrder, useTickerStream, useTrack, useTrackingInstance, useTradingRewardsStatus, useTransfer, useTransferHistory, useWS, useWalletConnector, useWalletRewardsHistory, useWalletSubscription, useWithdraw, useWsStatus, utils_exports as utils, version_default as version };
14756
15578
  //# sourceMappingURL=out.js.map
14757
15579
  //# sourceMappingURL=index.mjs.map