@orderly.network/hooks 2.3.2 → 2.4.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
@@ -3,7 +3,7 @@ import useSWR__default, { mutate } from 'swr';
3
3
  import * as useSWR from 'swr';
4
4
  export { useSWR as swr };
5
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';
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, DistributionType, TriggerPriceType } from '@orderly.network/types';
7
7
  import React, { createContext, useContext, useCallback, useState, useEffect, useMemo, useRef, useId, useLayoutEffect } from 'react';
8
8
  import useSWRMutation from 'swr/mutation';
9
9
  import useConstant from 'use-constant';
@@ -36,9 +36,9 @@ var __export = (target, all) => {
36
36
  // src/version.ts
37
37
  if (typeof window !== "undefined") {
38
38
  window.__ORDERLY_VERSION__ = window.__ORDERLY_VERSION__ || {};
39
- window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "2.3.2";
39
+ window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "2.4.0";
40
40
  }
41
- var version_default = "2.3.2";
41
+ var version_default = "2.4.0";
42
42
  var fetcher = (url, init2 = {}, queryOptions) => get(url, init2, queryOptions?.formatter);
43
43
  var OrderlyContext = createContext({
44
44
  // configStore: new MemoryConfigStore(),
@@ -243,7 +243,8 @@ var useTrack = () => {
243
243
  page_title: title,
244
244
  page_url: url,
245
245
  page_domain: origin,
246
- user_agent: userAgent
246
+ user_agent: userAgent,
247
+ sdk_version: window?.__ORDERLY_VERSION__?.["@orderly.network/net"] ?? ""
247
248
  });
248
249
  if (eventName === TrackerEventName.placeOrderSuccess) {
249
250
  Object.assign(params, {
@@ -4175,7 +4176,7 @@ function fillChainsInfo(chains, filter, chainInfos) {
4175
4176
  return _chains;
4176
4177
  }
4177
4178
  function filterAndUpdateChains(chains, chainInfos, filter, isTestNet) {
4178
- const filterChains = [];
4179
+ const chainsMap = /* @__PURE__ */ new Map();
4179
4180
  chains.forEach((chain) => {
4180
4181
  const _chain = { ...chain };
4181
4182
  const networkInfo = chainInfos?.find(
@@ -4200,10 +4201,10 @@ function filterAndUpdateChains(chains, chainInfos, filter, isTestNet) {
4200
4201
  return;
4201
4202
  }
4202
4203
  if (networkInfo) {
4203
- filterChains.push(_chain);
4204
+ chainsMap.set(chain.network_infos.chain_id, _chain);
4204
4205
  }
4205
4206
  });
4206
- return filterChains;
4207
+ return Array.from(chainsMap.values());
4207
4208
  }
4208
4209
  function filterByAllowedChains(chains, allowedChains) {
4209
4210
  if (!allowedChains) {
@@ -4887,12 +4888,11 @@ var useSymbolPriceRange = (symbol, side, price) => {
4887
4888
  };
4888
4889
  function getMinNotional(props) {
4889
4890
  const { price, base_tick, qty, min_notional, base_dp, quote_dp, quote_tick } = props;
4890
- if (price !== void 0 && qty !== void 0 && min_notional !== void 0) {
4891
+ if (price && qty && min_notional) {
4891
4892
  try {
4892
- const calcNotional = new Decimal(price).mul(new Decimal(qty)).toNumber();
4893
- const notional = Number.parseFloat(`${min_notional}`);
4894
- if (calcNotional < notional) {
4895
- let minQty = new Decimal(notional).div(price).toDecimalPlaces(base_dp, Decimal.ROUND_DOWN).add(base_tick ?? 0);
4893
+ const calcMinNotional = new Decimal(price).mul(new Decimal(qty));
4894
+ if (calcMinNotional.lt(min_notional)) {
4895
+ let minQty = new Decimal(min_notional).div(price).toDecimalPlaces(base_dp, Decimal.ROUND_DOWN).add(base_tick ?? 0);
4896
4896
  if (base_tick && base_tick > 0) {
4897
4897
  minQty = new Decimal(
4898
4898
  getRoundedDownDivision(minQty.toNumber(), base_tick)
@@ -4950,6 +4950,14 @@ var OrderValidation = class {
4950
4950
  return "TP price";
4951
4951
  case "sl_trigger_price":
4952
4952
  return "SL price";
4953
+ case "max_price":
4954
+ return "Upper price";
4955
+ case "min_price":
4956
+ return "Lower price";
4957
+ case "total_orders":
4958
+ return "Total orders";
4959
+ case "skew":
4960
+ return "Skew";
4953
4961
  default:
4954
4962
  return key;
4955
4963
  }
@@ -4974,6 +4982,14 @@ var OrderValidation = class {
4974
4982
  value
4975
4983
  };
4976
4984
  }
4985
+ static range(key, min3, max3) {
4986
+ return {
4987
+ type: "range",
4988
+ message: `${this.getLabel(key)} must be in the range of ${min3} to ${max3}`,
4989
+ min: min3,
4990
+ max: max3
4991
+ };
4992
+ }
4977
4993
  };
4978
4994
 
4979
4995
  // src/services/orderCreator/baseCreator.ts
@@ -5176,33 +5192,33 @@ var BaseOrderCreator = class {
5176
5192
  }
5177
5193
  };
5178
5194
 
5179
- // src/services/orderCreator/marketOrderCreator.ts
5180
- var MarketOrderCreator = class extends BaseOrderCreator {
5195
+ // src/services/orderCreator/bboOrderCreator.ts
5196
+ var BBOOrderCreator = class extends BaseOrderCreator {
5197
+ constructor() {
5198
+ super(...arguments);
5199
+ this.orderType = OrderType.LIMIT;
5200
+ }
5181
5201
  create(values2) {
5182
- const data = this.baseOrder(values2);
5183
- delete data["order_price"];
5184
- delete data["total"];
5185
- delete data["trigger_price"];
5186
- delete data["isStopOrder"];
5187
- return {
5188
- ...data
5202
+ const order = {
5203
+ ...this.baseOrder(values2),
5204
+ level: values2.level
5189
5205
  };
5206
+ return pick(
5207
+ [
5208
+ "symbol",
5209
+ "order_quantity",
5210
+ "visible_quantity",
5211
+ "reduce_only",
5212
+ "side",
5213
+ "order_type",
5214
+ "level"
5215
+ ],
5216
+ order
5217
+ );
5190
5218
  }
5191
- validate(values2, configs) {
5192
- return this.baseValidate(values2, configs).then((result) => {
5193
- const slippage = Number(values2.slippage);
5194
- const estSlippage = Number.isNaN(configs.estSlippage) ? 0 : Number(configs.estSlippage) * 100;
5195
- if (!isNaN(slippage) && estSlippage > slippage) {
5196
- return {
5197
- ...result,
5198
- slippage: {
5199
- type: "max",
5200
- message: "Estimated slippage exceeds your maximum allowed slippage.",
5201
- value: estSlippage
5202
- }
5203
- };
5204
- }
5205
- return result;
5219
+ async validate(values2, configs) {
5220
+ return this.baseValidate(values2, configs).then((errors) => {
5221
+ return errors;
5206
5222
  });
5207
5223
  }
5208
5224
  };
@@ -5281,124 +5297,791 @@ var LimitOrderCreator = class extends BaseOrderCreator {
5281
5297
  });
5282
5298
  }
5283
5299
  };
5284
- var { maxPrice: maxPrice2, minPrice: minPrice2, scopePrice: scopePrice2 } = order;
5285
- var StopLimitOrderCreator = class extends BaseOrderCreator {
5286
- constructor() {
5287
- super(...arguments);
5288
- this.orderType = OrderType.STOP_LIMIT;
5300
+ async function bracketOrderValidator(values2, config) {
5301
+ const result = /* @__PURE__ */ Object.create(null);
5302
+ await Promise.resolve();
5303
+ const { tp_trigger_price, sl_trigger_price, side } = values2;
5304
+ const qty = Number(values2.quantity);
5305
+ const maxQty = config.maxQty;
5306
+ const type = values2.order_type;
5307
+ const { quote_max, quote_min, price_scope, quote_dp } = config.symbol ?? {};
5308
+ const mark_price = type === OrderType.MARKET ? config.markPrice : values2.order_price ? Number(values2.order_price) : void 0;
5309
+ if (!isNaN(qty) && qty > maxQty) {
5310
+ result.quantity = OrderValidation.max("quantity", config.maxQty);
5289
5311
  }
5290
- create(values2, config) {
5291
- this.totalToQuantity(values2, config);
5292
- const order = {
5293
- ...this.baseOrder(values2),
5294
- trigger_price: values2.trigger_price,
5295
- algo_type: AlgoOrderRootType.STOP,
5296
- type: OrderType.LIMIT,
5297
- quantity: values2["order_quantity"],
5298
- price: values2["order_price"],
5299
- trigger_price_type: TriggerPriceType.MARK_PRICE
5300
- };
5301
- return pick(
5302
- [
5303
- "symbol",
5304
- "trigger_price",
5305
- "algo_type",
5306
- "type",
5307
- "quantity",
5308
- "price",
5309
- "trigger_price_type",
5310
- "side",
5311
- "reduce_only",
5312
- "visible_quantity"
5313
- ],
5314
- order
5315
- );
5312
+ if (Number(tp_trigger_price) < 0) {
5313
+ result.tp_trigger_price = OrderValidation.min("tp_trigger_price", 0);
5316
5314
  }
5317
- validate(values2, config) {
5318
- return this.baseValidate(values2, config).then((errors) => {
5319
- const { order_price, trigger_price, side } = values2;
5320
- const { symbol } = config;
5321
- const { price_range, price_scope, quote_max, quote_min } = symbol;
5322
- if (!trigger_price) {
5323
- errors.trigger_price = OrderValidation.required("trigger_price");
5324
- }
5325
- if (!order_price) {
5326
- errors.order_price = OrderValidation.required("order_price");
5327
- }
5328
- if (trigger_price > quote_max) {
5329
- errors.trigger_price = OrderValidation.max("trigger_price", quote_max);
5330
- } else if (trigger_price < quote_min) {
5331
- errors.trigger_price = OrderValidation.min("trigger_price", quote_min);
5332
- } else {
5333
- if (trigger_price && order_price) {
5334
- const price = new Decimal(order_price);
5335
- const maxPriceNumber = maxPrice2(trigger_price, price_range);
5336
- const minPriceNumber = minPrice2(trigger_price, price_range);
5337
- const scropePriceNumbere = scopePrice2(
5338
- trigger_price,
5339
- price_scope,
5340
- side
5341
- );
5342
- const priceRange = side === "BUY" ? {
5343
- min: scropePriceNumbere,
5344
- max: maxPriceNumber
5345
- } : {
5346
- min: minPriceNumber,
5347
- max: scropePriceNumbere
5348
- };
5349
- if (price.gt(quote_max)) {
5350
- errors.order_price = OrderValidation.max("order_price", quote_max);
5351
- } else {
5352
- if (price.gt(priceRange?.max)) {
5353
- errors.order_price = OrderValidation.max(
5354
- "order_price",
5355
- new Decimal(priceRange.max).todp(symbol.quote_dp).toString()
5356
- );
5357
- }
5358
- }
5359
- if (price.lt(quote_min)) {
5360
- errors.order_price = OrderValidation.min("order_price", quote_min);
5361
- } else {
5362
- if (price.lt(priceRange?.min)) {
5363
- errors.order_price = OrderValidation.min(
5364
- "order_price",
5365
- new Decimal(priceRange.min).todp(symbol.quote_dp).toString()
5366
- );
5367
- }
5368
- }
5369
- }
5370
- }
5371
- return errors;
5372
- });
5315
+ if (Number(sl_trigger_price) < 0) {
5316
+ result.sl_trigger_price = OrderValidation.min("sl_trigger_price", 0);
5373
5317
  }
5374
- };
5318
+ if (side === OrderSide.BUY && mark_price) {
5319
+ const slTriggerPriceScope = new Decimal(mark_price * (1 - price_scope)).toDecimalPlaces(quote_dp, Decimal.ROUND_DOWN).toNumber();
5320
+ if (!!sl_trigger_price && Number(sl_trigger_price) < slTriggerPriceScope) {
5321
+ result.sl_trigger_price = OrderValidation.min(
5322
+ "sl_trigger_price",
5323
+ slTriggerPriceScope
5324
+ );
5325
+ }
5326
+ if (!!tp_trigger_price && Number(tp_trigger_price) <= mark_price) {
5327
+ result.tp_trigger_price = OrderValidation.min(
5328
+ "tp_trigger_price",
5329
+ mark_price
5330
+ );
5331
+ }
5332
+ if (!!tp_trigger_price && Number(tp_trigger_price) > quote_max) {
5333
+ result.tp_trigger_price = OrderValidation.max(
5334
+ "tp_trigger_price",
5335
+ quote_max
5336
+ );
5337
+ }
5338
+ if (!!sl_trigger_price && Number(sl_trigger_price) < quote_min) {
5339
+ result.sl_trigger_price = OrderValidation.min(
5340
+ "sl_trigger_price",
5341
+ quote_min
5342
+ );
5343
+ }
5344
+ }
5345
+ if (side === OrderSide.SELL && mark_price) {
5346
+ const slTriggerPriceScope = new Decimal(mark_price * (1 + price_scope)).toDecimalPlaces(quote_dp, Decimal.ROUND_DOWN).toNumber();
5347
+ if (!!sl_trigger_price && Number(sl_trigger_price) > slTriggerPriceScope) {
5348
+ result.sl_trigger_price = OrderValidation.max(
5349
+ "sl_trigger_price",
5350
+ slTriggerPriceScope
5351
+ );
5352
+ }
5353
+ if (!!tp_trigger_price && Number(tp_trigger_price) >= mark_price) {
5354
+ result.tp_trigger_price = OrderValidation.max(
5355
+ "tp_trigger_price",
5356
+ mark_price
5357
+ );
5358
+ }
5359
+ if (!!tp_trigger_price && Number(tp_trigger_price) > quote_max) {
5360
+ result.tp_trigger_price = OrderValidation.max(
5361
+ "tp_trigger_price",
5362
+ quote_max
5363
+ );
5364
+ }
5365
+ if (!!sl_trigger_price && Number(sl_trigger_price) < quote_min) {
5366
+ result.sl_trigger_price = OrderValidation.min(
5367
+ "sl_trigger_price",
5368
+ quote_min
5369
+ );
5370
+ }
5371
+ }
5372
+ return Object.keys(result).length > 0 ? result : null;
5373
+ }
5375
5374
 
5376
- // src/services/orderCreator/generalCreator.ts
5377
- var GeneralOrderCreator = class extends BaseOrderCreator {
5378
- create(data) {
5375
+ // src/services/orderCreator/bracketLimitOrderCreator.ts
5376
+ var BracketLimitOrderCreator = class extends LimitOrderCreator {
5377
+ // orderType: OrderType;
5378
+ create(values2, config) {
5379
+ const order = super.create(values2, config);
5379
5380
  return {
5380
- ...this.baseOrder(data),
5381
- order_price: data.order_price,
5382
- order_quantity: data.order_quantity
5381
+ ...order,
5382
+ quantity: order.order_quantity,
5383
+ type: order.order_type,
5384
+ price: order.order_price
5383
5385
  };
5384
5386
  }
5385
- validate(values2, configs) {
5386
- return super.baseValidate(values2, configs);
5387
+ async validate(values2, config) {
5388
+ const value = await super.validate(values2, config);
5389
+ const bracketData = await bracketOrderValidator(values2, config);
5390
+ return { ...value, ...bracketData };
5387
5391
  }
5388
5392
  };
5389
- var StopMarketOrderCreator = class extends BaseOrderCreator {
5393
+
5394
+ // src/services/orderCreator/marketOrderCreator.ts
5395
+ var MarketOrderCreator = class extends BaseOrderCreator {
5390
5396
  create(values2) {
5391
- const order = {
5392
- ...this.baseOrder(values2),
5393
- // order_price: values.order_price,
5394
- trigger_price: values2.trigger_price,
5395
- algo_type: AlgoOrderRootType.STOP,
5396
- type: OrderType.MARKET,
5397
- quantity: values2["order_quantity"],
5398
- // price: values["order_price"],
5399
- trigger_price_type: TriggerPriceType.MARK_PRICE
5397
+ const data = this.baseOrder(values2);
5398
+ delete data["order_price"];
5399
+ delete data["total"];
5400
+ delete data["trigger_price"];
5401
+ delete data["isStopOrder"];
5402
+ return {
5403
+ ...data
5400
5404
  };
5401
- return pick(
5405
+ }
5406
+ validate(values2, configs) {
5407
+ return this.baseValidate(values2, configs).then((result) => {
5408
+ const slippage = Number(values2.slippage);
5409
+ const estSlippage = Number.isNaN(configs.estSlippage) ? 0 : Number(configs.estSlippage) * 100;
5410
+ if (!isNaN(slippage) && estSlippage > slippage) {
5411
+ return {
5412
+ ...result,
5413
+ slippage: {
5414
+ type: "max",
5415
+ message: "Estimated slippage exceeds your maximum allowed slippage.",
5416
+ value: estSlippage
5417
+ }
5418
+ };
5419
+ }
5420
+ return result;
5421
+ });
5422
+ }
5423
+ };
5424
+
5425
+ // src/services/orderCreator/bracketMarketOrderCreator.ts
5426
+ var BracketMarketOrderCreator = class extends MarketOrderCreator {
5427
+ constructor() {
5428
+ super(...arguments);
5429
+ this.orderType = OrderType.MARKET;
5430
+ }
5431
+ create(values2) {
5432
+ const order = super.create(values2);
5433
+ return {
5434
+ ...order,
5435
+ quantity: order.order_quantity,
5436
+ type: order.order_type,
5437
+ price: order.order_price
5438
+ };
5439
+ }
5440
+ async validate(values2, config) {
5441
+ const value = await super.validate(values2, config);
5442
+ const bracketData = await bracketOrderValidator(values2, config);
5443
+ return { ...value, ...bracketData };
5444
+ }
5445
+ };
5446
+
5447
+ // src/services/orderCreator/fokCreator.ts
5448
+ var FOKOrderCreator = class extends LimitOrderCreator {
5449
+ };
5450
+
5451
+ // src/services/orderCreator/generalCreator.ts
5452
+ var GeneralOrderCreator = class extends BaseOrderCreator {
5453
+ create(data) {
5454
+ return {
5455
+ ...this.baseOrder(data),
5456
+ order_price: data.order_price,
5457
+ order_quantity: data.order_quantity
5458
+ };
5459
+ }
5460
+ validate(values2, configs) {
5461
+ return super.baseValidate(values2, configs);
5462
+ }
5463
+ };
5464
+
5465
+ // src/services/orderCreator/iocCreator.ts
5466
+ var IOCOrderCreator = class extends LimitOrderCreator {
5467
+ };
5468
+
5469
+ // src/services/orderCreator/postOnlyCreator.ts
5470
+ var PostOnlyOrderCreator = class extends LimitOrderCreator {
5471
+ };
5472
+ var getCreateOrderUrl = (order) => {
5473
+ const isAlgoOrder = order?.order_type === OrderType.STOP_LIMIT || order?.order_type === OrderType.STOP_MARKET || order?.order_type === OrderType.CLOSE_POSITION || order.algo_type && order.algo_type === AlgoOrderRootType.BRACKET || isBracketOrder(order);
5474
+ if (order.order_type === OrderType.SCALED) {
5475
+ return "/v1/batch-order";
5476
+ }
5477
+ return isAlgoOrder ? "/v1/algo/order" : "/v1/order";
5478
+ };
5479
+ var getOrderCreator = (order) => {
5480
+ let type;
5481
+ if (isBracketOrder(order)) {
5482
+ type = `${AlgoOrderRootType.BRACKET}:${order.order_type}`;
5483
+ } else if (order.order_type === OrderType.LIMIT) {
5484
+ type = order.order_type_ext || order.order_type;
5485
+ } else {
5486
+ type = order.order_type;
5487
+ }
5488
+ return OrderFactory.create(type);
5489
+ };
5490
+ var tpslFields = [
5491
+ "tp_trigger_price",
5492
+ "sl_trigger_price",
5493
+ "tp_pnl",
5494
+ "sl_pnl",
5495
+ "tp_offset",
5496
+ "sl_offset",
5497
+ "tp_offset_percentage",
5498
+ "sl_offset_percentage"
5499
+ ];
5500
+ var isBracketOrder = (order) => {
5501
+ return !!order.tp_trigger_price || !!order.sl_trigger_price;
5502
+ };
5503
+ var hasTPSL = (order) => {
5504
+ return tpslFields.some((field) => !!order[field]);
5505
+ };
5506
+ function getOrderPrice(order, askAndBid) {
5507
+ const orderPrice = Number(order.order_price);
5508
+ if (order.order_type === OrderType.MARKET || order.order_type === OrderType.STOP_MARKET) {
5509
+ if (order.side === OrderSide.BUY) {
5510
+ return askAndBid[0];
5511
+ } else {
5512
+ return askAndBid[1];
5513
+ }
5514
+ } else {
5515
+ if (order.side === OrderSide.BUY) {
5516
+ if (orderPrice >= askAndBid[0]) {
5517
+ return askAndBid[0];
5518
+ } else {
5519
+ return orderPrice;
5520
+ }
5521
+ } else {
5522
+ if (orderPrice <= askAndBid[1]) {
5523
+ return askAndBid[1];
5524
+ } else {
5525
+ return orderPrice;
5526
+ }
5527
+ }
5528
+ }
5529
+ }
5530
+ var getPriceAndQty = (order, symbolInfo, askAndBid) => {
5531
+ let quantity = Number(order.order_quantity);
5532
+ const orderPrice = Number(order.order_price);
5533
+ if (isNaN(quantity) || quantity <= 0) {
5534
+ return null;
5535
+ }
5536
+ if (askAndBid.length === 0) {
5537
+ return null;
5538
+ }
5539
+ if ((order.order_type === OrderType.LIMIT || order.order_type === OrderType.STOP_LIMIT) && isNaN(orderPrice)) {
5540
+ return null;
5541
+ }
5542
+ let price;
5543
+ if (order.order_type === OrderType.SCALED) {
5544
+ price = calcScaledOrderAvgOrderPrice(order, symbolInfo, askAndBid);
5545
+ const orders = calcScaledOrderBatchBody(order, symbolInfo);
5546
+ const sumQtys = orders.reduce((acc, order2) => {
5547
+ return acc.plus(new Decimal(order2.order_quantity));
5548
+ }, zero);
5549
+ quantity = sumQtys.todp(symbolInfo.base_dp).toNumber();
5550
+ if (!quantity || isNaN(quantity)) {
5551
+ return null;
5552
+ }
5553
+ } else {
5554
+ price = getOrderPrice(order, askAndBid);
5555
+ }
5556
+ if (!price || isNaN(price)) {
5557
+ return null;
5558
+ }
5559
+ if (order.side === OrderSide.SELL) {
5560
+ quantity = -quantity;
5561
+ }
5562
+ return { price, quantity };
5563
+ };
5564
+ var calcEstLiqPrice = (order$1, askAndBid, inputs) => {
5565
+ const { symbolInfo } = inputs;
5566
+ const result = getPriceAndQty(order$1, symbolInfo, askAndBid);
5567
+ if (!result)
5568
+ return null;
5569
+ const { price, quantity } = result;
5570
+ if (!price || !quantity)
5571
+ return null;
5572
+ const {
5573
+ symbol,
5574
+ imr_factor,
5575
+ markPrice,
5576
+ totalCollateral,
5577
+ futures_taker_fee_rate,
5578
+ positions: positions3
5579
+ } = inputs;
5580
+ const orderFee = order.orderFee({
5581
+ qty: quantity,
5582
+ price,
5583
+ futuresTakeFeeRate: Number(futures_taker_fee_rate) / 1e4
5584
+ });
5585
+ const liqPrice = order.estLiqPrice({
5586
+ markPrice,
5587
+ baseIMR: symbolInfo.base_imr,
5588
+ baseMMR: symbolInfo.base_mmr,
5589
+ totalCollateral,
5590
+ positions: positions3 == null ? [] : positions3,
5591
+ IMR_Factor: imr_factor,
5592
+ orderFee,
5593
+ newOrder: {
5594
+ qty: quantity,
5595
+ price,
5596
+ symbol
5597
+ }
5598
+ });
5599
+ if (liqPrice <= 0)
5600
+ return null;
5601
+ return liqPrice;
5602
+ };
5603
+ var calcEstLeverage = (order$1, askAndBid, inputs) => {
5604
+ const { totalCollateral, positions: positions3, symbol, symbolInfo } = inputs;
5605
+ const result = getPriceAndQty(order$1, symbolInfo, askAndBid);
5606
+ if (!result)
5607
+ return null;
5608
+ const { price, quantity } = result;
5609
+ if (!price || !quantity)
5610
+ return null;
5611
+ return order.estLeverage({
5612
+ totalCollateral,
5613
+ positions: positions3,
5614
+ newOrder: {
5615
+ symbol,
5616
+ qty: result.quantity,
5617
+ price: result.price
5618
+ }
5619
+ });
5620
+ };
5621
+ function isBBOOrder(options) {
5622
+ const { order_type, order_type_ext } = options;
5623
+ return order_type === OrderType.LIMIT && [OrderType.ASK, OrderType.BID].includes(order_type_ext);
5624
+ }
5625
+ function calcScaledOrderPrices(inputs) {
5626
+ const { min_price, max_price, total_orders, quote_dp } = inputs;
5627
+ if (!min_price || !max_price || !total_orders) {
5628
+ return [];
5629
+ }
5630
+ const minPrice3 = new Decimal(min_price);
5631
+ const maxPrice3 = new Decimal(max_price);
5632
+ const totalOrders = Number(total_orders);
5633
+ const priceStep = maxPrice3.minus(minPrice3).div(totalOrders - 1);
5634
+ const prices = [];
5635
+ for (let i = 0; i < totalOrders; i++) {
5636
+ prices[i] = minPrice3.plus(priceStep.mul(i)).todp(quote_dp).toString();
5637
+ }
5638
+ return prices;
5639
+ }
5640
+ function getScaledOrderSkew(inputs) {
5641
+ const { skew, distribution_type, total_orders } = inputs;
5642
+ if (distribution_type === DistributionType.FLAT) {
5643
+ return 1;
5644
+ } else if (distribution_type === DistributionType.ASCENDING) {
5645
+ return total_orders;
5646
+ } else if (distribution_type === DistributionType.DESCENDING) {
5647
+ return 1 / total_orders;
5648
+ }
5649
+ return skew;
5650
+ }
5651
+ function calcScaledOrderWeights(inputs) {
5652
+ const { total_orders, distribution_type, skew } = inputs;
5653
+ const weights = [];
5654
+ if (!total_orders || !distribution_type || distribution_type === DistributionType.CUSTOM && (!skew || skew <= 0 || skew > 100)) {
5655
+ return {
5656
+ weights: [],
5657
+ sumWeights: 0,
5658
+ minWeight: 0
5659
+ };
5660
+ }
5661
+ const totalOrders = Number(total_orders);
5662
+ const skewNum = getScaledOrderSkew({
5663
+ skew,
5664
+ distribution_type,
5665
+ total_orders: totalOrders
5666
+ });
5667
+ for (let i = 0; i < totalOrders; i++) {
5668
+ weights[i] = 1 + (skewNum - 1) * i / (totalOrders - 1);
5669
+ }
5670
+ const sumWeights = weights.reduce((acc, cur) => acc + cur, 0);
5671
+ const minWeight = weights.reduce(
5672
+ (min3, current) => current < min3 ? current : min3,
5673
+ weights?.[0]
5674
+ );
5675
+ return {
5676
+ weights,
5677
+ sumWeights,
5678
+ minWeight
5679
+ };
5680
+ }
5681
+ function calcScaledOrderQtys(inputs) {
5682
+ const {
5683
+ order_quantity = 0,
5684
+ total_orders = 0,
5685
+ distribution_type,
5686
+ skew,
5687
+ base_dp,
5688
+ base_tick
5689
+ } = inputs;
5690
+ const qtys = [];
5691
+ if (!order_quantity || !total_orders) {
5692
+ return [];
5693
+ }
5694
+ const { weights, sumWeights } = calcScaledOrderWeights({
5695
+ total_orders,
5696
+ distribution_type,
5697
+ skew
5698
+ });
5699
+ for (let i = 0; i < total_orders; i++) {
5700
+ let qty = new Decimal(order_quantity).mul(weights[i]).div(sumWeights);
5701
+ if (base_tick > 1) {
5702
+ qty = qty.div(base_tick).todp(0, Decimal.ROUND_DOWN).mul(base_tick);
5703
+ } else {
5704
+ qty = qty.todp(base_dp);
5705
+ }
5706
+ qtys[i] = qty.toString();
5707
+ }
5708
+ return qtys;
5709
+ }
5710
+ function calcScaledOrderBatchBody(order, symbolInfo) {
5711
+ if (!validateScaledOrderInput(order)) {
5712
+ return [];
5713
+ }
5714
+ try {
5715
+ const { base_dp, quote_dp, base_tick } = symbolInfo;
5716
+ const {
5717
+ symbol,
5718
+ side,
5719
+ order_quantity,
5720
+ min_price,
5721
+ max_price,
5722
+ total_orders,
5723
+ distribution_type,
5724
+ skew,
5725
+ reduce_only,
5726
+ visible_quantity
5727
+ } = order;
5728
+ const prices = calcScaledOrderPrices({
5729
+ min_price,
5730
+ max_price,
5731
+ total_orders,
5732
+ quote_dp
5733
+ });
5734
+ const qtys = calcScaledOrderQtys({
5735
+ side,
5736
+ order_quantity,
5737
+ total_orders,
5738
+ distribution_type,
5739
+ skew,
5740
+ base_dp,
5741
+ base_tick
5742
+ });
5743
+ const now = Date.now();
5744
+ const orders = prices.map((price, index) => {
5745
+ const subOrder = {
5746
+ symbol,
5747
+ side,
5748
+ // this order type is scaled order, so we need to set the order type to limit
5749
+ order_type: OrderType.LIMIT,
5750
+ order_quantity: qtys[index],
5751
+ order_price: price,
5752
+ reduce_only,
5753
+ // it will be used for identify the scaled order from ws
5754
+ client_order_id: `scaled_${index}_${now}`
5755
+ };
5756
+ if (visible_quantity === 0) {
5757
+ subOrder.visible_quantity = visible_quantity;
5758
+ }
5759
+ return subOrder;
5760
+ });
5761
+ return orders;
5762
+ } catch (error) {
5763
+ return [];
5764
+ }
5765
+ }
5766
+ function calcScaledOrderAvgOrderPrice(order, symbolInfo, askAndBid) {
5767
+ if (!validateScaledOrderInput(order)) {
5768
+ return null;
5769
+ }
5770
+ try {
5771
+ const orders = calcScaledOrderBatchBody(order, symbolInfo);
5772
+ const sumQtys = orders.reduce((acc, order2) => {
5773
+ return acc.plus(new Decimal(order2.order_quantity));
5774
+ }, zero);
5775
+ const totalNational = orders.reduce((acc, order2) => {
5776
+ const orderPrice = getOrderPrice(order2, askAndBid);
5777
+ return acc.plus(new Decimal(orderPrice).mul(order2.order_quantity));
5778
+ }, zero);
5779
+ return totalNational.div(sumQtys).todp(symbolInfo.quote_dp).toNumber();
5780
+ } catch (error) {
5781
+ return null;
5782
+ }
5783
+ }
5784
+ function validateScaledOrderInput(order) {
5785
+ const {
5786
+ min_price,
5787
+ max_price,
5788
+ order_quantity,
5789
+ total_orders,
5790
+ distribution_type,
5791
+ skew
5792
+ } = order;
5793
+ if (!min_price || !max_price || !order_quantity || !total_orders || !distribution_type || distribution_type === DistributionType.CUSTOM && (!skew || skew <= 0 || skew > 100) || total_orders < 2 || total_orders > 20) {
5794
+ return false;
5795
+ }
5796
+ return true;
5797
+ }
5798
+ function calcScaledOrderMinTotalAmount(order, symbolInfo, askAndBid) {
5799
+ try {
5800
+ const minTotalAmount_baseMin = calcScaledOrderMinTotalAmountByBaseMin(
5801
+ order,
5802
+ symbolInfo
5803
+ );
5804
+ const minTotalAmount_minNotional = calcScaledOrderMinTotalAmountByMinNotional(order, symbolInfo, askAndBid);
5805
+ const minTotalAmount = Math.max(
5806
+ minTotalAmount_baseMin,
5807
+ minTotalAmount_minNotional
5808
+ );
5809
+ return minTotalAmount;
5810
+ } catch (error) {
5811
+ return null;
5812
+ }
5813
+ }
5814
+ function calcScaledOrderMinTotalAmountByBaseMin(order, symbolInfo) {
5815
+ const { total_orders, distribution_type, skew } = order;
5816
+ const { base_min, base_dp } = symbolInfo;
5817
+ const { sumWeights, minWeight } = calcScaledOrderWeights({
5818
+ total_orders,
5819
+ distribution_type,
5820
+ skew
5821
+ });
5822
+ const minTotalAmount = new Decimal(base_min).mul(new Decimal(sumWeights).div(minWeight)).todp(base_dp, Decimal.ROUND_UP).toNumber();
5823
+ return minTotalAmount;
5824
+ }
5825
+ function calcScaledOrderMinTotalAmountByMinNotional(order, symbolInfo, askAndBid) {
5826
+ const { base_dp, min_notional } = symbolInfo;
5827
+ const orders = calcScaledOrderBatchBody(order, symbolInfo);
5828
+ const { total_orders, distribution_type, skew } = order;
5829
+ const { weights, sumWeights } = calcScaledOrderWeights({
5830
+ total_orders,
5831
+ distribution_type,
5832
+ skew
5833
+ });
5834
+ const minQtys = orders.map((order2, i) => {
5835
+ const orderPrice = getOrderPrice(order2, askAndBid);
5836
+ return new Decimal(min_notional).mul(sumWeights).div(new Decimal(weights[i]).mul(orderPrice));
5837
+ });
5838
+ const max_minQty = minQtys.reduce(
5839
+ (max3, current) => current.gt(max3) ? current : max3,
5840
+ minQtys?.[0]
5841
+ );
5842
+ return max_minQty.todp(base_dp, Decimal.ROUND_UP).toNumber();
5843
+ }
5844
+
5845
+ // src/services/orderCreator/scaledOrderCreator.ts
5846
+ var ScaledOrderCreator = class extends BaseOrderCreator {
5847
+ constructor() {
5848
+ super(...arguments);
5849
+ this.orderType = OrderType.SCALED;
5850
+ }
5851
+ create(values2, config) {
5852
+ const orders = calcScaledOrderBatchBody(values2, config.symbol);
5853
+ const { total_orders, distribution_type, skew } = values2;
5854
+ const order = {
5855
+ ...this.baseOrder(values2),
5856
+ total_orders,
5857
+ distribution_type,
5858
+ skew,
5859
+ orders
5860
+ };
5861
+ return pick(
5862
+ [
5863
+ "symbol",
5864
+ "order_quantity",
5865
+ "visible_quantity",
5866
+ "reduce_only",
5867
+ "side",
5868
+ "order_type",
5869
+ "orders",
5870
+ "total_orders",
5871
+ "distribution_type",
5872
+ "skew"
5873
+ ],
5874
+ order
5875
+ );
5876
+ }
5877
+ validatePrice(values2, config) {
5878
+ const errors = {};
5879
+ const { side, min_price, max_price } = values2;
5880
+ const { price_range, price_scope, quote_max, quote_min, quote_dp } = config.symbol;
5881
+ const maxPriceNumber = order.maxPrice(config.markPrice, price_range);
5882
+ const minPriceNumber = order.minPrice(config.markPrice, price_range);
5883
+ const scopePriceNumber = order.scopePrice(
5884
+ config.markPrice,
5885
+ price_scope,
5886
+ side
5887
+ );
5888
+ const priceRange = side === OrderSide.BUY ? {
5889
+ min: scopePriceNumber,
5890
+ max: maxPriceNumber
5891
+ } : {
5892
+ min: minPriceNumber,
5893
+ max: scopePriceNumber
5894
+ };
5895
+ const minPrice3 = Number(min_price || 0);
5896
+ const maxPrice3 = Number(max_price || 0);
5897
+ if (!min_price) {
5898
+ errors.min_price = OrderValidation.required("min_price");
5899
+ } else {
5900
+ if (minPrice3 < priceRange?.min) {
5901
+ errors.min_price = OrderValidation.min(
5902
+ "min_price",
5903
+ new Decimal(priceRange.min).todp(quote_dp).toString()
5904
+ );
5905
+ } else if (minPrice3 < quote_min) {
5906
+ errors.min_price = OrderValidation.min("min_price", quote_min);
5907
+ } else if (minPrice3 > maxPrice3) {
5908
+ errors.min_price = OrderValidation.max("min_price", max_price);
5909
+ }
5910
+ }
5911
+ if (!max_price) {
5912
+ errors.max_price = OrderValidation.required("max_price");
5913
+ } else {
5914
+ if (maxPrice3 < priceRange?.min) {
5915
+ errors.max_price = OrderValidation.min(
5916
+ "max_price",
5917
+ new Decimal(priceRange.min).todp(quote_dp).toString()
5918
+ );
5919
+ } else if (maxPrice3 > priceRange?.max) {
5920
+ errors.max_price = OrderValidation.max(
5921
+ "max_price",
5922
+ new Decimal(priceRange.max).todp(quote_dp).toString()
5923
+ );
5924
+ } else if (maxPrice3 > quote_max) {
5925
+ errors.max_price = OrderValidation.max("max_price", quote_max);
5926
+ }
5927
+ }
5928
+ return errors;
5929
+ }
5930
+ async validate(values2, config) {
5931
+ const { base_dp } = config.symbol;
5932
+ const { maxQty, askAndBid } = config;
5933
+ const { order_quantity, total_orders, distribution_type, skew } = values2;
5934
+ const errors = this.validatePrice(values2, config);
5935
+ if (!total_orders) {
5936
+ errors.total_orders = OrderValidation.required("total_orders");
5937
+ } else {
5938
+ const totalOrdersNum = Number(total_orders);
5939
+ if (totalOrdersNum < 2 || totalOrdersNum > 20) {
5940
+ errors.total_orders = OrderValidation.range("total_orders", 2, 20);
5941
+ }
5942
+ }
5943
+ if (distribution_type === DistributionType.CUSTOM) {
5944
+ if (!skew) {
5945
+ errors.skew = OrderValidation.required("skew");
5946
+ } else {
5947
+ const skewNum = Number(skew);
5948
+ if (skewNum <= 0) {
5949
+ errors.skew = OrderValidation.min("skew", 0);
5950
+ } else if (skewNum > 100) {
5951
+ errors.skew = OrderValidation.max("skew", 100);
5952
+ }
5953
+ }
5954
+ }
5955
+ if (!order_quantity) {
5956
+ errors.order_quantity = OrderValidation.required("order_quantity");
5957
+ } else {
5958
+ const qty = new Decimal(order_quantity);
5959
+ if (qty.gt(maxQty)) {
5960
+ errors.order_quantity = OrderValidation.max(
5961
+ "order_quantity",
5962
+ new Decimal(maxQty).todp(base_dp).toString()
5963
+ );
5964
+ } else if (!errors.skew && !errors.total_orders) {
5965
+ const minTotalAmount = calcScaledOrderMinTotalAmount(
5966
+ values2,
5967
+ config.symbol,
5968
+ askAndBid
5969
+ );
5970
+ if (minTotalAmount && qty.lt(minTotalAmount)) {
5971
+ errors.order_quantity = OrderValidation.min(
5972
+ "order_quantity",
5973
+ minTotalAmount
5974
+ );
5975
+ }
5976
+ }
5977
+ }
5978
+ return errors;
5979
+ }
5980
+ };
5981
+ var { maxPrice: maxPrice2, minPrice: minPrice2, scopePrice: scopePrice2 } = order;
5982
+ var StopLimitOrderCreator = class extends BaseOrderCreator {
5983
+ constructor() {
5984
+ super(...arguments);
5985
+ this.orderType = OrderType.STOP_LIMIT;
5986
+ }
5987
+ create(values2, config) {
5988
+ this.totalToQuantity(values2, config);
5989
+ const order = {
5990
+ ...this.baseOrder(values2),
5991
+ trigger_price: values2.trigger_price,
5992
+ algo_type: AlgoOrderRootType.STOP,
5993
+ type: OrderType.LIMIT,
5994
+ quantity: values2["order_quantity"],
5995
+ price: values2["order_price"],
5996
+ trigger_price_type: TriggerPriceType.MARK_PRICE
5997
+ };
5998
+ return pick(
5999
+ [
6000
+ "symbol",
6001
+ "trigger_price",
6002
+ "algo_type",
6003
+ "type",
6004
+ "quantity",
6005
+ "price",
6006
+ "trigger_price_type",
6007
+ "side",
6008
+ "reduce_only",
6009
+ "visible_quantity"
6010
+ ],
6011
+ order
6012
+ );
6013
+ }
6014
+ validate(values2, config) {
6015
+ return this.baseValidate(values2, config).then((errors) => {
6016
+ const { order_price, trigger_price, side } = values2;
6017
+ const { symbol } = config;
6018
+ const { price_range, price_scope, quote_max, quote_min } = symbol;
6019
+ if (!trigger_price) {
6020
+ errors.trigger_price = OrderValidation.required("trigger_price");
6021
+ }
6022
+ if (!order_price) {
6023
+ errors.order_price = OrderValidation.required("order_price");
6024
+ }
6025
+ if (trigger_price > quote_max) {
6026
+ errors.trigger_price = OrderValidation.max("trigger_price", quote_max);
6027
+ } else if (trigger_price < quote_min) {
6028
+ errors.trigger_price = OrderValidation.min("trigger_price", quote_min);
6029
+ } else {
6030
+ if (trigger_price && order_price) {
6031
+ const price = new Decimal(order_price);
6032
+ const maxPriceNumber = maxPrice2(trigger_price, price_range);
6033
+ const minPriceNumber = minPrice2(trigger_price, price_range);
6034
+ const scropePriceNumbere = scopePrice2(
6035
+ trigger_price,
6036
+ price_scope,
6037
+ side
6038
+ );
6039
+ const priceRange = side === "BUY" ? {
6040
+ min: scropePriceNumbere,
6041
+ max: maxPriceNumber
6042
+ } : {
6043
+ min: minPriceNumber,
6044
+ max: scropePriceNumbere
6045
+ };
6046
+ if (price.gt(quote_max)) {
6047
+ errors.order_price = OrderValidation.max("order_price", quote_max);
6048
+ } else {
6049
+ if (price.gt(priceRange?.max)) {
6050
+ errors.order_price = OrderValidation.max(
6051
+ "order_price",
6052
+ new Decimal(priceRange.max).todp(symbol.quote_dp).toString()
6053
+ );
6054
+ }
6055
+ }
6056
+ if (price.lt(quote_min)) {
6057
+ errors.order_price = OrderValidation.min("order_price", quote_min);
6058
+ } else {
6059
+ if (price.lt(priceRange?.min)) {
6060
+ errors.order_price = OrderValidation.min(
6061
+ "order_price",
6062
+ new Decimal(priceRange.min).todp(symbol.quote_dp).toString()
6063
+ );
6064
+ }
6065
+ }
6066
+ }
6067
+ }
6068
+ return errors;
6069
+ });
6070
+ }
6071
+ };
6072
+ var StopMarketOrderCreator = class extends BaseOrderCreator {
6073
+ create(values2) {
6074
+ const order = {
6075
+ ...this.baseOrder(values2),
6076
+ // order_price: values.order_price,
6077
+ trigger_price: values2.trigger_price,
6078
+ algo_type: AlgoOrderRootType.STOP,
6079
+ type: OrderType.MARKET,
6080
+ quantity: values2["order_quantity"],
6081
+ // price: values["order_price"],
6082
+ trigger_price_type: TriggerPriceType.MARK_PRICE
6083
+ };
6084
+ return pick(
5402
6085
  [
5403
6086
  "symbol",
5404
6087
  "trigger_price",
@@ -5431,18 +6114,6 @@ var StopMarketOrderCreator = class extends BaseOrderCreator {
5431
6114
  });
5432
6115
  }
5433
6116
  };
5434
-
5435
- // src/services/orderCreator/postOnlyCreator.ts
5436
- var PostOnlyOrderCreator = class extends LimitOrderCreator {
5437
- };
5438
-
5439
- // src/services/orderCreator/fokCreator.ts
5440
- var FOKOrderCreator = class extends LimitOrderCreator {
5441
- };
5442
-
5443
- // src/services/orderCreator/iocCreator.ts
5444
- var IOCOrderCreator = class extends LimitOrderCreator {
5445
- };
5446
6117
  var BaseAlgoOrderCreator = class {
5447
6118
  /**
5448
6119
  * base validate
@@ -5646,216 +6317,58 @@ var TPSLPositionOrderCreator = class extends BaseAlgoOrderCreator {
5646
6317
  type: OrderType.CLOSE_POSITION,
5647
6318
  trigger_price: tp_trigger_price,
5648
6319
  trigger_price_type: TriggerPriceType.MARK_PRICE,
5649
- symbol: values2.symbol,
5650
- is_activated: !!values2.tp_trigger_price
5651
- });
5652
- }
5653
- if (typeof values2.sl_trigger_price !== "undefined") {
5654
- const sl_trigger_price = !!values2.sl_trigger_price ? new Decimal(values2.sl_trigger_price).todp(config.symbol.quote_dp).toNumber() : values2.sl_trigger_price;
5655
- child_orders.push({
5656
- algo_type: AlgoOrderType.STOP_LOSS,
5657
- reduce_only: true,
5658
- side,
5659
- type: OrderType.CLOSE_POSITION,
5660
- trigger_price: sl_trigger_price,
5661
- trigger_price_type: TriggerPriceType.MARK_PRICE,
5662
- symbol: values2.symbol,
5663
- is_activated: !!values2.sl_trigger_price
5664
- });
5665
- }
5666
- return {
5667
- algo_type: AlgoOrderRootType.POSITIONAL_TP_SL,
5668
- trigger_price_type: TriggerPriceType.MARK_PRICE,
5669
- // reduce_only: true,
5670
- symbol: values2.symbol,
5671
- child_orders
5672
- };
5673
- }
5674
- crateUpdateOrder(values2, oldValue, config) {
5675
- const data = this.create(values2, config);
5676
- const newData = [];
5677
- data.child_orders.forEach((order) => {
5678
- const oldOrder = oldValue.child_orders?.find(
5679
- (oldOrder2) => oldOrder2.algo_type === order.algo_type
5680
- );
5681
- if (oldOrder) {
5682
- if (!order.is_activated) {
5683
- newData.push({
5684
- is_activated: false,
5685
- order_id: Number(oldOrder.algo_order_id)
5686
- });
5687
- } else if (oldOrder.trigger_price !== order.trigger_price) {
5688
- newData.push({
5689
- trigger_price: order.trigger_price,
5690
- order_id: Number(oldOrder.algo_order_id)
5691
- });
5692
- }
5693
- }
5694
- });
5695
- return [
5696
- {
5697
- child_orders: newData
5698
- },
5699
- data
5700
- ];
5701
- }
5702
- };
5703
- async function bracketOrderValidator(values2, config) {
5704
- const result = /* @__PURE__ */ Object.create(null);
5705
- await Promise.resolve();
5706
- const { tp_trigger_price, sl_trigger_price, side } = values2;
5707
- const qty = Number(values2.quantity);
5708
- const maxQty = config.maxQty;
5709
- const type = values2.order_type;
5710
- const { quote_max, quote_min, price_scope, quote_dp } = config.symbol ?? {};
5711
- const mark_price = type === OrderType.MARKET ? config.markPrice : values2.order_price ? Number(values2.order_price) : void 0;
5712
- if (!isNaN(qty) && qty > maxQty) {
5713
- result.quantity = OrderValidation.max("quantity", config.maxQty);
5714
- }
5715
- if (Number(tp_trigger_price) < 0) {
5716
- result.tp_trigger_price = OrderValidation.min("tp_trigger_price", 0);
5717
- }
5718
- if (Number(sl_trigger_price) < 0) {
5719
- result.sl_trigger_price = OrderValidation.min("sl_trigger_price", 0);
5720
- }
5721
- if (side === OrderSide.BUY && mark_price) {
5722
- const slTriggerPriceScope = new Decimal(mark_price * (1 - price_scope)).toDecimalPlaces(quote_dp, Decimal.ROUND_DOWN).toNumber();
5723
- if (!!sl_trigger_price && Number(sl_trigger_price) < slTriggerPriceScope) {
5724
- result.sl_trigger_price = OrderValidation.min(
5725
- "sl_trigger_price",
5726
- slTriggerPriceScope
5727
- );
5728
- }
5729
- if (!!tp_trigger_price && Number(tp_trigger_price) <= mark_price) {
5730
- result.tp_trigger_price = OrderValidation.min(
5731
- "tp_trigger_price",
5732
- mark_price
5733
- );
5734
- }
5735
- if (!!tp_trigger_price && Number(tp_trigger_price) > quote_max) {
5736
- result.tp_trigger_price = OrderValidation.max(
5737
- "tp_trigger_price",
5738
- quote_max
5739
- );
5740
- }
5741
- if (!!sl_trigger_price && Number(sl_trigger_price) < quote_min) {
5742
- result.sl_trigger_price = OrderValidation.min(
5743
- "sl_trigger_price",
5744
- quote_min
5745
- );
5746
- }
5747
- }
5748
- if (side === OrderSide.SELL && mark_price) {
5749
- const slTriggerPriceScope = new Decimal(mark_price * (1 + price_scope)).toDecimalPlaces(quote_dp, Decimal.ROUND_DOWN).toNumber();
5750
- if (!!sl_trigger_price && Number(sl_trigger_price) > slTriggerPriceScope) {
5751
- result.sl_trigger_price = OrderValidation.max(
5752
- "sl_trigger_price",
5753
- slTriggerPriceScope
5754
- );
5755
- }
5756
- if (!!tp_trigger_price && Number(tp_trigger_price) >= mark_price) {
5757
- result.tp_trigger_price = OrderValidation.max(
5758
- "tp_trigger_price",
5759
- mark_price
5760
- );
5761
- }
5762
- if (!!tp_trigger_price && Number(tp_trigger_price) > quote_max) {
5763
- result.tp_trigger_price = OrderValidation.max(
5764
- "tp_trigger_price",
5765
- quote_max
5766
- );
5767
- }
5768
- if (!!sl_trigger_price && Number(sl_trigger_price) < quote_min) {
5769
- result.sl_trigger_price = OrderValidation.min(
5770
- "sl_trigger_price",
5771
- quote_min
5772
- );
5773
- }
5774
- }
5775
- return Object.keys(result).length > 0 ? result : null;
5776
- }
5777
-
5778
- // src/services/orderCreator/bracketLimitOrderCreator.ts
5779
- var BracketLimitOrderCreator = class extends LimitOrderCreator {
5780
- // orderType: OrderType;
5781
- create(values2, config) {
5782
- const order = super.create(values2, config);
5783
- return {
5784
- ...order,
5785
- quantity: order.order_quantity,
5786
- type: order.order_type,
5787
- price: order.order_price
5788
- };
5789
- }
5790
- async validate(values2, config) {
5791
- const value = await super.validate(values2, config);
5792
- const bracketData = await bracketOrderValidator(values2, config);
5793
- return { ...value, ...bracketData };
5794
- }
5795
- };
5796
- var BracketMarketOrderCreator = class extends MarketOrderCreator {
5797
- constructor() {
5798
- super(...arguments);
5799
- this.orderType = OrderType.MARKET;
5800
- }
5801
- create(values2) {
5802
- const order = super.create(values2);
6320
+ symbol: values2.symbol,
6321
+ is_activated: !!values2.tp_trigger_price
6322
+ });
6323
+ }
6324
+ if (typeof values2.sl_trigger_price !== "undefined") {
6325
+ const sl_trigger_price = !!values2.sl_trigger_price ? new Decimal(values2.sl_trigger_price).todp(config.symbol.quote_dp).toNumber() : values2.sl_trigger_price;
6326
+ child_orders.push({
6327
+ algo_type: AlgoOrderType.STOP_LOSS,
6328
+ reduce_only: true,
6329
+ side,
6330
+ type: OrderType.CLOSE_POSITION,
6331
+ trigger_price: sl_trigger_price,
6332
+ trigger_price_type: TriggerPriceType.MARK_PRICE,
6333
+ symbol: values2.symbol,
6334
+ is_activated: !!values2.sl_trigger_price
6335
+ });
6336
+ }
5803
6337
  return {
5804
- ...order,
5805
- quantity: order.order_quantity,
5806
- type: order.order_type,
5807
- price: order.order_price
5808
- };
5809
- }
5810
- async validate(values2, config) {
5811
- const value = await super.validate(values2, config);
5812
- const bracketData = await bracketOrderValidator(values2, config);
5813
- return { ...value, ...bracketData };
5814
- }
5815
- };
5816
- var BBOOrderCreator = class extends BaseOrderCreator {
5817
- create(values2) {
5818
- const order = {
5819
- ...this.baseOrder(values2),
5820
- level: values2.level
6338
+ algo_type: AlgoOrderRootType.POSITIONAL_TP_SL,
6339
+ trigger_price_type: TriggerPriceType.MARK_PRICE,
6340
+ // reduce_only: true,
6341
+ symbol: values2.symbol,
6342
+ child_orders
5821
6343
  };
5822
- return pick(
5823
- [
5824
- "symbol",
5825
- "order_quantity",
5826
- "visible_quantity",
5827
- "reduce_only",
5828
- "side",
5829
- "order_type",
5830
- "level"
5831
- ],
5832
- order
5833
- );
5834
6344
  }
5835
- async validate(values2, configs) {
5836
- return this.baseValidate(values2, configs).then((errors) => {
5837
- delete errors["total"];
5838
- let { order_quantity, order_price, reduce_only, level } = values2;
5839
- const { symbol } = configs;
5840
- const { min_notional, base_tick, quote_dp, quote_tick, base_dp } = symbol || {};
5841
- const minNotional = getMinNotional({
5842
- base_tick,
5843
- quote_tick,
5844
- price: order_price,
5845
- qty: order_quantity,
5846
- min_notional,
5847
- quote_dp,
5848
- base_dp
5849
- });
5850
- if (minNotional !== void 0 && !reduce_only) {
5851
- errors.total = {
5852
- type: "min",
5853
- message: `The order value should be greater or equal to ${minNotional} USDC`,
5854
- value: minNotional
5855
- };
6345
+ crateUpdateOrder(values2, oldValue, config) {
6346
+ const data = this.create(values2, config);
6347
+ const newData = [];
6348
+ data.child_orders.forEach((order) => {
6349
+ const oldOrder = oldValue.child_orders?.find(
6350
+ (oldOrder2) => oldOrder2.algo_type === order.algo_type
6351
+ );
6352
+ if (oldOrder) {
6353
+ if (!order.is_activated) {
6354
+ newData.push({
6355
+ is_activated: false,
6356
+ order_id: Number(oldOrder.algo_order_id)
6357
+ });
6358
+ } else if (oldOrder.trigger_price !== order.trigger_price) {
6359
+ newData.push({
6360
+ trigger_price: order.trigger_price,
6361
+ order_id: Number(oldOrder.algo_order_id)
6362
+ });
6363
+ }
5856
6364
  }
5857
- return errors;
5858
6365
  });
6366
+ return [
6367
+ {
6368
+ child_orders: newData
6369
+ },
6370
+ data
6371
+ ];
5859
6372
  }
5860
6373
  };
5861
6374
 
@@ -5884,6 +6397,8 @@ var OrderFactory = class {
5884
6397
  return new StopLimitOrderCreator();
5885
6398
  case OrderType.STOP_MARKET:
5886
6399
  return new StopMarketOrderCreator();
6400
+ case OrderType.SCALED:
6401
+ return new ScaledOrderCreator();
5887
6402
  case AlgoOrderRootType.TP_SL:
5888
6403
  return new TPSLOrderCreator();
5889
6404
  case AlgoOrderRootType.POSITIONAL_TP_SL:
@@ -7147,6 +7662,9 @@ var usePrivateDataObserver = (options) => {
7147
7662
  return () => unsubscribe?.();
7148
7663
  }, [account7.accountId]);
7149
7664
  const isHoldingInit = useRef(false);
7665
+ useEffect(() => {
7666
+ isHoldingInit.current = false;
7667
+ }, [state.accountId]);
7150
7668
  useEffect(() => {
7151
7669
  if (!holding) {
7152
7670
  return;
@@ -14506,137 +15024,6 @@ function getQueryParamsFromObject(obj) {
14506
15024
  }
14507
15025
  return queryParams.toString();
14508
15026
  }
14509
- var getCreateOrderUrl = (order) => {
14510
- const isAlgoOrder = order?.order_type === OrderType.STOP_LIMIT || order?.order_type === OrderType.STOP_MARKET || order?.order_type === OrderType.CLOSE_POSITION || order.algo_type && order.algo_type === AlgoOrderRootType.BRACKET || isBracketOrder(order);
14511
- return isAlgoOrder ? "/v1/algo/order" : "/v1/order";
14512
- };
14513
- var getOrderCreator = (order) => {
14514
- let type;
14515
- if (isBracketOrder(order)) {
14516
- type = `${AlgoOrderRootType.BRACKET}:${order.order_type}`;
14517
- } else if (order.order_type === OrderType.LIMIT) {
14518
- type = order.order_type_ext || order.order_type;
14519
- } else {
14520
- type = order.order_type;
14521
- }
14522
- return OrderFactory.create(type);
14523
- };
14524
- var tpslFields = [
14525
- "tp_trigger_price",
14526
- "sl_trigger_price",
14527
- "tp_pnl",
14528
- "sl_pnl",
14529
- "tp_offset",
14530
- "sl_offset",
14531
- "tp_offset_percentage",
14532
- "sl_offset_percentage"
14533
- ];
14534
- var isBracketOrder = (order) => {
14535
- return !!order.tp_trigger_price || !!order.sl_trigger_price;
14536
- };
14537
- var hasTPSL = (order) => {
14538
- return tpslFields.some((field) => !!order[field]);
14539
- };
14540
- var getPriceAndQty = (symbolOrOrder, askAndBid) => {
14541
- let quantity = Number(symbolOrOrder.order_quantity);
14542
- const orderPrice = Number(symbolOrOrder.order_price);
14543
- if (isNaN(quantity) || quantity <= 0) {
14544
- return null;
14545
- }
14546
- if (askAndBid.length === 0) {
14547
- return null;
14548
- }
14549
- if ((symbolOrOrder.order_type === OrderType.LIMIT || symbolOrOrder.order_type === OrderType.STOP_LIMIT) && isNaN(orderPrice))
14550
- return null;
14551
- let price;
14552
- if (symbolOrOrder.order_type === OrderType.MARKET || symbolOrOrder.order_type === OrderType.STOP_MARKET) {
14553
- if (symbolOrOrder.side === OrderSide.BUY) {
14554
- price = askAndBid[0];
14555
- } else {
14556
- price = askAndBid[1];
14557
- }
14558
- } else {
14559
- if (symbolOrOrder.side === OrderSide.BUY) {
14560
- if (orderPrice >= askAndBid[0]) {
14561
- price = askAndBid[0];
14562
- } else {
14563
- price = orderPrice;
14564
- }
14565
- } else {
14566
- if (orderPrice <= askAndBid[1]) {
14567
- price = askAndBid[1];
14568
- } else {
14569
- price = orderPrice;
14570
- }
14571
- }
14572
- }
14573
- if (symbolOrOrder.side === OrderSide.SELL) {
14574
- quantity = -quantity;
14575
- }
14576
- return { price, quantity };
14577
- };
14578
- var calcEstLiqPrice = (order$1, askAndBid, inputs) => {
14579
- const result = getPriceAndQty(order$1, askAndBid);
14580
- if (!result)
14581
- return null;
14582
- const { price, quantity } = result;
14583
- if (!price || !quantity)
14584
- return null;
14585
- const {
14586
- symbol,
14587
- baseIMR,
14588
- baseMMR,
14589
- imr_factor,
14590
- markPrice,
14591
- totalCollateral,
14592
- futures_taker_fee_rate,
14593
- positions: positions3
14594
- } = inputs;
14595
- const orderFee = order.orderFee({
14596
- qty: quantity,
14597
- price,
14598
- futuresTakeFeeRate: Number(futures_taker_fee_rate) / 1e4
14599
- });
14600
- const liqPrice = order.estLiqPrice({
14601
- markPrice,
14602
- baseIMR,
14603
- baseMMR,
14604
- totalCollateral,
14605
- positions: positions3 == null ? [] : positions3,
14606
- IMR_Factor: imr_factor,
14607
- orderFee,
14608
- newOrder: {
14609
- qty: quantity,
14610
- price,
14611
- symbol
14612
- }
14613
- });
14614
- if (liqPrice <= 0)
14615
- return null;
14616
- return liqPrice;
14617
- };
14618
- var calcEstLeverage = (order$1, askAndBid, inputs) => {
14619
- const result = getPriceAndQty(order$1, askAndBid);
14620
- const { totalCollateral, positions: positions3, symbol } = inputs;
14621
- if (!result)
14622
- return null;
14623
- const { price, quantity } = result;
14624
- if (!price || !quantity)
14625
- return null;
14626
- return order.estLeverage({
14627
- totalCollateral,
14628
- positions: positions3,
14629
- newOrder: {
14630
- symbol,
14631
- qty: result.quantity,
14632
- price: result.price
14633
- }
14634
- });
14635
- };
14636
- function isBBOOrder(options) {
14637
- const { order_type, order_type_ext } = options;
14638
- return order_type === OrderType.LIMIT && [OrderType.ASK, OrderType.BID].includes(order_type_ext);
14639
- }
14640
15027
  var initialOrderState = {
14641
15028
  order_price: "",
14642
15029
  order_quantity: "",
@@ -14649,7 +15036,12 @@ var initialOrderState = {
14649
15036
  sl_offset_percentage: "",
14650
15037
  tp_offset: "",
14651
15038
  sl_offset: "",
14652
- total: ""
15039
+ total: "",
15040
+ min_price: "",
15041
+ max_price: "",
15042
+ totalOrders: "",
15043
+ distribution_type: "",
15044
+ skew: ""
14653
15045
  // symbol: "",
14654
15046
  };
14655
15047
  var useOrderStore = (initialOrder) => {
@@ -14886,12 +15278,9 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
14886
15278
  [calculate2, options.symbolInfo, orderEntity, orderEntryActions]
14887
15279
  );
14888
15280
  const validate = (order, creator, options2) => {
14889
- const { markPrice, maxQty, estSlippage } = options2;
14890
15281
  return creator?.validate(order, {
14891
- symbol: symbolInfo,
14892
- maxQty,
14893
- markPrice,
14894
- estSlippage
15282
+ ...options2,
15283
+ symbol: symbolInfo
14895
15284
  });
14896
15285
  };
14897
15286
  const generateOrder = (creator, options2) => {
@@ -15073,7 +15462,8 @@ var useOrderEntry2 = (symbol, options = {}) => {
15073
15462
  return {
15074
15463
  markPrice: actions.getMarkPriceBySymbol(symbol),
15075
15464
  maxQty,
15076
- estSlippage
15465
+ estSlippage,
15466
+ askAndBid: askAndBid.current?.[0] || []
15077
15467
  };
15078
15468
  }, [maxQty, symbol, estSlippage]);
15079
15469
  const interactiveValidate = (order) => {
@@ -15173,25 +15563,36 @@ var useOrderEntry2 = (symbol, options = {}) => {
15173
15563
  const { freeCollateral, totalCollateral } = useCollateral();
15174
15564
  const estLiqPrice = useMemo(() => {
15175
15565
  const markPrice2 = actions.getMarkPriceBySymbol(symbol);
15176
- if (!markPrice2 || !accountInfo)
15566
+ if (!markPrice2 || !accountInfo || !symbolInfo) {
15177
15567
  return null;
15568
+ }
15178
15569
  const orderQuantity = Number(formattedOrder.order_quantity);
15179
15570
  if (orderQuantity === 0 || orderQuantity > maxQty) {
15180
15571
  return null;
15181
15572
  }
15182
15573
  const estLiqPrice2 = calcEstLiqPrice(formattedOrder, askAndBid.current[0], {
15183
- baseIMR: symbolInfo?.base_imr,
15184
- baseMMR: symbolInfo?.base_mmr,
15185
15574
  markPrice: markPrice2,
15186
15575
  totalCollateral,
15187
15576
  futures_taker_fee_rate: accountInfo.futures_taker_fee_rate,
15188
15577
  imr_factor: accountInfo.imr_factor[symbol],
15189
15578
  symbol,
15190
- positions: positions3
15579
+ positions: positions3,
15580
+ symbolInfo
15191
15581
  });
15192
15582
  return estLiqPrice2;
15193
- }, [formattedOrder, accountInfo, positions3, totalCollateral, symbol, maxQty]);
15583
+ }, [
15584
+ formattedOrder,
15585
+ accountInfo,
15586
+ positions3,
15587
+ totalCollateral,
15588
+ symbol,
15589
+ maxQty,
15590
+ symbolInfo
15591
+ ]);
15194
15592
  const estLeverage = useMemo(() => {
15593
+ if (!symbolInfo) {
15594
+ return null;
15595
+ }
15195
15596
  const orderQuantity = Number(formattedOrder.order_quantity);
15196
15597
  if (orderQuantity === 0 || orderQuantity > maxQty) {
15197
15598
  return null;
@@ -15199,9 +15600,18 @@ var useOrderEntry2 = (symbol, options = {}) => {
15199
15600
  return calcEstLeverage(formattedOrder, askAndBid.current[0], {
15200
15601
  totalCollateral,
15201
15602
  positions: positions3,
15202
- symbol
15603
+ symbol,
15604
+ symbolInfo
15203
15605
  });
15204
- }, [formattedOrder, accountInfo, positions3, totalCollateral, symbol, maxQty]);
15606
+ }, [
15607
+ formattedOrder,
15608
+ accountInfo,
15609
+ positions3,
15610
+ totalCollateral,
15611
+ symbol,
15612
+ maxQty,
15613
+ symbolInfo
15614
+ ]);
15205
15615
  const resetErrors = () => {
15206
15616
  setMeta(
15207
15617
  produce((draft) => {
@@ -15238,14 +15648,31 @@ var useOrderEntry2 = (symbol, options = {}) => {
15238
15648
  throw new SDKError("Order validation failed");
15239
15649
  }
15240
15650
  const order = generateOrder(creator, prepareData());
15241
- const result = await doCreateOrder(order);
15651
+ const isScaledOrder = order.order_type === OrderType.SCALED;
15652
+ const params = isScaledOrder ? { orders: order.orders } : order;
15653
+ const result = await doCreateOrder(params);
15242
15654
  if (result.success) {
15243
- track2(TrackerEventName.placeOrderSuccess, {
15655
+ let trackParams = {
15244
15656
  side: order.side,
15245
15657
  order_type: order.order_type,
15246
15658
  tp_sl: hasTPSL(formattedOrder),
15247
15659
  symbol: order.symbol
15248
- });
15660
+ };
15661
+ if (isScaledOrder) {
15662
+ const skew = getScaledOrderSkew({
15663
+ skew: order.skew,
15664
+ distribution_type: order.distribution_type,
15665
+ total_orders: order.total_orders
15666
+ });
15667
+ trackParams = {
15668
+ ...trackParams,
15669
+ order_type: "scaled",
15670
+ distribution_type: order.distribution_type,
15671
+ skew: new Decimal(skew).todp(2).toNumber(),
15672
+ total_orders: order.total_orders
15673
+ };
15674
+ }
15675
+ track2(TrackerEventName.placeOrderSuccess, trackParams);
15249
15676
  }
15250
15677
  if (result.success && resetOnSuccess) {
15251
15678
  reset();
@@ -15430,6 +15857,7 @@ var useOrderEntity = (order, options) => {
15430
15857
  symbolInfo
15431
15858
  };
15432
15859
  };
15860
+ var canUnblockRegions = ["United States"];
15433
15861
  var useRestrictedInfo = (options) => {
15434
15862
  const {
15435
15863
  enableDefault = false,
@@ -15437,63 +15865,70 @@ var useRestrictedInfo = (options) => {
15437
15865
  customRestrictedRegions = [],
15438
15866
  content
15439
15867
  } = options || {};
15440
- const apiBaseUrl = useConfig("apiBaseUrl");
15441
- const [invalidWebCity, setInvalidWebCity] = useState([]);
15442
- const [invalidWebCountry, setInvalidWebCountry] = useState([]);
15443
- const [invalidRegions, setInvalidRegions] = useState([]);
15444
- const [allInvalidAreas, setAllInvalidAreas] = useState([]);
15445
- const [city, setCity] = useState("");
15446
- const [region, setRegion] = useState("");
15447
15868
  const [ip, setIp] = useState("");
15869
+ const [allInvalidAreas, setAllInvalidAreas] = useState([]);
15448
15870
  const [restrictedOpen, setRestrictedOpen] = useState(false);
15871
+ const [canUnblock, setCanUnblock] = useState(false);
15872
+ const [accessRestricted, setAccessRestricted] = useLocalStorage("orderly_access_restricted", void 0);
15873
+ const { data: ipInfo } = useQuery("/v1/ip_info");
15874
+ const { data: restrictedAreas } = useQuery(
15875
+ "/v1/restricted_areas"
15876
+ );
15449
15877
  useEffect(() => {
15450
- const fetchData = async () => {
15451
- try {
15452
- const areaRes = await fetch(`${apiBaseUrl}/v1/restricted_areas`);
15453
- const areaResdata = await areaRes.json();
15454
- const ipRes = await fetch(`${apiBaseUrl}/v1/ip_info`);
15455
- const ipData = await ipRes.json();
15456
- if (areaResdata.success && ipData.success) {
15457
- const invalidCountries = areaResdata?.data?.invalid_web_country?.toLocaleLowerCase()?.replace(/\s+/g, "").split(",");
15458
- const invalidCities = areaResdata?.data?.invalid_web_city?.toLocaleLowerCase()?.replace(/\s+/g, "").split(",");
15459
- const combinedInvalidRegions = (enableDefault ? invalidCities.concat(invalidCountries) : []).concat(
15460
- customRestrictedRegions?.map(
15461
- (item) => item?.replace(/\s+/g, "")?.toLocaleLowerCase()
15462
- )
15463
- );
15464
- const allInvalidAreas2 = [
15465
- enableDefault ? areaResdata?.data?.invalid_web_country : "",
15466
- enableDefault ? areaResdata?.data?.invalid_web_city : "",
15467
- customRestrictedRegions?.join(", ")
15468
- ].filter((item) => !!item);
15469
- setInvalidWebCity(invalidCities);
15470
- setInvalidWebCountry(invalidCountries);
15471
- setInvalidRegions(combinedInvalidRegions);
15472
- setAllInvalidAreas(allInvalidAreas2);
15473
- const { city: city2, region: region2, ip: ip2 } = ipData.data;
15474
- setCity(city2);
15475
- setRegion(region2);
15476
- setIp(ip2);
15477
- if (combinedInvalidRegions.includes(
15478
- ipData?.data?.city?.replace(/\s+/g, "").toLocaleLowerCase()
15479
- ) || combinedInvalidRegions.includes(
15480
- ipData?.data?.region?.replace(/\s+/g, "").toLocaleLowerCase()
15481
- ) || customRestrictedIps.includes(ipData?.data?.ip)) {
15482
- setRestrictedOpen(true);
15483
- }
15878
+ if (!restrictedAreas || !ipInfo) {
15879
+ return;
15880
+ }
15881
+ try {
15882
+ const { invalid_web_country, invalid_web_city } = restrictedAreas;
15883
+ const invalidCountries = invalid_web_country?.toLowerCase().replace(/\s+/g, "").split(",");
15884
+ const invalidCities = invalid_web_city?.toLowerCase().replace(/\s+/g, "").split(",");
15885
+ const formattedCustomRegions = customRestrictedRegions?.map(
15886
+ (item) => formatRegion(item)
15887
+ );
15888
+ const combinedInvalidRegions = [
15889
+ ...formattedCustomRegions,
15890
+ ...enableDefault ? [...invalidCountries, ...invalidCities] : []
15891
+ ];
15892
+ const allInvalidAreas2 = [
15893
+ enableDefault ? invalid_web_country : "",
15894
+ enableDefault ? invalid_web_city : "",
15895
+ customRestrictedRegions?.join(", ")
15896
+ ].filter((item) => !!item);
15897
+ const { city, region, ip: ip2 } = ipInfo;
15898
+ const formattedCity = formatRegion(city);
15899
+ const formattedRegion = formatRegion(region);
15900
+ const showRestricted = accessRestricted && (combinedInvalidRegions.includes(formattedCity) || combinedInvalidRegions.includes(formattedRegion) || customRestrictedIps.includes(ip2));
15901
+ for (const item of canUnblockRegions) {
15902
+ if (formatRegion(item) === formatRegion(region)) {
15903
+ setCanUnblock(true);
15484
15904
  }
15485
- } catch (error) {
15486
15905
  }
15487
- };
15488
- fetchData();
15489
- }, [apiBaseUrl]);
15906
+ setIp(ip2);
15907
+ setAllInvalidAreas(allInvalidAreas2);
15908
+ setRestrictedOpen(showRestricted);
15909
+ } catch (error) {
15910
+ }
15911
+ }, [
15912
+ ipInfo,
15913
+ restrictedAreas,
15914
+ enableDefault,
15915
+ customRestrictedIps,
15916
+ customRestrictedRegions,
15917
+ accessRestricted
15918
+ ]);
15490
15919
  return {
15491
15920
  ip,
15492
15921
  invalidRegions: allInvalidAreas,
15493
15922
  restrictedOpen,
15494
- content
15923
+ content,
15924
+ canUnblock,
15925
+ accessRestricted,
15926
+ setAccessRestricted
15495
15927
  };
15496
15928
  };
15929
+ function formatRegion(region) {
15930
+ return region?.replace(/\s+/g, "").toLowerCase();
15931
+ }
15497
15932
  var usePositionClose = (options) => {
15498
15933
  const { position, order: initialOrder } = options;
15499
15934
  const { type, quantity, price } = initialOrder;
@@ -15501,6 +15936,10 @@ var usePositionClose = (options) => {
15501
15936
  const [errors, setErrors] = useState(null);
15502
15937
  const symbolsInfo = useSymbolsInfo();
15503
15938
  const { data: markPrices } = useMarkPricesStream();
15939
+ const markPricesRef = useRef(markPrices);
15940
+ useEffect(() => {
15941
+ markPricesRef.current = markPrices;
15942
+ }, [markPrices]);
15504
15943
  const [doCreateOrder, { isMutating }] = useSubAccountMutation(
15505
15944
  "/v1/order",
15506
15945
  "POST",
@@ -15549,11 +15988,12 @@ var usePositionClose = (options) => {
15549
15988
  const errors2 = await creator.validate(data, {
15550
15989
  symbol: symbolsInfo[symbol](),
15551
15990
  maxQty,
15552
- markPrice: markPrices[symbol]
15991
+ // use ref to avoid re-render when markPrices change
15992
+ markPrice: markPricesRef.current[symbol]
15553
15993
  });
15554
15994
  return errors2;
15555
15995
  },
15556
- [markPrices, maxQty, symbol, symbolsInfo]
15996
+ [maxQty, symbol, symbolsInfo]
15557
15997
  );
15558
15998
  useEffect(() => {
15559
15999
  validate(closeOrderData).then((errors2) => {