@orderly.network/ui-positions 2.10.2 → 2.11.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.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +741 -57
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +745 -61
- package/dist/index.mjs.map +1 -1
- package/package.json +13 -13
package/dist/index.js
CHANGED
|
@@ -598,7 +598,7 @@ var calculatePositions = (positions2, symbolsInfo, accountInfo, tpslOrders) => {
|
|
|
598
598
|
return positions2.map((item) => {
|
|
599
599
|
const info = symbolsInfo[item.symbol];
|
|
600
600
|
const notional = perp.positions.notional(item.position_qty, item.mark_price);
|
|
601
|
-
const
|
|
601
|
+
const account3 = accountInfo.find(
|
|
602
602
|
(acc) => acc.account_id === item.account_id
|
|
603
603
|
);
|
|
604
604
|
const baseMMR = info?.("base_mmr");
|
|
@@ -609,7 +609,7 @@ var calculatePositions = (positions2, symbolsInfo, accountInfo, tpslOrders) => {
|
|
|
609
609
|
const MMR = perp.positions.MMR({
|
|
610
610
|
baseMMR,
|
|
611
611
|
baseIMR,
|
|
612
|
-
IMRFactor:
|
|
612
|
+
IMRFactor: account3?.imr_factor[item.symbol] ?? 0,
|
|
613
613
|
positionNotional: notional,
|
|
614
614
|
IMR_factor_power: 4 / 5
|
|
615
615
|
});
|
|
@@ -627,7 +627,7 @@ var calculatePositions = (positions2, symbolsInfo, accountInfo, tpslOrders) => {
|
|
|
627
627
|
const imr = perp.account.IMR({
|
|
628
628
|
maxLeverage,
|
|
629
629
|
baseIMR,
|
|
630
|
-
IMR_Factor:
|
|
630
|
+
IMR_Factor: account3?.imr_factor[item.symbol] ?? 0,
|
|
631
631
|
positionNotional: notional,
|
|
632
632
|
ordersNotional: 0,
|
|
633
633
|
IMR_factor_power: 4 / 5
|
|
@@ -656,7 +656,7 @@ var calculatePositions = (positions2, symbolsInfo, accountInfo, tpslOrders) => {
|
|
|
656
656
|
const filteredTPSLOrders = tpslOrders.filter(
|
|
657
657
|
(tpslOrder) => tpslOrder.account_id === item.account_id
|
|
658
658
|
);
|
|
659
|
-
const tpsl = formatTPSL(filteredTPSLOrders, item.symbol);
|
|
659
|
+
const tpsl = formatTPSL(filteredTPSLOrders, item.symbol, item.margin_mode);
|
|
660
660
|
return {
|
|
661
661
|
...item,
|
|
662
662
|
...tpsl,
|
|
@@ -669,9 +669,9 @@ var calculatePositions = (positions2, symbolsInfo, accountInfo, tpslOrders) => {
|
|
|
669
669
|
};
|
|
670
670
|
});
|
|
671
671
|
};
|
|
672
|
-
function formatTPSL(tpslOrders, symbol) {
|
|
672
|
+
function formatTPSL(tpslOrders, symbol, marginMode) {
|
|
673
673
|
if (Array.isArray(tpslOrders) && tpslOrders.length) {
|
|
674
|
-
const { fullPositionOrder, partialPositionOrders } = hooks.findPositionTPSLFromOrders(tpslOrders, symbol);
|
|
674
|
+
const { fullPositionOrder, partialPositionOrders } = hooks.findPositionTPSLFromOrders(tpslOrders, symbol, marginMode);
|
|
675
675
|
const full_tp_sl = fullPositionOrder ? hooks.findTPSLFromOrder(fullPositionOrder) : void 0;
|
|
676
676
|
const partialPossitionOrder = partialPositionOrders && partialPositionOrders.length ? partialPositionOrders[0] : void 0;
|
|
677
677
|
const partial_tp_sl = partialPossitionOrder ? hooks.findTPSLFromOrder(partialPossitionOrder) : void 0;
|
|
@@ -690,7 +690,7 @@ function formatTPSL(tpslOrders, symbol) {
|
|
|
690
690
|
};
|
|
691
691
|
}
|
|
692
692
|
}
|
|
693
|
-
var signatureMiddleware = (
|
|
693
|
+
var signatureMiddleware = (account3, accountId) => {
|
|
694
694
|
const apiBaseUrl = hooks.useConfig("apiBaseUrl");
|
|
695
695
|
return (useSWRNext) => {
|
|
696
696
|
return (key, fetcher2, config) => {
|
|
@@ -698,7 +698,7 @@ var signatureMiddleware = (account2, accountId) => {
|
|
|
698
698
|
const extendedFetcher = async (args) => {
|
|
699
699
|
const url = Array.isArray(args) ? args[0] : args;
|
|
700
700
|
const fullUrl = `${apiBaseUrl}${url}`;
|
|
701
|
-
const signer =
|
|
701
|
+
const signer = account3.signer;
|
|
702
702
|
const payload = { method: "GET", url };
|
|
703
703
|
const signature = await signer.sign(payload, utils.getTimestamp());
|
|
704
704
|
const ids = Array.isArray(accountId) ? accountId : [accountId];
|
|
@@ -722,7 +722,7 @@ var signatureMiddleware = (account2, accountId) => {
|
|
|
722
722
|
};
|
|
723
723
|
var useSubAccountQuery = (query, options) => {
|
|
724
724
|
const { formatter, accountId, ...swrOptions } = options || {};
|
|
725
|
-
const { state, account:
|
|
725
|
+
const { state, account: account3 } = hooks.useAccount();
|
|
726
726
|
const middleware = Array.isArray(options?.use) ? options?.use ?? [] : [];
|
|
727
727
|
const ids = Array.isArray(accountId) ? accountId : [accountId];
|
|
728
728
|
const shouldFetch = ids.filter(Boolean).length && (state.status >= types.AccountStatusEnum.EnableTrading || state.status === types.AccountStatusEnum.EnableTradingWithoutConnected);
|
|
@@ -733,7 +733,7 @@ var useSubAccountQuery = (query, options) => {
|
|
|
733
733
|
},
|
|
734
734
|
{
|
|
735
735
|
...swrOptions,
|
|
736
|
-
use: [...middleware, signatureMiddleware(
|
|
736
|
+
use: [...middleware, signatureMiddleware(account3, ids)],
|
|
737
737
|
onError: () => {
|
|
738
738
|
}
|
|
739
739
|
}
|
|
@@ -1268,7 +1268,9 @@ var useReversePositionScript = (options) => {
|
|
|
1268
1268
|
order_type: types.OrderType.MARKET,
|
|
1269
1269
|
side,
|
|
1270
1270
|
order_quantity: new utils.Decimal(qty).todp(baseDp).toString(),
|
|
1271
|
-
reduce_only: reduceOnly
|
|
1271
|
+
reduce_only: reduceOnly,
|
|
1272
|
+
// Use position's margin_mode or default to CROSS for backward compatibility
|
|
1273
|
+
margin_mode: position.margin_mode || types.MarginMode.CROSS
|
|
1272
1274
|
};
|
|
1273
1275
|
};
|
|
1274
1276
|
const closeSide = isLong ? types.OrderSide.SELL : types.OrderSide.BUY;
|
|
@@ -1604,6 +1606,610 @@ var RwaStatusTag = ({ symbol }) => {
|
|
|
1604
1606
|
}
|
|
1605
1607
|
);
|
|
1606
1608
|
};
|
|
1609
|
+
var usePositionMargin = (symbol, isAdd, isolatedMargin, finalMargin) => {
|
|
1610
|
+
const { freeCollateral, freeCollateralUSDCOnly, usdcHolding } = hooks.useCollateral(
|
|
1611
|
+
{
|
|
1612
|
+
dp: 2
|
|
1613
|
+
}
|
|
1614
|
+
);
|
|
1615
|
+
const positions2 = hooks.usePositions();
|
|
1616
|
+
const total_cross_unsettled_pnl = React2.useMemo(() => {
|
|
1617
|
+
return positions2?.filter((item) => (item.margin_mode ?? "CROSS") === "CROSS").reduce((acc, item) => acc.add(item.unsettled_pnl), new utils.Decimal(0));
|
|
1618
|
+
}, [positions2]);
|
|
1619
|
+
const fundingRates = hooks.useAppStore((state) => state.fundingRates);
|
|
1620
|
+
const symbolsInfo = hooks.useAppStore((state) => state.symbolsInfo);
|
|
1621
|
+
const accountInfo = hooks.useAppStore((state) => state.accountInfo);
|
|
1622
|
+
const { data: markPrice } = hooks.useMarkPrice(symbol);
|
|
1623
|
+
const totalUnsettlementPnl = React2.useMemo(() => {
|
|
1624
|
+
if (!positions2?.length) {
|
|
1625
|
+
return null;
|
|
1626
|
+
}
|
|
1627
|
+
return positions2.reduce((acc, item) => {
|
|
1628
|
+
const itemAny = item;
|
|
1629
|
+
const positionUnsettlementPnl = itemAny["unsettlement_pnl"] ?? item.unsettled_pnl ?? 0;
|
|
1630
|
+
return acc.add(positionUnsettlementPnl);
|
|
1631
|
+
}, new utils.Decimal(0));
|
|
1632
|
+
}, [positions2]);
|
|
1633
|
+
const currentPosition = React2.useMemo(() => {
|
|
1634
|
+
return positions2?.find(
|
|
1635
|
+
(item) => item.symbol === symbol && item.margin_mode === types.MarginMode.ISOLATED
|
|
1636
|
+
);
|
|
1637
|
+
}, [positions2]);
|
|
1638
|
+
const notional = React2.useMemo(() => {
|
|
1639
|
+
if (!currentPosition) return null;
|
|
1640
|
+
return new utils.Decimal(currentPosition.notional);
|
|
1641
|
+
}, [currentPosition]);
|
|
1642
|
+
const unSettledPnl = currentPosition?.unsettled_pnl;
|
|
1643
|
+
const imr = React2.useMemo(() => {
|
|
1644
|
+
if (!currentPosition || !symbolsInfo?.[symbol] || !notional) {
|
|
1645
|
+
return null;
|
|
1646
|
+
}
|
|
1647
|
+
const currentSymbolInfo = symbolsInfo[symbol];
|
|
1648
|
+
const maxLeverage = Math.max(currentPosition.leverage ?? 1, 1);
|
|
1649
|
+
const IMR_Factor = accountInfo?.imr_factor?.[symbol] ?? currentSymbolInfo.imr_factor ?? 0;
|
|
1650
|
+
return new utils.Decimal(
|
|
1651
|
+
perp.account.IMR({
|
|
1652
|
+
maxLeverage,
|
|
1653
|
+
baseIMR: currentSymbolInfo.base_imr ?? 0,
|
|
1654
|
+
IMR_Factor,
|
|
1655
|
+
positionNotional: notional.toNumber(),
|
|
1656
|
+
ordersNotional: 0
|
|
1657
|
+
})
|
|
1658
|
+
);
|
|
1659
|
+
}, [currentPosition, symbolsInfo, symbol, notional, accountInfo]);
|
|
1660
|
+
const maxAmount = React2.useMemo(() => {
|
|
1661
|
+
if (isAdd) {
|
|
1662
|
+
if (!freeCollateralUSDCOnly) return null;
|
|
1663
|
+
return Math.max(0, freeCollateralUSDCOnly);
|
|
1664
|
+
}
|
|
1665
|
+
if (!imr || !notional || isolatedMargin === void 0 || isolatedMargin === null || !currentPosition) {
|
|
1666
|
+
return null;
|
|
1667
|
+
}
|
|
1668
|
+
const positionNotional = notional;
|
|
1669
|
+
const imrValue = imr;
|
|
1670
|
+
const unsettledPnlValue = unSettledPnl ?? 0;
|
|
1671
|
+
return perp.account.maxReduce({
|
|
1672
|
+
isolatedPositionMargin: isolatedMargin,
|
|
1673
|
+
positionNotional: positionNotional.toNumber(),
|
|
1674
|
+
imr: imrValue.toNumber(),
|
|
1675
|
+
positionUnsettledPnL: unsettledPnlValue
|
|
1676
|
+
});
|
|
1677
|
+
}, [
|
|
1678
|
+
total_cross_unsettled_pnl,
|
|
1679
|
+
usdcHolding,
|
|
1680
|
+
isAdd,
|
|
1681
|
+
freeCollateral,
|
|
1682
|
+
unSettledPnl,
|
|
1683
|
+
isolatedMargin
|
|
1684
|
+
]);
|
|
1685
|
+
const liquidationPrice = React2.useMemo(() => {
|
|
1686
|
+
if (!totalUnsettlementPnl || !currentPosition || !symbolsInfo?.[symbol] || !accountInfo?.imr_factor) {
|
|
1687
|
+
return null;
|
|
1688
|
+
}
|
|
1689
|
+
const currentSymbolInfo = symbolsInfo[symbol];
|
|
1690
|
+
const currentPositionNotional = notional?.toNumber() ?? 0;
|
|
1691
|
+
const currentPositionIMRFactor = accountInfo.imr_factor[symbol] ?? currentSymbolInfo.imr_factor ?? 0;
|
|
1692
|
+
perp.positions.MMR({
|
|
1693
|
+
baseMMR: currentSymbolInfo.base_mmr ?? 0,
|
|
1694
|
+
baseIMR: currentSymbolInfo.base_imr ?? 0,
|
|
1695
|
+
IMRFactor: currentPositionIMRFactor,
|
|
1696
|
+
positionNotional: currentPositionNotional,
|
|
1697
|
+
IMR_factor_power: 4 / 5
|
|
1698
|
+
});
|
|
1699
|
+
positions2?.filter((item) => item.symbol !== symbol).map((item) => {
|
|
1700
|
+
const itemSymbolInfo = symbolsInfo[item.symbol];
|
|
1701
|
+
const itemIMRFactor = accountInfo.imr_factor[item.symbol] ?? itemSymbolInfo?.imr_factor ?? 0;
|
|
1702
|
+
const itemNotional = item.notional ?? new utils.Decimal(item.position_qty).mul(item.mark_price).abs().toNumber();
|
|
1703
|
+
const itemMMR = item.mmr ?? perp.positions.MMR({
|
|
1704
|
+
baseMMR: itemSymbolInfo?.base_mmr ?? 0,
|
|
1705
|
+
baseIMR: itemSymbolInfo?.base_imr ?? 0,
|
|
1706
|
+
IMRFactor: itemIMRFactor,
|
|
1707
|
+
positionNotional: itemNotional,
|
|
1708
|
+
IMR_factor_power: 4 / 5
|
|
1709
|
+
});
|
|
1710
|
+
return {
|
|
1711
|
+
symbol: item.symbol,
|
|
1712
|
+
position_qty: item.position_qty,
|
|
1713
|
+
mark_price: item.mark_price,
|
|
1714
|
+
mmr: itemMMR
|
|
1715
|
+
};
|
|
1716
|
+
}) ?? [];
|
|
1717
|
+
new utils.Decimal(finalMargin).add(currentPosition.unsettled_pnl ?? 0).toNumber();
|
|
1718
|
+
const sumUnitaryFunding = fundingRates?.[symbol]?.sum_unitary_funding ?? 0;
|
|
1719
|
+
const liqPrice = perp.positions.liquidationPriceIsolated({
|
|
1720
|
+
isolatedPositionMargin: finalMargin,
|
|
1721
|
+
costPosition: currentPosition.cost_position ?? 0,
|
|
1722
|
+
positionQty: currentPosition.position_qty ?? 0,
|
|
1723
|
+
sumUnitaryFunding,
|
|
1724
|
+
lastSumUnitaryFunding: currentPosition.last_sum_unitary_funding ?? 0,
|
|
1725
|
+
baseMMR: currentSymbolInfo.base_mmr ?? 0,
|
|
1726
|
+
baseIMR: currentSymbolInfo.base_imr ?? 0,
|
|
1727
|
+
IMRFactor: currentPositionIMRFactor,
|
|
1728
|
+
referencePrice: markPrice,
|
|
1729
|
+
leverage: currentPosition.leverage ?? 0
|
|
1730
|
+
});
|
|
1731
|
+
return liqPrice;
|
|
1732
|
+
}, [
|
|
1733
|
+
totalUnsettlementPnl,
|
|
1734
|
+
currentPosition,
|
|
1735
|
+
symbolsInfo,
|
|
1736
|
+
symbol,
|
|
1737
|
+
accountInfo,
|
|
1738
|
+
notional,
|
|
1739
|
+
positions2,
|
|
1740
|
+
finalMargin,
|
|
1741
|
+
markPrice
|
|
1742
|
+
]);
|
|
1743
|
+
const total_collateral_value = React2.useMemo(() => {
|
|
1744
|
+
if (!unSettledPnl) return null;
|
|
1745
|
+
return new utils.Decimal(finalMargin).add(unSettledPnl).toNumber();
|
|
1746
|
+
}, [unSettledPnl, finalMargin]);
|
|
1747
|
+
const effectiveLeverage = React2.useMemo(() => {
|
|
1748
|
+
if (!notional || !total_collateral_value) return null;
|
|
1749
|
+
return notional.div(total_collateral_value).toNumber();
|
|
1750
|
+
}, [notional, total_collateral_value]);
|
|
1751
|
+
return {
|
|
1752
|
+
maxAmount,
|
|
1753
|
+
liquidationPrice,
|
|
1754
|
+
effectiveLeverage
|
|
1755
|
+
};
|
|
1756
|
+
};
|
|
1757
|
+
var usePositionMargin_default = usePositionMargin;
|
|
1758
|
+
|
|
1759
|
+
// src/components/positions/adjustMargin/adjustMargin.script.tsx
|
|
1760
|
+
var useAdjustMarginScript = (props) => {
|
|
1761
|
+
const { position, symbol, close } = props;
|
|
1762
|
+
const { t } = i18n.useTranslation();
|
|
1763
|
+
const [tab, setTab] = React2.useState("add");
|
|
1764
|
+
const [inputValue, setInputValue] = React2.useState("");
|
|
1765
|
+
const [sliderValue, setSliderValue] = React2.useState(0);
|
|
1766
|
+
const [updateMargin, { isMutating: isLoading }] = hooks.useMutation(
|
|
1767
|
+
"/v1/position_margin",
|
|
1768
|
+
"POST"
|
|
1769
|
+
);
|
|
1770
|
+
const isAdd = React2.useMemo(() => {
|
|
1771
|
+
return tab === "add";
|
|
1772
|
+
}, [tab]);
|
|
1773
|
+
const currentMargin = position.margin ?? 0;
|
|
1774
|
+
const finalMargin = React2.useMemo(() => {
|
|
1775
|
+
const delta = new utils.Decimal(inputValue || 0);
|
|
1776
|
+
if (tab === "add") return currentMargin + delta.toNumber();
|
|
1777
|
+
return currentMargin - delta.toNumber();
|
|
1778
|
+
}, [currentMargin, inputValue, tab]);
|
|
1779
|
+
const { maxAmount, liquidationPrice, effectiveLeverage } = usePositionMargin_default(
|
|
1780
|
+
symbol,
|
|
1781
|
+
isAdd,
|
|
1782
|
+
currentMargin,
|
|
1783
|
+
finalMargin
|
|
1784
|
+
);
|
|
1785
|
+
const syncSliderFromInput = React2.useCallback(
|
|
1786
|
+
(value) => {
|
|
1787
|
+
if (!value) {
|
|
1788
|
+
setSliderValue(0);
|
|
1789
|
+
return;
|
|
1790
|
+
}
|
|
1791
|
+
if (!maxAmount) return;
|
|
1792
|
+
const val = new utils.Decimal(value);
|
|
1793
|
+
if (maxAmount === 0) {
|
|
1794
|
+
setSliderValue(0);
|
|
1795
|
+
return;
|
|
1796
|
+
}
|
|
1797
|
+
const percent = val.div(maxAmount).mul(100).toNumber();
|
|
1798
|
+
setSliderValue(Math.min(100, Math.max(0, percent)));
|
|
1799
|
+
},
|
|
1800
|
+
[maxAmount]
|
|
1801
|
+
);
|
|
1802
|
+
const syncInputFromSlider = React2.useCallback(
|
|
1803
|
+
(value) => {
|
|
1804
|
+
if (!maxAmount) return;
|
|
1805
|
+
const val = new utils.Decimal(maxAmount).mul(value).div(100);
|
|
1806
|
+
setInputValue(val.toFixed(2, utils.Decimal.ROUND_DOWN));
|
|
1807
|
+
},
|
|
1808
|
+
[maxAmount]
|
|
1809
|
+
);
|
|
1810
|
+
const onInputChange = React2.useCallback(
|
|
1811
|
+
(value) => {
|
|
1812
|
+
let finalValue = value;
|
|
1813
|
+
if (maxAmount && value) {
|
|
1814
|
+
const inputDecimal = new utils.Decimal(value);
|
|
1815
|
+
if (inputDecimal.gt(maxAmount)) {
|
|
1816
|
+
finalValue = new utils.Decimal(maxAmount).toFixed(2, utils.Decimal.ROUND_DOWN);
|
|
1817
|
+
}
|
|
1818
|
+
}
|
|
1819
|
+
setInputValue(finalValue);
|
|
1820
|
+
syncSliderFromInput(finalValue);
|
|
1821
|
+
},
|
|
1822
|
+
[syncSliderFromInput, maxAmount]
|
|
1823
|
+
);
|
|
1824
|
+
const onSliderChange = React2.useCallback(
|
|
1825
|
+
(value) => {
|
|
1826
|
+
setSliderValue(value);
|
|
1827
|
+
syncInputFromSlider(value);
|
|
1828
|
+
},
|
|
1829
|
+
[syncInputFromSlider]
|
|
1830
|
+
);
|
|
1831
|
+
const onTabChange = React2.useCallback((nextTab) => {
|
|
1832
|
+
setTab(nextTab);
|
|
1833
|
+
setInputValue("");
|
|
1834
|
+
setSliderValue(0);
|
|
1835
|
+
}, []);
|
|
1836
|
+
const canConfirm = React2.useMemo(() => {
|
|
1837
|
+
if (!inputValue) return false;
|
|
1838
|
+
const value = new utils.Decimal(inputValue);
|
|
1839
|
+
return !value.isZero() && value.isPositive();
|
|
1840
|
+
}, [inputValue]);
|
|
1841
|
+
const onConfirm = React2.useCallback(async () => {
|
|
1842
|
+
if (!inputValue || new utils.Decimal(inputValue).isZero()) return;
|
|
1843
|
+
if (maxAmount) {
|
|
1844
|
+
const inputDecimal = new utils.Decimal(inputValue);
|
|
1845
|
+
if (inputDecimal.gt(maxAmount)) {
|
|
1846
|
+
ui.toast.error(t("positions.adjustMargin.marginCannotMoreThanMax"));
|
|
1847
|
+
return;
|
|
1848
|
+
}
|
|
1849
|
+
}
|
|
1850
|
+
try {
|
|
1851
|
+
const payload = {
|
|
1852
|
+
symbol,
|
|
1853
|
+
amount: new utils.Decimal(inputValue).toString(),
|
|
1854
|
+
type: tab === "add" ? "ADD" : "REDUCE"
|
|
1855
|
+
};
|
|
1856
|
+
const response = await updateMargin(payload);
|
|
1857
|
+
if (!response?.success) {
|
|
1858
|
+
ui.toast.error(response?.message || t("positions.adjustMargin.failed"));
|
|
1859
|
+
return;
|
|
1860
|
+
}
|
|
1861
|
+
ui.toast.success(t("positions.adjustMargin.success"));
|
|
1862
|
+
close();
|
|
1863
|
+
} catch (error) {
|
|
1864
|
+
const message = error instanceof Error ? error.message : void 0;
|
|
1865
|
+
ui.toast.error(message || t("positions.adjustMargin.failed"));
|
|
1866
|
+
}
|
|
1867
|
+
}, [close, inputValue, symbol, t, tab, updateMargin, maxAmount]);
|
|
1868
|
+
return {
|
|
1869
|
+
symbol,
|
|
1870
|
+
tab,
|
|
1871
|
+
inputValue,
|
|
1872
|
+
sliderValue,
|
|
1873
|
+
maxAmount: maxAmount ?? 0,
|
|
1874
|
+
currentMargin,
|
|
1875
|
+
liquidationPrice,
|
|
1876
|
+
effectiveLeverage: effectiveLeverage ?? 0,
|
|
1877
|
+
isLoading,
|
|
1878
|
+
isAdd,
|
|
1879
|
+
canConfirm,
|
|
1880
|
+
onTabChange,
|
|
1881
|
+
onInputChange,
|
|
1882
|
+
onSliderChange,
|
|
1883
|
+
onConfirm,
|
|
1884
|
+
close
|
|
1885
|
+
};
|
|
1886
|
+
};
|
|
1887
|
+
var Footer = (props) => {
|
|
1888
|
+
const { t } = i18n.useTranslation();
|
|
1889
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 3, className: "oui-w-full oui-pt-5", children: [
|
|
1890
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1891
|
+
ui.Button,
|
|
1892
|
+
{
|
|
1893
|
+
variant: "contained",
|
|
1894
|
+
fullWidth: true,
|
|
1895
|
+
size: "lg",
|
|
1896
|
+
color: "secondary",
|
|
1897
|
+
className: "oui-h-10",
|
|
1898
|
+
onClick: props.close,
|
|
1899
|
+
children: t("common.cancel")
|
|
1900
|
+
}
|
|
1901
|
+
),
|
|
1902
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1903
|
+
ui.Button,
|
|
1904
|
+
{
|
|
1905
|
+
variant: "contained",
|
|
1906
|
+
color: "primary",
|
|
1907
|
+
fullWidth: true,
|
|
1908
|
+
size: "lg",
|
|
1909
|
+
className: "oui-h-10",
|
|
1910
|
+
loading: props.isLoading,
|
|
1911
|
+
disabled: !props.canConfirm,
|
|
1912
|
+
onClick: props.onConfirm,
|
|
1913
|
+
children: t("common.confirm")
|
|
1914
|
+
}
|
|
1915
|
+
)
|
|
1916
|
+
] });
|
|
1917
|
+
};
|
|
1918
|
+
var fotter_default = Footer;
|
|
1919
|
+
var Infos = ({
|
|
1920
|
+
currentMargin,
|
|
1921
|
+
liquidationPrice,
|
|
1922
|
+
effectiveLeverage
|
|
1923
|
+
}) => {
|
|
1924
|
+
const { t } = i18n.useTranslation();
|
|
1925
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1926
|
+
ui.Flex,
|
|
1927
|
+
{
|
|
1928
|
+
direction: "column",
|
|
1929
|
+
gap: 1,
|
|
1930
|
+
className: "oui-w-full oui-rounded-[6px] oui-bg-base-6 oui-p-3 oui-text-2xs oui-font-semibold",
|
|
1931
|
+
children: [
|
|
1932
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1933
|
+
ui.Statistic,
|
|
1934
|
+
{
|
|
1935
|
+
label: t("positions.adjustMargin.currentMargin"),
|
|
1936
|
+
valueProps: { dp: 2, unit: " USDC", padding: false },
|
|
1937
|
+
classNames: {
|
|
1938
|
+
root: "oui-flex-row oui-justify-between oui-items-center oui-w-full oui-text-2xs oui-h-5",
|
|
1939
|
+
label: "oui-text-2xs"
|
|
1940
|
+
},
|
|
1941
|
+
children: currentMargin
|
|
1942
|
+
}
|
|
1943
|
+
),
|
|
1944
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1945
|
+
ui.Statistic,
|
|
1946
|
+
{
|
|
1947
|
+
label: t("positions.adjustMargin.liqPriceAfter"),
|
|
1948
|
+
valueProps: { dp: 2, unit: " USDC", padding: false },
|
|
1949
|
+
classNames: {
|
|
1950
|
+
root: "oui-flex-row oui-justify-between oui-items-center oui-w-full oui-text-2xs oui-h-5",
|
|
1951
|
+
label: "oui-text-2xs"
|
|
1952
|
+
},
|
|
1953
|
+
children: liquidationPrice ?? "--"
|
|
1954
|
+
}
|
|
1955
|
+
),
|
|
1956
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1957
|
+
ui.Statistic,
|
|
1958
|
+
{
|
|
1959
|
+
label: t("positions.adjustMargin.leverageAfter"),
|
|
1960
|
+
valueProps: { dp: 2, unit: " x" },
|
|
1961
|
+
classNames: {
|
|
1962
|
+
root: "oui-flex-row oui-justify-between oui-items-center oui-w-full oui-text-2xs oui-h-5",
|
|
1963
|
+
label: "oui-text-2xs"
|
|
1964
|
+
},
|
|
1965
|
+
children: effectiveLeverage ?? "--"
|
|
1966
|
+
}
|
|
1967
|
+
)
|
|
1968
|
+
]
|
|
1969
|
+
}
|
|
1970
|
+
);
|
|
1971
|
+
};
|
|
1972
|
+
var MarginActions = ({
|
|
1973
|
+
isAdd,
|
|
1974
|
+
onTabChange
|
|
1975
|
+
}) => {
|
|
1976
|
+
const { t } = i18n.useTranslation();
|
|
1977
|
+
const tabBase = "oui-h-7 oui-rounded-[4px] oui-text-xs oui-font-semibold oui-transition-colors";
|
|
1978
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { className: "oui-w-full oui-gap-[6px]", children: [
|
|
1979
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1980
|
+
ui.Button,
|
|
1981
|
+
{
|
|
1982
|
+
size: "md",
|
|
1983
|
+
fullWidth: true,
|
|
1984
|
+
variant: "contained",
|
|
1985
|
+
color: "secondary",
|
|
1986
|
+
className: ui.cn(
|
|
1987
|
+
tabBase,
|
|
1988
|
+
isAdd && "oui-bg-base-5 oui-text-base-contrast-98",
|
|
1989
|
+
!isAdd && "oui-bg-base-7 oui-text-base-contrast-54 hover:oui-text-base-contrast-80"
|
|
1990
|
+
),
|
|
1991
|
+
onClick: () => onTabChange("add"),
|
|
1992
|
+
children: t("positions.adjustMargin.add")
|
|
1993
|
+
}
|
|
1994
|
+
),
|
|
1995
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1996
|
+
ui.Button,
|
|
1997
|
+
{
|
|
1998
|
+
size: "sm",
|
|
1999
|
+
fullWidth: true,
|
|
2000
|
+
variant: "contained",
|
|
2001
|
+
color: "secondary",
|
|
2002
|
+
className: ui.cn(
|
|
2003
|
+
tabBase,
|
|
2004
|
+
!isAdd && "oui-bg-base-5 oui-text-base-contrast-98 hover:oui-text-base-contrast-80",
|
|
2005
|
+
isAdd && "oui-bg-base-7 oui-text-base-contrast-54 hover:oui-text-base-contrast-80"
|
|
2006
|
+
),
|
|
2007
|
+
onClick: () => onTabChange("reduce"),
|
|
2008
|
+
children: t("positions.adjustMargin.reduce")
|
|
2009
|
+
}
|
|
2010
|
+
)
|
|
2011
|
+
] });
|
|
2012
|
+
};
|
|
2013
|
+
var Quantity = ({
|
|
2014
|
+
inputValue,
|
|
2015
|
+
sliderValue,
|
|
2016
|
+
maxAmount,
|
|
2017
|
+
onInputChange,
|
|
2018
|
+
onSliderChange
|
|
2019
|
+
}) => {
|
|
2020
|
+
const { t } = i18n.useTranslation();
|
|
2021
|
+
const percentMarks = React2.useMemo(
|
|
2022
|
+
() => [0, 25, 50, 75, 100].map((m) => ({ value: m, label: `${m}%` })),
|
|
2023
|
+
[]
|
|
2024
|
+
);
|
|
2025
|
+
const isMaxClickable = maxAmount > 0;
|
|
2026
|
+
const handleSetToMax = React2.useCallback(() => {
|
|
2027
|
+
if (!isMaxClickable) return;
|
|
2028
|
+
onSliderChange(100);
|
|
2029
|
+
}, [isMaxClickable, onSliderChange]);
|
|
2030
|
+
const handleKeyDown = React2.useCallback(
|
|
2031
|
+
(e) => {
|
|
2032
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
2033
|
+
e.preventDefault();
|
|
2034
|
+
handleSetToMax();
|
|
2035
|
+
}
|
|
2036
|
+
},
|
|
2037
|
+
[handleSetToMax]
|
|
2038
|
+
);
|
|
2039
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", gap: 3, className: "oui-w-full", children: [
|
|
2040
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2041
|
+
ui.Input,
|
|
2042
|
+
{
|
|
2043
|
+
value: inputValue,
|
|
2044
|
+
onValueChange: onInputChange,
|
|
2045
|
+
type: "text",
|
|
2046
|
+
fullWidth: true,
|
|
2047
|
+
size: "lg",
|
|
2048
|
+
align: "right",
|
|
2049
|
+
prefix: t("positions.adjustMargin.quantity"),
|
|
2050
|
+
suffix: "USDC",
|
|
2051
|
+
formatters: [
|
|
2052
|
+
ui.inputFormatter.numberFormatter,
|
|
2053
|
+
ui.inputFormatter.dpFormatter(2)
|
|
2054
|
+
],
|
|
2055
|
+
disabled: maxAmount === null || maxAmount <= 0,
|
|
2056
|
+
autoComplete: "off",
|
|
2057
|
+
classNames: {
|
|
2058
|
+
// Keep border color stable and remove focus ring (Input has focus-within:outline-primary-light by default)
|
|
2059
|
+
root: "oui-rounded-[6px] oui-bg-base-6 oui-border oui-border-solid oui-border-white/[0.12] oui-outline oui-outline-1 oui-outline-offset-0 oui-outline-transparent focus-within:oui-outline-transparent",
|
|
2060
|
+
// keep value aligned to suffix side and match design emphasis
|
|
2061
|
+
input: "oui-text-sm oui-font-semibold oui-text-base-contrast-98",
|
|
2062
|
+
// override default additional padding so value can sit closer to suffix
|
|
2063
|
+
additional: "oui-px-0",
|
|
2064
|
+
prefix: "oui-pl-3 oui-pr-2 oui-text-sm oui-text-base-contrast-54",
|
|
2065
|
+
suffix: "oui-pl-2 oui-pr-3 oui-text-sm oui-text-base-contrast-54"
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
),
|
|
2069
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", gap: 2, className: "oui-w-full", children: [
|
|
2070
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2071
|
+
ui.Slider,
|
|
2072
|
+
{
|
|
2073
|
+
value: [sliderValue],
|
|
2074
|
+
onValueChange: (val) => onSliderChange(val[0]),
|
|
2075
|
+
max: 100,
|
|
2076
|
+
min: 0,
|
|
2077
|
+
step: 1,
|
|
2078
|
+
color: "primary",
|
|
2079
|
+
showTip: true,
|
|
2080
|
+
tipFormatter: (v, _min, _max, percent) => `${percent.toFixed(0)}%`,
|
|
2081
|
+
marks: percentMarks,
|
|
2082
|
+
markLabelVisible: false,
|
|
2083
|
+
disabled: maxAmount === null || maxAmount <= 0
|
|
2084
|
+
}
|
|
2085
|
+
),
|
|
2086
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", className: "oui-w-full", children: [
|
|
2087
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", className: "oui-text-primary", children: `${sliderValue.toFixed(0)}%` }),
|
|
2088
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2089
|
+
ui.Flex,
|
|
2090
|
+
{
|
|
2091
|
+
gap: 1,
|
|
2092
|
+
itemAlign: "baseline",
|
|
2093
|
+
role: isMaxClickable ? "button" : void 0,
|
|
2094
|
+
tabIndex: isMaxClickable ? 0 : void 0,
|
|
2095
|
+
onClick: isMaxClickable ? handleSetToMax : void 0,
|
|
2096
|
+
onKeyDown: isMaxClickable ? handleKeyDown : void 0,
|
|
2097
|
+
className: isMaxClickable ? "oui-cursor-pointer oui-opacity-90 hover:oui-opacity-100" : void 0,
|
|
2098
|
+
children: [
|
|
2099
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", className: "oui-text-primary", children: t("positions.adjustMargin.max") }),
|
|
2100
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { size: "2xs", intensity: 54, dp: 2, children: maxAmount })
|
|
2101
|
+
]
|
|
2102
|
+
}
|
|
2103
|
+
)
|
|
2104
|
+
] })
|
|
2105
|
+
] })
|
|
2106
|
+
] });
|
|
2107
|
+
};
|
|
2108
|
+
var SymbolInfo = ({ symbol }) => {
|
|
2109
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-flex oui-items-center oui-gap-2", children: [
|
|
2110
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.TokenIcon, { symbol, className: "oui-size-5" }),
|
|
2111
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2112
|
+
ui.Text.formatted,
|
|
2113
|
+
{
|
|
2114
|
+
rule: "symbol",
|
|
2115
|
+
formatString: "base-type",
|
|
2116
|
+
size: "base",
|
|
2117
|
+
weight: "semibold",
|
|
2118
|
+
intensity: 98,
|
|
2119
|
+
children: symbol
|
|
2120
|
+
}
|
|
2121
|
+
)
|
|
2122
|
+
] });
|
|
2123
|
+
};
|
|
2124
|
+
var Title = ({ close }) => {
|
|
2125
|
+
const { t } = i18n.useTranslation();
|
|
2126
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-w-full", children: [
|
|
2127
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", itemAlign: "center", children: [
|
|
2128
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2129
|
+
ui.Text,
|
|
2130
|
+
{
|
|
2131
|
+
className: "oui-text-base oui-leading-6 oui-font-semibold oui-tracking-[0.48px]",
|
|
2132
|
+
intensity: 98,
|
|
2133
|
+
children: t("positions.adjustMargin.title")
|
|
2134
|
+
}
|
|
2135
|
+
),
|
|
2136
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { onClick: close, color: "secondary", children: /* @__PURE__ */ jsxRuntime.jsx(ui.CloseIcon, { size: 18, color: "white", opacity: 0.98 }) })
|
|
2137
|
+
] }),
|
|
2138
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { className: "oui-mt-[9px] oui-w-full" })
|
|
2139
|
+
] });
|
|
2140
|
+
};
|
|
2141
|
+
var title_default = Title;
|
|
2142
|
+
var AdjustMargin = (props) => {
|
|
2143
|
+
const {
|
|
2144
|
+
symbol,
|
|
2145
|
+
inputValue,
|
|
2146
|
+
sliderValue,
|
|
2147
|
+
maxAmount,
|
|
2148
|
+
currentMargin,
|
|
2149
|
+
liquidationPrice,
|
|
2150
|
+
effectiveLeverage,
|
|
2151
|
+
onTabChange,
|
|
2152
|
+
onInputChange,
|
|
2153
|
+
onSliderChange,
|
|
2154
|
+
close,
|
|
2155
|
+
isAdd
|
|
2156
|
+
} = props;
|
|
2157
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2158
|
+
ui.Flex,
|
|
2159
|
+
{
|
|
2160
|
+
direction: "column",
|
|
2161
|
+
className: "oui-w-full oui-rounded-[12px] oui-bg-base-8 oui-font-semibold",
|
|
2162
|
+
children: [
|
|
2163
|
+
/* @__PURE__ */ jsxRuntime.jsx(title_default, { close }),
|
|
2164
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-w-full oui-pt-5", children: [
|
|
2165
|
+
/* @__PURE__ */ jsxRuntime.jsx(SymbolInfo, { symbol }),
|
|
2166
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", gap: 4, className: "oui-mt-4 oui-w-full", children: [
|
|
2167
|
+
/* @__PURE__ */ jsxRuntime.jsx(MarginActions, { isAdd, onTabChange }),
|
|
2168
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2169
|
+
Quantity,
|
|
2170
|
+
{
|
|
2171
|
+
inputValue,
|
|
2172
|
+
sliderValue,
|
|
2173
|
+
maxAmount,
|
|
2174
|
+
onInputChange,
|
|
2175
|
+
onSliderChange
|
|
2176
|
+
}
|
|
2177
|
+
),
|
|
2178
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2179
|
+
Infos,
|
|
2180
|
+
{
|
|
2181
|
+
currentMargin,
|
|
2182
|
+
liquidationPrice,
|
|
2183
|
+
effectiveLeverage
|
|
2184
|
+
}
|
|
2185
|
+
)
|
|
2186
|
+
] })
|
|
2187
|
+
] }),
|
|
2188
|
+
/* @__PURE__ */ jsxRuntime.jsx(fotter_default, { ...props })
|
|
2189
|
+
]
|
|
2190
|
+
}
|
|
2191
|
+
);
|
|
2192
|
+
};
|
|
2193
|
+
var AdjustMarginDialogId = "AdjustMarginDialog";
|
|
2194
|
+
var AdjustMarginSheetId = "AdjustMarginSheet";
|
|
2195
|
+
var AdjustMarginWidget = (props) => {
|
|
2196
|
+
const { isMobile } = ui.useScreen();
|
|
2197
|
+
const state = useAdjustMarginScript({
|
|
2198
|
+
position: props.position,
|
|
2199
|
+
symbol: props.symbol,
|
|
2200
|
+
close: () => ui.modal.hide(isMobile ? AdjustMarginSheetId : AdjustMarginDialogId)
|
|
2201
|
+
});
|
|
2202
|
+
return /* @__PURE__ */ jsxRuntime.jsx(AdjustMargin, { ...state });
|
|
2203
|
+
};
|
|
2204
|
+
ui.registerSimpleDialog(AdjustMarginDialogId, AdjustMarginWidget, {
|
|
2205
|
+
title: void 0,
|
|
2206
|
+
closable: false,
|
|
2207
|
+
size: "sm"
|
|
2208
|
+
});
|
|
2209
|
+
ui.registerSimpleSheet(AdjustMarginSheetId, AdjustMarginWidget, {
|
|
2210
|
+
title: void 0,
|
|
2211
|
+
closable: false
|
|
2212
|
+
});
|
|
1607
2213
|
var QuantitySlider = (props) => {
|
|
1608
2214
|
const { t } = i18n.useTranslation();
|
|
1609
2215
|
const [sliderValue, setSliderValue] = React2.useState(props.value);
|
|
@@ -2260,29 +2866,59 @@ var AddIcon = (props) => {
|
|
|
2260
2866
|
);
|
|
2261
2867
|
};
|
|
2262
2868
|
var LeverageBadge = (props) => {
|
|
2263
|
-
const { symbol, leverage } = props;
|
|
2869
|
+
const { symbol, leverage, marginMode } = props;
|
|
2870
|
+
const { t } = i18n.useTranslation();
|
|
2871
|
+
const resolvedMarginMode = marginMode;
|
|
2264
2872
|
const showModal = () => {
|
|
2265
2873
|
ui.modal.show(props.modalId, {
|
|
2266
2874
|
symbol,
|
|
2267
|
-
curLeverage:
|
|
2875
|
+
curLeverage: leverage,
|
|
2876
|
+
marginMode: resolvedMarginMode
|
|
2268
2877
|
});
|
|
2269
2878
|
};
|
|
2270
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2879
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-flex oui-items-center oui-gap-1", children: [
|
|
2880
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2881
|
+
"div",
|
|
2882
|
+
{
|
|
2883
|
+
className: ui.cn(
|
|
2884
|
+
"oui-flex oui-h-[18px] oui-items-center",
|
|
2885
|
+
"oui-rounded oui-bg-line-6 oui-px-2",
|
|
2886
|
+
"oui-text-2xs oui-font-semibold oui-text-base-contrast-36"
|
|
2887
|
+
),
|
|
2888
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: resolvedMarginMode === void 0 ? "--" : resolvedMarginMode === types.MarginMode.ISOLATED ? t("marginMode.isolated") : t("marginMode.cross") })
|
|
2889
|
+
}
|
|
2890
|
+
),
|
|
2891
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2892
|
+
"div",
|
|
2893
|
+
{
|
|
2894
|
+
className: ui.cn(
|
|
2895
|
+
"oui-flex oui-h-[18px] oui-items-center oui-gap-1",
|
|
2896
|
+
"oui-rounded oui-bg-line-6 oui-px-2",
|
|
2897
|
+
"oui-text-2xs oui-font-semibold oui-text-base-contrast-36",
|
|
2898
|
+
"oui-cursor-pointer"
|
|
2899
|
+
),
|
|
2900
|
+
onClick: showModal,
|
|
2901
|
+
children: [
|
|
2902
|
+
leverage === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(LeverageDisplay, { symbol, marginMode }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { dp: 0, rm: utils.Decimal.ROUND_DOWN, size: "2xs", unit: "X", children: leverage }),
|
|
2903
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2904
|
+
ui.ChevronRightIcon,
|
|
2905
|
+
{
|
|
2906
|
+
size: 12,
|
|
2907
|
+
className: "oui-text-base-contrast-36",
|
|
2908
|
+
opacity: 1
|
|
2909
|
+
}
|
|
2910
|
+
)
|
|
2911
|
+
]
|
|
2912
|
+
}
|
|
2913
|
+
)
|
|
2914
|
+
] });
|
|
2282
2915
|
};
|
|
2283
|
-
var LeverageDisplay = ({
|
|
2284
|
-
|
|
2285
|
-
|
|
2916
|
+
var LeverageDisplay = ({
|
|
2917
|
+
symbol,
|
|
2918
|
+
marginMode
|
|
2919
|
+
}) => {
|
|
2920
|
+
const leverage = hooks.useLeverageBySymbol(symbol, marginMode);
|
|
2921
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: leverage === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", children: "--" }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { dp: 0, rm: utils.Decimal.ROUND_DOWN, size: "2xs", unit: "X", children: leverage }) });
|
|
2286
2922
|
};
|
|
2287
2923
|
var renderQuantity = (value) => {
|
|
2288
2924
|
const symbolInfo = useSymbolContext();
|
|
@@ -2436,11 +3072,13 @@ var useShareButtonScript = (props) => {
|
|
|
2436
3072
|
const { position, sharePnLConfig, iconSize } = props;
|
|
2437
3073
|
const { getFirstRefCode } = hooks.useReferralInfo();
|
|
2438
3074
|
const symbolsInfo = hooks.useSymbolsInfo();
|
|
2439
|
-
const { data: accountInfo } = hooks.useAccountInfo();
|
|
2440
3075
|
const refCode = React2.useMemo(() => {
|
|
2441
3076
|
return getFirstRefCode()?.code;
|
|
2442
3077
|
}, [getFirstRefCode]);
|
|
2443
|
-
const symbolLeverage = hooks.useLeverageBySymbol(
|
|
3078
|
+
const symbolLeverage = hooks.useLeverageBySymbol(
|
|
3079
|
+
position.symbol,
|
|
3080
|
+
position.margin_mode ?? types.MarginMode.CROSS
|
|
3081
|
+
);
|
|
2444
3082
|
const getHistoryEntity = () => {
|
|
2445
3083
|
const netPnL = position.netPnL || 0;
|
|
2446
3084
|
const openPrice = Math.abs(position.avg_open_price);
|
|
@@ -2449,10 +3087,22 @@ var useShareButtonScript = (props) => {
|
|
|
2449
3087
|
const symbolInfo = symbolsInfo[position.symbol];
|
|
2450
3088
|
const baseIMR = symbolInfo("base_imr");
|
|
2451
3089
|
const IMR_Factor = symbolInfo("imr_factor");
|
|
2452
|
-
if (netPnL !== 0 && quantity !== 0 && openPrice !== 0 &&
|
|
3090
|
+
if (netPnL !== 0 && quantity !== 0 && openPrice !== 0 && baseIMR && // IMR_Factor is possible to be 0
|
|
2453
3091
|
typeof IMR_Factor !== "undefined") {
|
|
2454
3092
|
const notional = perp.positions.notional(quantity, openPrice);
|
|
2455
|
-
const maxLeverage = position.leverage
|
|
3093
|
+
const maxLeverage = position.leverage || symbolLeverage;
|
|
3094
|
+
if (!maxLeverage) {
|
|
3095
|
+
return {
|
|
3096
|
+
side: position.side,
|
|
3097
|
+
pnl: netPnL,
|
|
3098
|
+
roi,
|
|
3099
|
+
openPrice,
|
|
3100
|
+
closePrice: Math.abs(position.avg_close_price),
|
|
3101
|
+
openTime: position.open_timestamp,
|
|
3102
|
+
closeTime: position.close_timestamp,
|
|
3103
|
+
quantity: position.closed_position_qty
|
|
3104
|
+
};
|
|
3105
|
+
}
|
|
2456
3106
|
const imr = perp.account.IMR({
|
|
2457
3107
|
maxLeverage,
|
|
2458
3108
|
baseIMR,
|
|
@@ -2496,7 +3146,8 @@ var useShareButtonScript = (props) => {
|
|
|
2496
3146
|
symbol: position.symbol,
|
|
2497
3147
|
// when position.leverage is empty, use leverage from useSymbolLeverage
|
|
2498
3148
|
leverage: position.leverage || symbolLeverage,
|
|
2499
|
-
...entity
|
|
3149
|
+
...entity,
|
|
3150
|
+
marginMode: position.margin_mode
|
|
2500
3151
|
},
|
|
2501
3152
|
refCode,
|
|
2502
3153
|
...sharePnLConfig
|
|
@@ -2811,7 +3462,7 @@ var useColumn = (config) => {
|
|
|
2811
3462
|
positionReverse
|
|
2812
3463
|
} = config;
|
|
2813
3464
|
const { t } = i18n.useTranslation();
|
|
2814
|
-
|
|
3465
|
+
const { isMobile } = ui.useScreen();
|
|
2815
3466
|
const column = React2.useMemo(
|
|
2816
3467
|
() => [
|
|
2817
3468
|
{
|
|
@@ -2854,7 +3505,8 @@ var useColumn = (config) => {
|
|
|
2854
3505
|
{
|
|
2855
3506
|
symbol: value,
|
|
2856
3507
|
leverage: record.leverage,
|
|
2857
|
-
modalId: uiLeverage.SymbolLeverageDialogId
|
|
3508
|
+
modalId: uiLeverage.SymbolLeverageDialogId,
|
|
3509
|
+
marginMode: record.margin_mode
|
|
2858
3510
|
}
|
|
2859
3511
|
),
|
|
2860
3512
|
/* @__PURE__ */ jsxRuntime.jsx(RwaStatusTag, { symbol: value })
|
|
@@ -3043,17 +3695,13 @@ var useColumn = (config) => {
|
|
|
3043
3695
|
ui.Tooltip,
|
|
3044
3696
|
{
|
|
3045
3697
|
className: "oui-max-w-[280px] oui-bg-base-8 oui-p-3 oui-text-2xs oui-text-base-contrast-54",
|
|
3046
|
-
content: /* @__PURE__ */ jsxRuntime.
|
|
3698
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3047
3699
|
ui.Flex,
|
|
3048
3700
|
{
|
|
3049
3701
|
direction: "column",
|
|
3050
3702
|
gap: 3,
|
|
3051
3703
|
className: "oui-rounded-sm oui-bg-base-8 oui-text-base-contrast-54",
|
|
3052
|
-
children:
|
|
3053
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: t("positions.column.margin.tooltip") }),
|
|
3054
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { className: "oui-w-full" }),
|
|
3055
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: t("positions.column.margin.formula") })
|
|
3056
|
-
]
|
|
3704
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: t("positions.column.margin.tooltip") })
|
|
3057
3705
|
}
|
|
3058
3706
|
),
|
|
3059
3707
|
children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-underline oui-decoration-dotted", children: t("positions.column.margin") })
|
|
@@ -3063,7 +3711,26 @@ var useColumn = (config) => {
|
|
|
3063
3711
|
onSort: true,
|
|
3064
3712
|
width: 140,
|
|
3065
3713
|
rule: "price",
|
|
3066
|
-
render: (value) =>
|
|
3714
|
+
render: (value, record) => {
|
|
3715
|
+
const isIsolated = record.margin_mode === "ISOLATED";
|
|
3716
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 2, itemAlign: "center", children: [
|
|
3717
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { children: isIsolated ? record.margin ?? "--" : "--" }),
|
|
3718
|
+
isIsolated && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3719
|
+
ui.IconButton,
|
|
3720
|
+
{
|
|
3721
|
+
color: "secondary",
|
|
3722
|
+
onClick: (e) => {
|
|
3723
|
+
e.stopPropagation();
|
|
3724
|
+
ui.modal.show(AdjustMarginDialogId, {
|
|
3725
|
+
position: record,
|
|
3726
|
+
symbol: record.symbol
|
|
3727
|
+
});
|
|
3728
|
+
},
|
|
3729
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ui.AddCircleIcon, { size: 16, fill: "currentColor", opacity: 1 })
|
|
3730
|
+
}
|
|
3731
|
+
)
|
|
3732
|
+
] });
|
|
3733
|
+
}
|
|
3067
3734
|
},
|
|
3068
3735
|
// {
|
|
3069
3736
|
// title: t("funding.fundingFee"),
|
|
@@ -3128,7 +3795,8 @@ var SymbolToken = (props) => {
|
|
|
3128
3795
|
{
|
|
3129
3796
|
symbol: item.symbol,
|
|
3130
3797
|
leverage: item.leverage,
|
|
3131
|
-
modalId: uiLeverage.SymbolLeverageSheetId
|
|
3798
|
+
modalId: uiLeverage.SymbolLeverageSheetId,
|
|
3799
|
+
marginMode: item.margin_mode
|
|
3132
3800
|
}
|
|
3133
3801
|
)
|
|
3134
3802
|
] }),
|
|
@@ -3211,11 +3879,8 @@ var Qty = (props) => {
|
|
|
3211
3879
|
var Margin = (props) => {
|
|
3212
3880
|
const { item } = props;
|
|
3213
3881
|
const { t } = i18n.useTranslation();
|
|
3214
|
-
const
|
|
3215
|
-
|
|
3216
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-my-2 oui-h-px oui-w-full oui-bg-base-8" }),
|
|
3217
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { children: t("positions.column.margin.formula") })
|
|
3218
|
-
] });
|
|
3882
|
+
const isIsolated = item.margin_mode === "ISOLATED";
|
|
3883
|
+
const marginTipsContent = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-text-2xs oui-text-base-contrast-80", children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: t("positions.column.margin.tooltip") }) });
|
|
3219
3884
|
const marginLabel = /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-underline oui-decoration-dotted", children: t("positions.column.margin") });
|
|
3220
3885
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3221
3886
|
ui.Statistic,
|
|
@@ -3232,7 +3897,23 @@ var Margin = (props) => {
|
|
|
3232
3897
|
root: "oui-text-xs",
|
|
3233
3898
|
label: "oui-text-2xs"
|
|
3234
3899
|
},
|
|
3235
|
-
children: /* @__PURE__ */ jsxRuntime.
|
|
3900
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 1, children: [
|
|
3901
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { dp: 2, intensity: 80, children: isIsolated ? item.margin ?? "--" : "--" }),
|
|
3902
|
+
isIsolated && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3903
|
+
ui.IconButton,
|
|
3904
|
+
{
|
|
3905
|
+
color: "secondary",
|
|
3906
|
+
onClick: (e) => {
|
|
3907
|
+
e.stopPropagation();
|
|
3908
|
+
ui.modal.show(AdjustMarginSheetId, {
|
|
3909
|
+
position: item,
|
|
3910
|
+
symbol: item.symbol
|
|
3911
|
+
});
|
|
3912
|
+
},
|
|
3913
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ui.AddCircleIcon, { size: 16, fill: "currentColor", opacity: 1 })
|
|
3914
|
+
}
|
|
3915
|
+
)
|
|
3916
|
+
] })
|
|
3236
3917
|
}
|
|
3237
3918
|
);
|
|
3238
3919
|
};
|
|
@@ -3637,7 +4318,7 @@ var Positions = (props) => {
|
|
|
3637
4318
|
columns,
|
|
3638
4319
|
bordered: true,
|
|
3639
4320
|
dataSource,
|
|
3640
|
-
generatedRowKey: (record) => record.symbol
|
|
4321
|
+
generatedRowKey: (record, index) => `${record.symbol}-${index}`,
|
|
3641
4322
|
renderRowContainer: (record, index, children) => {
|
|
3642
4323
|
return /* @__PURE__ */ jsxRuntime.jsx(SymbolProvider, { symbol: record.symbol, children: /* @__PURE__ */ jsxRuntime.jsx(PositionsRowProvider, { position: record, children }) });
|
|
3643
4324
|
},
|
|
@@ -3709,7 +4390,7 @@ var CombinePositions = (props) => {
|
|
|
3709
4390
|
dataSource,
|
|
3710
4391
|
expanded: true,
|
|
3711
4392
|
getSubRows: (row) => row.children,
|
|
3712
|
-
generatedRowKey: (record) => `${record.account_id}${record.symbol || ""}`,
|
|
4393
|
+
generatedRowKey: (record, index) => `${record.account_id}${record.symbol || ""}-${index}`,
|
|
3713
4394
|
onCell: (column, record) => {
|
|
3714
4395
|
const isGroup = (record.children ?? []).length > 0;
|
|
3715
4396
|
if (isGroup) {
|
|
@@ -3768,14 +4449,14 @@ var usePositionHistoryColumn = (props) => {
|
|
|
3768
4449
|
onSort: (r1, r2) => {
|
|
3769
4450
|
return r1.symbol?.localeCompare(r2.symbol || "");
|
|
3770
4451
|
},
|
|
3771
|
-
render: (value, record) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
4452
|
+
render: (value, record) => /* @__PURE__ */ jsxRuntime.jsx(SymbolInfo2, { record, onSymbolChange })
|
|
3772
4453
|
},
|
|
3773
4454
|
// quantity
|
|
3774
4455
|
{
|
|
3775
4456
|
title: t("positions.history.column.closed&maxClosed"),
|
|
3776
4457
|
dataIndex: "close_maxClose",
|
|
3777
4458
|
width: 200,
|
|
3778
|
-
render: (value, record) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
4459
|
+
render: (value, record) => /* @__PURE__ */ jsxRuntime.jsx(Quantity2, { record })
|
|
3779
4460
|
},
|
|
3780
4461
|
// net pnl
|
|
3781
4462
|
{
|
|
@@ -3883,7 +4564,7 @@ var usePositionHistoryColumn = (props) => {
|
|
|
3883
4564
|
);
|
|
3884
4565
|
return column;
|
|
3885
4566
|
};
|
|
3886
|
-
var
|
|
4567
|
+
var SymbolInfo2 = (props) => {
|
|
3887
4568
|
const { record, onSymbolChange } = props;
|
|
3888
4569
|
const { t } = i18n.useTranslation();
|
|
3889
4570
|
const tags = React2.useMemo(() => {
|
|
@@ -3997,7 +4678,7 @@ var SymbolInfo = (props) => {
|
|
|
3997
4678
|
] })
|
|
3998
4679
|
] });
|
|
3999
4680
|
};
|
|
4000
|
-
var
|
|
4681
|
+
var Quantity2 = (props) => {
|
|
4001
4682
|
const { record } = props;
|
|
4002
4683
|
const { base_dp } = useSymbolContext();
|
|
4003
4684
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -4130,6 +4811,8 @@ var usePositionHistoryScript = (props) => {
|
|
|
4130
4811
|
const netPnL = item.realized_pnl - item.accumulated_funding_fee - item.trading_fee;
|
|
4131
4812
|
return {
|
|
4132
4813
|
...item,
|
|
4814
|
+
// convert margin_mode to MarginMode
|
|
4815
|
+
margin_mode: item.margin_mode === 1 || item.margin_mode === types.MarginMode.ISOLATED ? types.MarginMode.ISOLATED : types.MarginMode.CROSS,
|
|
4133
4816
|
netPnL
|
|
4134
4817
|
};
|
|
4135
4818
|
}
|
|
@@ -4743,7 +5426,7 @@ var PositionHistory = (props) => {
|
|
|
4743
5426
|
columns: column,
|
|
4744
5427
|
bordered: true,
|
|
4745
5428
|
dataSource: props.dataSource,
|
|
4746
|
-
generatedRowKey: (record) => `${record.symbol}_${record.position_id}`,
|
|
5429
|
+
generatedRowKey: (record, index) => `${record.symbol}_${record.position_id}_${index}`,
|
|
4747
5430
|
renderRowContainer: (record, index, children) => /* @__PURE__ */ jsxRuntime.jsx(SymbolProvider, { symbol: record.symbol, children }),
|
|
4748
5431
|
manualPagination: false,
|
|
4749
5432
|
pagination,
|
|
@@ -5536,7 +6219,8 @@ var useCloseAllPositionsScript = (options) => {
|
|
|
5536
6219
|
order_type: types.OrderType.MARKET,
|
|
5537
6220
|
side,
|
|
5538
6221
|
order_quantity: quantity,
|
|
5539
|
-
reduce_only: true
|
|
6222
|
+
reduce_only: true,
|
|
6223
|
+
margin_mode: position.margin_mode
|
|
5540
6224
|
};
|
|
5541
6225
|
}),
|
|
5542
6226
|
[]
|