@orderly.network/ui-positions 2.10.2 → 3.0.0-beta.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 +750 -57
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +754 -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,619 @@ 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 = React2.useMemo(() => {
|
|
1643
|
+
if (!currentPosition || !notional || !fundingRates) return null;
|
|
1644
|
+
const fundingRate = fundingRates[currentPosition.symbol];
|
|
1645
|
+
return notional.sub(new utils.Decimal(currentPosition.cost_position)).sub(
|
|
1646
|
+
new utils.Decimal(currentPosition.position_qty).mul(
|
|
1647
|
+
new utils.Decimal(fundingRate.sum_unitary_funding ?? 0).sub(
|
|
1648
|
+
new utils.Decimal(currentPosition.last_sum_unitary_funding)
|
|
1649
|
+
)
|
|
1650
|
+
)
|
|
1651
|
+
);
|
|
1652
|
+
}, [notional, currentPosition, fundingRates]);
|
|
1653
|
+
const imr = React2.useMemo(() => {
|
|
1654
|
+
if (!currentPosition || !symbolsInfo?.[symbol] || !notional) {
|
|
1655
|
+
return null;
|
|
1656
|
+
}
|
|
1657
|
+
const currentSymbolInfo = symbolsInfo[symbol];
|
|
1658
|
+
const maxLeverage = Math.max(currentPosition.leverage ?? 1, 1);
|
|
1659
|
+
const IMR_Factor = accountInfo?.imr_factor?.[symbol] ?? currentSymbolInfo.imr_factor ?? 0;
|
|
1660
|
+
return new utils.Decimal(
|
|
1661
|
+
perp.account.IMR({
|
|
1662
|
+
maxLeverage,
|
|
1663
|
+
baseIMR: currentSymbolInfo.base_imr ?? 0,
|
|
1664
|
+
IMR_Factor,
|
|
1665
|
+
positionNotional: notional.toNumber(),
|
|
1666
|
+
ordersNotional: 0
|
|
1667
|
+
})
|
|
1668
|
+
);
|
|
1669
|
+
}, [currentPosition, symbolsInfo, symbol, notional, accountInfo]);
|
|
1670
|
+
const maxAmount = React2.useMemo(() => {
|
|
1671
|
+
if (isAdd) {
|
|
1672
|
+
if (!freeCollateralUSDCOnly) return null;
|
|
1673
|
+
return Math.max(0, freeCollateralUSDCOnly);
|
|
1674
|
+
}
|
|
1675
|
+
if (!imr || !notional || isolatedMargin === void 0 || isolatedMargin === null || !currentPosition) {
|
|
1676
|
+
return null;
|
|
1677
|
+
}
|
|
1678
|
+
const positionNotional = notional;
|
|
1679
|
+
const imrValue = imr;
|
|
1680
|
+
const unsettledPnlValue = unSettledPnl ?? new utils.Decimal(0);
|
|
1681
|
+
return perp.account.maxReduce({
|
|
1682
|
+
isolatedPositionMargin: isolatedMargin,
|
|
1683
|
+
positionNotional: positionNotional.toNumber(),
|
|
1684
|
+
imr: imrValue.toNumber(),
|
|
1685
|
+
positionUnsettledPnL: unsettledPnlValue.toNumber()
|
|
1686
|
+
});
|
|
1687
|
+
}, [
|
|
1688
|
+
total_cross_unsettled_pnl,
|
|
1689
|
+
usdcHolding,
|
|
1690
|
+
isAdd,
|
|
1691
|
+
freeCollateral,
|
|
1692
|
+
unSettledPnl,
|
|
1693
|
+
isolatedMargin
|
|
1694
|
+
]);
|
|
1695
|
+
const liquidationPrice = React2.useMemo(() => {
|
|
1696
|
+
if (!totalUnsettlementPnl || !currentPosition || !symbolsInfo?.[symbol] || !accountInfo?.imr_factor) {
|
|
1697
|
+
return null;
|
|
1698
|
+
}
|
|
1699
|
+
const currentSymbolInfo = symbolsInfo[symbol];
|
|
1700
|
+
const currentPositionNotional = notional?.toNumber() ?? 0;
|
|
1701
|
+
const currentPositionIMRFactor = accountInfo.imr_factor[symbol] ?? currentSymbolInfo.imr_factor ?? 0;
|
|
1702
|
+
const currentPositionMMR = perp.positions.MMR({
|
|
1703
|
+
baseMMR: currentSymbolInfo.base_mmr ?? 0,
|
|
1704
|
+
baseIMR: currentSymbolInfo.base_imr ?? 0,
|
|
1705
|
+
IMRFactor: currentPositionIMRFactor,
|
|
1706
|
+
positionNotional: currentPositionNotional,
|
|
1707
|
+
IMR_factor_power: 4 / 5
|
|
1708
|
+
});
|
|
1709
|
+
const otherPositions = positions2?.filter((item) => item.symbol !== symbol).map((item) => {
|
|
1710
|
+
const itemSymbolInfo = symbolsInfo[item.symbol];
|
|
1711
|
+
const itemIMRFactor = accountInfo.imr_factor[item.symbol] ?? itemSymbolInfo?.imr_factor ?? 0;
|
|
1712
|
+
const itemNotional = item.notional ?? new utils.Decimal(item.position_qty).mul(item.mark_price).abs().toNumber();
|
|
1713
|
+
const itemMMR = item.mmr ?? perp.positions.MMR({
|
|
1714
|
+
baseMMR: itemSymbolInfo?.base_mmr ?? 0,
|
|
1715
|
+
baseIMR: itemSymbolInfo?.base_imr ?? 0,
|
|
1716
|
+
IMRFactor: itemIMRFactor,
|
|
1717
|
+
positionNotional: itemNotional,
|
|
1718
|
+
IMR_factor_power: 4 / 5
|
|
1719
|
+
});
|
|
1720
|
+
return {
|
|
1721
|
+
symbol: item.symbol,
|
|
1722
|
+
position_qty: item.position_qty,
|
|
1723
|
+
mark_price: item.mark_price,
|
|
1724
|
+
mmr: itemMMR
|
|
1725
|
+
};
|
|
1726
|
+
}) ?? [];
|
|
1727
|
+
const totalCollateral = new utils.Decimal(finalMargin).add(currentPosition.unsettled_pnl ?? 0).toNumber();
|
|
1728
|
+
const liqPrice = perp.positions.liqPrice({
|
|
1729
|
+
markPrice,
|
|
1730
|
+
symbol,
|
|
1731
|
+
totalCollateral,
|
|
1732
|
+
positionQty: currentPosition.position_qty,
|
|
1733
|
+
positions: otherPositions,
|
|
1734
|
+
MMR: currentPositionMMR,
|
|
1735
|
+
baseMMR: currentSymbolInfo.base_mmr ?? 0,
|
|
1736
|
+
baseIMR: currentSymbolInfo.base_imr ?? 0,
|
|
1737
|
+
IMRFactor: currentPositionIMRFactor,
|
|
1738
|
+
costPosition: currentPosition.cost_position ?? 0
|
|
1739
|
+
});
|
|
1740
|
+
return liqPrice;
|
|
1741
|
+
}, [
|
|
1742
|
+
totalUnsettlementPnl,
|
|
1743
|
+
currentPosition,
|
|
1744
|
+
symbolsInfo,
|
|
1745
|
+
symbol,
|
|
1746
|
+
accountInfo,
|
|
1747
|
+
notional,
|
|
1748
|
+
positions2,
|
|
1749
|
+
finalMargin,
|
|
1750
|
+
markPrice
|
|
1751
|
+
]);
|
|
1752
|
+
const total_collateral_value = React2.useMemo(() => {
|
|
1753
|
+
if (!unSettledPnl) return null;
|
|
1754
|
+
return new utils.Decimal(finalMargin).add(unSettledPnl).toNumber();
|
|
1755
|
+
}, [unSettledPnl, finalMargin]);
|
|
1756
|
+
const effectiveLeverage = React2.useMemo(() => {
|
|
1757
|
+
if (!notional || !total_collateral_value) return null;
|
|
1758
|
+
return notional.div(total_collateral_value).toNumber();
|
|
1759
|
+
}, [notional, total_collateral_value]);
|
|
1760
|
+
return {
|
|
1761
|
+
maxAmount,
|
|
1762
|
+
liquidationPrice,
|
|
1763
|
+
effectiveLeverage
|
|
1764
|
+
};
|
|
1765
|
+
};
|
|
1766
|
+
var usePositionMargin_default = usePositionMargin;
|
|
1767
|
+
|
|
1768
|
+
// src/components/positions/adjustMargin/adjustMargin.script.tsx
|
|
1769
|
+
var useAdjustMarginScript = (props) => {
|
|
1770
|
+
const { position, symbol, close } = props;
|
|
1771
|
+
const { t } = i18n.useTranslation();
|
|
1772
|
+
const [tab, setTab] = React2.useState("add");
|
|
1773
|
+
const [inputValue, setInputValue] = React2.useState("");
|
|
1774
|
+
const [sliderValue, setSliderValue] = React2.useState(0);
|
|
1775
|
+
const [updateMargin, { isMutating: isLoading }] = hooks.useMutation(
|
|
1776
|
+
"/v1/position_margin",
|
|
1777
|
+
"POST"
|
|
1778
|
+
);
|
|
1779
|
+
const isAdd = React2.useMemo(() => {
|
|
1780
|
+
return tab === "add";
|
|
1781
|
+
}, [tab]);
|
|
1782
|
+
const currentMargin = position.margin ?? 0;
|
|
1783
|
+
const finalMargin = React2.useMemo(() => {
|
|
1784
|
+
const delta = new utils.Decimal(inputValue || 0);
|
|
1785
|
+
if (tab === "add") return currentMargin + delta.toNumber();
|
|
1786
|
+
return currentMargin - delta.toNumber();
|
|
1787
|
+
}, [currentMargin, inputValue, tab]);
|
|
1788
|
+
const { maxAmount, liquidationPrice, effectiveLeverage } = usePositionMargin_default(
|
|
1789
|
+
symbol,
|
|
1790
|
+
isAdd,
|
|
1791
|
+
currentMargin,
|
|
1792
|
+
finalMargin
|
|
1793
|
+
);
|
|
1794
|
+
const syncSliderFromInput = React2.useCallback(
|
|
1795
|
+
(value) => {
|
|
1796
|
+
if (!value) {
|
|
1797
|
+
setSliderValue(0);
|
|
1798
|
+
return;
|
|
1799
|
+
}
|
|
1800
|
+
if (!maxAmount) return;
|
|
1801
|
+
const val = new utils.Decimal(value);
|
|
1802
|
+
if (maxAmount === 0) {
|
|
1803
|
+
setSliderValue(0);
|
|
1804
|
+
return;
|
|
1805
|
+
}
|
|
1806
|
+
const percent = val.div(maxAmount).mul(100).toNumber();
|
|
1807
|
+
setSliderValue(Math.min(100, Math.max(0, percent)));
|
|
1808
|
+
},
|
|
1809
|
+
[maxAmount]
|
|
1810
|
+
);
|
|
1811
|
+
const syncInputFromSlider = React2.useCallback(
|
|
1812
|
+
(value) => {
|
|
1813
|
+
if (!maxAmount) return;
|
|
1814
|
+
const val = new utils.Decimal(maxAmount).mul(value).div(100);
|
|
1815
|
+
setInputValue(val.toFixed(2, utils.Decimal.ROUND_DOWN));
|
|
1816
|
+
},
|
|
1817
|
+
[maxAmount]
|
|
1818
|
+
);
|
|
1819
|
+
const onInputChange = React2.useCallback(
|
|
1820
|
+
(value) => {
|
|
1821
|
+
let finalValue = value;
|
|
1822
|
+
if (maxAmount && value) {
|
|
1823
|
+
const inputDecimal = new utils.Decimal(value);
|
|
1824
|
+
if (inputDecimal.gt(maxAmount)) {
|
|
1825
|
+
finalValue = new utils.Decimal(maxAmount).toFixed(2, utils.Decimal.ROUND_DOWN);
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
setInputValue(finalValue);
|
|
1829
|
+
syncSliderFromInput(finalValue);
|
|
1830
|
+
},
|
|
1831
|
+
[syncSliderFromInput, maxAmount]
|
|
1832
|
+
);
|
|
1833
|
+
const onSliderChange = React2.useCallback(
|
|
1834
|
+
(value) => {
|
|
1835
|
+
setSliderValue(value);
|
|
1836
|
+
syncInputFromSlider(value);
|
|
1837
|
+
},
|
|
1838
|
+
[syncInputFromSlider]
|
|
1839
|
+
);
|
|
1840
|
+
const onTabChange = React2.useCallback((nextTab) => {
|
|
1841
|
+
setTab(nextTab);
|
|
1842
|
+
setInputValue("");
|
|
1843
|
+
setSliderValue(0);
|
|
1844
|
+
}, []);
|
|
1845
|
+
const canConfirm = React2.useMemo(() => {
|
|
1846
|
+
if (!inputValue) return false;
|
|
1847
|
+
const value = new utils.Decimal(inputValue);
|
|
1848
|
+
return !value.isZero() && value.isPositive();
|
|
1849
|
+
}, [inputValue]);
|
|
1850
|
+
const onConfirm = React2.useCallback(async () => {
|
|
1851
|
+
if (!inputValue || new utils.Decimal(inputValue).isZero()) return;
|
|
1852
|
+
if (maxAmount) {
|
|
1853
|
+
const inputDecimal = new utils.Decimal(inputValue);
|
|
1854
|
+
if (inputDecimal.gt(maxAmount)) {
|
|
1855
|
+
ui.toast.error(t("positions.adjustMargin.marginCannotMoreThanMax"));
|
|
1856
|
+
return;
|
|
1857
|
+
}
|
|
1858
|
+
}
|
|
1859
|
+
try {
|
|
1860
|
+
const payload = {
|
|
1861
|
+
symbol,
|
|
1862
|
+
amount: new utils.Decimal(inputValue).toString(),
|
|
1863
|
+
type: tab === "add" ? "ADD" : "REDUCE"
|
|
1864
|
+
};
|
|
1865
|
+
const response = await updateMargin(payload);
|
|
1866
|
+
if (!response?.success) {
|
|
1867
|
+
ui.toast.error(response?.message || t("positions.adjustMargin.failed"));
|
|
1868
|
+
return;
|
|
1869
|
+
}
|
|
1870
|
+
ui.toast.success(t("positions.adjustMargin.success"));
|
|
1871
|
+
close();
|
|
1872
|
+
} catch (error) {
|
|
1873
|
+
const message = error instanceof Error ? error.message : void 0;
|
|
1874
|
+
ui.toast.error(message || t("positions.adjustMargin.failed"));
|
|
1875
|
+
}
|
|
1876
|
+
}, [close, inputValue, symbol, t, tab, updateMargin, maxAmount]);
|
|
1877
|
+
return {
|
|
1878
|
+
symbol,
|
|
1879
|
+
tab,
|
|
1880
|
+
inputValue,
|
|
1881
|
+
sliderValue,
|
|
1882
|
+
maxAmount: maxAmount ?? 0,
|
|
1883
|
+
currentMargin,
|
|
1884
|
+
liquidationPrice: liquidationPrice ?? 0,
|
|
1885
|
+
effectiveLeverage: effectiveLeverage ?? 0,
|
|
1886
|
+
isLoading,
|
|
1887
|
+
isAdd,
|
|
1888
|
+
canConfirm,
|
|
1889
|
+
onTabChange,
|
|
1890
|
+
onInputChange,
|
|
1891
|
+
onSliderChange,
|
|
1892
|
+
onConfirm,
|
|
1893
|
+
close
|
|
1894
|
+
};
|
|
1895
|
+
};
|
|
1896
|
+
var Footer = (props) => {
|
|
1897
|
+
const { t } = i18n.useTranslation();
|
|
1898
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 3, className: "oui-w-full oui-pt-5", children: [
|
|
1899
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1900
|
+
ui.Button,
|
|
1901
|
+
{
|
|
1902
|
+
variant: "contained",
|
|
1903
|
+
fullWidth: true,
|
|
1904
|
+
size: "lg",
|
|
1905
|
+
color: "secondary",
|
|
1906
|
+
className: "oui-h-10",
|
|
1907
|
+
onClick: props.close,
|
|
1908
|
+
children: t("common.cancel")
|
|
1909
|
+
}
|
|
1910
|
+
),
|
|
1911
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1912
|
+
ui.Button,
|
|
1913
|
+
{
|
|
1914
|
+
variant: "contained",
|
|
1915
|
+
color: "primary",
|
|
1916
|
+
fullWidth: true,
|
|
1917
|
+
size: "lg",
|
|
1918
|
+
className: "oui-h-10",
|
|
1919
|
+
loading: props.isLoading,
|
|
1920
|
+
disabled: !props.canConfirm,
|
|
1921
|
+
onClick: props.onConfirm,
|
|
1922
|
+
children: t("common.confirm")
|
|
1923
|
+
}
|
|
1924
|
+
)
|
|
1925
|
+
] });
|
|
1926
|
+
};
|
|
1927
|
+
var fotter_default = Footer;
|
|
1928
|
+
var Infos = ({
|
|
1929
|
+
currentMargin,
|
|
1930
|
+
liquidationPrice,
|
|
1931
|
+
effectiveLeverage
|
|
1932
|
+
}) => {
|
|
1933
|
+
const { t } = i18n.useTranslation();
|
|
1934
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1935
|
+
ui.Flex,
|
|
1936
|
+
{
|
|
1937
|
+
direction: "column",
|
|
1938
|
+
gap: 1,
|
|
1939
|
+
className: "oui-w-full oui-rounded-[6px] oui-bg-base-6 oui-p-3 oui-text-2xs oui-font-semibold",
|
|
1940
|
+
children: [
|
|
1941
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1942
|
+
ui.Statistic,
|
|
1943
|
+
{
|
|
1944
|
+
label: t("positions.adjustMargin.currentMargin"),
|
|
1945
|
+
valueProps: { dp: 2, unit: " USDC", padding: false },
|
|
1946
|
+
classNames: {
|
|
1947
|
+
root: "oui-flex-row oui-justify-between oui-items-center oui-w-full oui-text-2xs oui-h-5",
|
|
1948
|
+
label: "oui-text-2xs"
|
|
1949
|
+
},
|
|
1950
|
+
children: currentMargin
|
|
1951
|
+
}
|
|
1952
|
+
),
|
|
1953
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1954
|
+
ui.Statistic,
|
|
1955
|
+
{
|
|
1956
|
+
label: t("positions.adjustMargin.liqPriceAfter"),
|
|
1957
|
+
valueProps: { dp: 2, unit: " USDC", padding: false },
|
|
1958
|
+
classNames: {
|
|
1959
|
+
root: "oui-flex-row oui-justify-between oui-items-center oui-w-full oui-text-2xs oui-h-5",
|
|
1960
|
+
label: "oui-text-2xs"
|
|
1961
|
+
},
|
|
1962
|
+
children: liquidationPrice ?? "--"
|
|
1963
|
+
}
|
|
1964
|
+
),
|
|
1965
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1966
|
+
ui.Statistic,
|
|
1967
|
+
{
|
|
1968
|
+
label: t("positions.adjustMargin.leverageAfter"),
|
|
1969
|
+
valueProps: { dp: 2, unit: " x" },
|
|
1970
|
+
classNames: {
|
|
1971
|
+
root: "oui-flex-row oui-justify-between oui-items-center oui-w-full oui-text-2xs oui-h-5",
|
|
1972
|
+
label: "oui-text-2xs"
|
|
1973
|
+
},
|
|
1974
|
+
children: effectiveLeverage ?? "--"
|
|
1975
|
+
}
|
|
1976
|
+
)
|
|
1977
|
+
]
|
|
1978
|
+
}
|
|
1979
|
+
);
|
|
1980
|
+
};
|
|
1981
|
+
var MarginActions = ({
|
|
1982
|
+
isAdd,
|
|
1983
|
+
onTabChange
|
|
1984
|
+
}) => {
|
|
1985
|
+
const { t } = i18n.useTranslation();
|
|
1986
|
+
const tabBase = "oui-h-7 oui-rounded-[4px] oui-text-xs oui-font-semibold oui-transition-colors";
|
|
1987
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { className: "oui-w-full oui-gap-[6px]", children: [
|
|
1988
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1989
|
+
ui.Button,
|
|
1990
|
+
{
|
|
1991
|
+
size: "md",
|
|
1992
|
+
fullWidth: true,
|
|
1993
|
+
variant: "contained",
|
|
1994
|
+
color: "secondary",
|
|
1995
|
+
className: ui.cn(
|
|
1996
|
+
tabBase,
|
|
1997
|
+
isAdd && "oui-bg-base-5 oui-text-base-contrast-98",
|
|
1998
|
+
!isAdd && "oui-bg-base-7 oui-text-base-contrast-54 hover:oui-text-base-contrast-80"
|
|
1999
|
+
),
|
|
2000
|
+
onClick: () => onTabChange("add"),
|
|
2001
|
+
children: t("positions.adjustMargin.add")
|
|
2002
|
+
}
|
|
2003
|
+
),
|
|
2004
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2005
|
+
ui.Button,
|
|
2006
|
+
{
|
|
2007
|
+
size: "sm",
|
|
2008
|
+
fullWidth: true,
|
|
2009
|
+
variant: "contained",
|
|
2010
|
+
color: "secondary",
|
|
2011
|
+
className: ui.cn(
|
|
2012
|
+
tabBase,
|
|
2013
|
+
!isAdd && "oui-bg-base-5 oui-text-base-contrast-98 hover:oui-text-base-contrast-80",
|
|
2014
|
+
isAdd && "oui-bg-base-7 oui-text-base-contrast-54 hover:oui-text-base-contrast-80"
|
|
2015
|
+
),
|
|
2016
|
+
onClick: () => onTabChange("reduce"),
|
|
2017
|
+
children: t("positions.adjustMargin.reduce")
|
|
2018
|
+
}
|
|
2019
|
+
)
|
|
2020
|
+
] });
|
|
2021
|
+
};
|
|
2022
|
+
var Quantity = ({
|
|
2023
|
+
inputValue,
|
|
2024
|
+
sliderValue,
|
|
2025
|
+
maxAmount,
|
|
2026
|
+
onInputChange,
|
|
2027
|
+
onSliderChange
|
|
2028
|
+
}) => {
|
|
2029
|
+
const { t } = i18n.useTranslation();
|
|
2030
|
+
const percentMarks = React2.useMemo(
|
|
2031
|
+
() => [0, 25, 50, 75, 100].map((m) => ({ value: m, label: `${m}%` })),
|
|
2032
|
+
[]
|
|
2033
|
+
);
|
|
2034
|
+
const isMaxClickable = maxAmount > 0;
|
|
2035
|
+
const handleSetToMax = React2.useCallback(() => {
|
|
2036
|
+
if (!isMaxClickable) return;
|
|
2037
|
+
onSliderChange(100);
|
|
2038
|
+
}, [isMaxClickable, onSliderChange]);
|
|
2039
|
+
const handleKeyDown = React2.useCallback(
|
|
2040
|
+
(e) => {
|
|
2041
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
2042
|
+
e.preventDefault();
|
|
2043
|
+
handleSetToMax();
|
|
2044
|
+
}
|
|
2045
|
+
},
|
|
2046
|
+
[handleSetToMax]
|
|
2047
|
+
);
|
|
2048
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", gap: 3, className: "oui-w-full", children: [
|
|
2049
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2050
|
+
ui.Input,
|
|
2051
|
+
{
|
|
2052
|
+
value: inputValue,
|
|
2053
|
+
onValueChange: onInputChange,
|
|
2054
|
+
type: "text",
|
|
2055
|
+
fullWidth: true,
|
|
2056
|
+
size: "lg",
|
|
2057
|
+
align: "right",
|
|
2058
|
+
prefix: t("positions.adjustMargin.quantity"),
|
|
2059
|
+
suffix: "USDC",
|
|
2060
|
+
formatters: [
|
|
2061
|
+
ui.inputFormatter.numberFormatter,
|
|
2062
|
+
ui.inputFormatter.dpFormatter(2)
|
|
2063
|
+
],
|
|
2064
|
+
disabled: maxAmount === null || maxAmount <= 0,
|
|
2065
|
+
autoComplete: "off",
|
|
2066
|
+
classNames: {
|
|
2067
|
+
// Keep border color stable and remove focus ring (Input has focus-within:outline-primary-light by default)
|
|
2068
|
+
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",
|
|
2069
|
+
// keep value aligned to suffix side and match design emphasis
|
|
2070
|
+
input: "oui-text-sm oui-font-semibold oui-text-base-contrast-98",
|
|
2071
|
+
// override default additional padding so value can sit closer to suffix
|
|
2072
|
+
additional: "oui-px-0",
|
|
2073
|
+
prefix: "oui-pl-3 oui-pr-2 oui-text-sm oui-text-base-contrast-54",
|
|
2074
|
+
suffix: "oui-pl-2 oui-pr-3 oui-text-sm oui-text-base-contrast-54"
|
|
2075
|
+
}
|
|
2076
|
+
}
|
|
2077
|
+
),
|
|
2078
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", gap: 2, className: "oui-w-full", children: [
|
|
2079
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2080
|
+
ui.Slider,
|
|
2081
|
+
{
|
|
2082
|
+
value: [sliderValue],
|
|
2083
|
+
onValueChange: (val) => onSliderChange(val[0]),
|
|
2084
|
+
max: 100,
|
|
2085
|
+
min: 0,
|
|
2086
|
+
step: 1,
|
|
2087
|
+
color: "primary",
|
|
2088
|
+
showTip: true,
|
|
2089
|
+
tipFormatter: (v, _min, _max, percent) => `${percent.toFixed(0)}%`,
|
|
2090
|
+
marks: percentMarks,
|
|
2091
|
+
markLabelVisible: false,
|
|
2092
|
+
disabled: maxAmount === null || maxAmount <= 0
|
|
2093
|
+
}
|
|
2094
|
+
),
|
|
2095
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", className: "oui-w-full", children: [
|
|
2096
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", className: "oui-text-primary", children: `${sliderValue.toFixed(0)}%` }),
|
|
2097
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2098
|
+
ui.Flex,
|
|
2099
|
+
{
|
|
2100
|
+
gap: 1,
|
|
2101
|
+
itemAlign: "baseline",
|
|
2102
|
+
role: isMaxClickable ? "button" : void 0,
|
|
2103
|
+
tabIndex: isMaxClickable ? 0 : void 0,
|
|
2104
|
+
onClick: isMaxClickable ? handleSetToMax : void 0,
|
|
2105
|
+
onKeyDown: isMaxClickable ? handleKeyDown : void 0,
|
|
2106
|
+
className: isMaxClickable ? "oui-cursor-pointer oui-opacity-90 hover:oui-opacity-100" : void 0,
|
|
2107
|
+
children: [
|
|
2108
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", className: "oui-text-primary", children: t("positions.adjustMargin.max") }),
|
|
2109
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { size: "2xs", intensity: 54, dp: 2, children: maxAmount })
|
|
2110
|
+
]
|
|
2111
|
+
}
|
|
2112
|
+
)
|
|
2113
|
+
] })
|
|
2114
|
+
] })
|
|
2115
|
+
] });
|
|
2116
|
+
};
|
|
2117
|
+
var SymbolInfo = ({ symbol }) => {
|
|
2118
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-flex oui-items-center oui-gap-2", children: [
|
|
2119
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.TokenIcon, { symbol, className: "oui-size-5" }),
|
|
2120
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2121
|
+
ui.Text.formatted,
|
|
2122
|
+
{
|
|
2123
|
+
rule: "symbol",
|
|
2124
|
+
formatString: "base-type",
|
|
2125
|
+
size: "base",
|
|
2126
|
+
weight: "semibold",
|
|
2127
|
+
intensity: 98,
|
|
2128
|
+
children: symbol
|
|
2129
|
+
}
|
|
2130
|
+
)
|
|
2131
|
+
] });
|
|
2132
|
+
};
|
|
2133
|
+
var Title = ({ close }) => {
|
|
2134
|
+
const { t } = i18n.useTranslation();
|
|
2135
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-w-full", children: [
|
|
2136
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", itemAlign: "center", children: [
|
|
2137
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2138
|
+
ui.Text,
|
|
2139
|
+
{
|
|
2140
|
+
className: "oui-text-base oui-leading-6 oui-font-semibold oui-tracking-[0.48px]",
|
|
2141
|
+
intensity: 98,
|
|
2142
|
+
children: t("positions.adjustMargin.title")
|
|
2143
|
+
}
|
|
2144
|
+
),
|
|
2145
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { onClick: close, color: "secondary", children: /* @__PURE__ */ jsxRuntime.jsx(ui.CloseIcon, { size: 18, color: "white", opacity: 0.98 }) })
|
|
2146
|
+
] }),
|
|
2147
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { className: "oui-mt-[9px] oui-w-full" })
|
|
2148
|
+
] });
|
|
2149
|
+
};
|
|
2150
|
+
var title_default = Title;
|
|
2151
|
+
var AdjustMargin = (props) => {
|
|
2152
|
+
const {
|
|
2153
|
+
symbol,
|
|
2154
|
+
inputValue,
|
|
2155
|
+
sliderValue,
|
|
2156
|
+
maxAmount,
|
|
2157
|
+
currentMargin,
|
|
2158
|
+
liquidationPrice,
|
|
2159
|
+
effectiveLeverage,
|
|
2160
|
+
onTabChange,
|
|
2161
|
+
onInputChange,
|
|
2162
|
+
onSliderChange,
|
|
2163
|
+
close,
|
|
2164
|
+
isAdd
|
|
2165
|
+
} = props;
|
|
2166
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2167
|
+
ui.Flex,
|
|
2168
|
+
{
|
|
2169
|
+
direction: "column",
|
|
2170
|
+
className: "oui-w-full oui-rounded-[12px] oui-bg-base-8 oui-font-semibold",
|
|
2171
|
+
children: [
|
|
2172
|
+
/* @__PURE__ */ jsxRuntime.jsx(title_default, { close }),
|
|
2173
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-w-full oui-pt-5", children: [
|
|
2174
|
+
/* @__PURE__ */ jsxRuntime.jsx(SymbolInfo, { symbol }),
|
|
2175
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", gap: 4, className: "oui-mt-4 oui-w-full", children: [
|
|
2176
|
+
/* @__PURE__ */ jsxRuntime.jsx(MarginActions, { isAdd, onTabChange }),
|
|
2177
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2178
|
+
Quantity,
|
|
2179
|
+
{
|
|
2180
|
+
inputValue,
|
|
2181
|
+
sliderValue,
|
|
2182
|
+
maxAmount,
|
|
2183
|
+
onInputChange,
|
|
2184
|
+
onSliderChange
|
|
2185
|
+
}
|
|
2186
|
+
),
|
|
2187
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2188
|
+
Infos,
|
|
2189
|
+
{
|
|
2190
|
+
currentMargin,
|
|
2191
|
+
liquidationPrice,
|
|
2192
|
+
effectiveLeverage
|
|
2193
|
+
}
|
|
2194
|
+
)
|
|
2195
|
+
] })
|
|
2196
|
+
] }),
|
|
2197
|
+
/* @__PURE__ */ jsxRuntime.jsx(fotter_default, { ...props })
|
|
2198
|
+
]
|
|
2199
|
+
}
|
|
2200
|
+
);
|
|
2201
|
+
};
|
|
2202
|
+
var AdjustMarginDialogId = "AdjustMarginDialog";
|
|
2203
|
+
var AdjustMarginSheetId = "AdjustMarginSheet";
|
|
2204
|
+
var AdjustMarginWidget = (props) => {
|
|
2205
|
+
const { isMobile } = ui.useScreen();
|
|
2206
|
+
const state = useAdjustMarginScript({
|
|
2207
|
+
position: props.position,
|
|
2208
|
+
symbol: props.symbol,
|
|
2209
|
+
close: () => ui.modal.hide(isMobile ? AdjustMarginSheetId : AdjustMarginDialogId)
|
|
2210
|
+
});
|
|
2211
|
+
return /* @__PURE__ */ jsxRuntime.jsx(AdjustMargin, { ...state });
|
|
2212
|
+
};
|
|
2213
|
+
ui.registerSimpleDialog(AdjustMarginDialogId, AdjustMarginWidget, {
|
|
2214
|
+
title: void 0,
|
|
2215
|
+
closable: false,
|
|
2216
|
+
size: "sm"
|
|
2217
|
+
});
|
|
2218
|
+
ui.registerSimpleSheet(AdjustMarginSheetId, AdjustMarginWidget, {
|
|
2219
|
+
title: void 0,
|
|
2220
|
+
closable: false
|
|
2221
|
+
});
|
|
1607
2222
|
var QuantitySlider = (props) => {
|
|
1608
2223
|
const { t } = i18n.useTranslation();
|
|
1609
2224
|
const [sliderValue, setSliderValue] = React2.useState(props.value);
|
|
@@ -2260,29 +2875,59 @@ var AddIcon = (props) => {
|
|
|
2260
2875
|
);
|
|
2261
2876
|
};
|
|
2262
2877
|
var LeverageBadge = (props) => {
|
|
2263
|
-
const { symbol, leverage } = props;
|
|
2878
|
+
const { symbol, leverage, marginMode } = props;
|
|
2879
|
+
const { t } = i18n.useTranslation();
|
|
2880
|
+
const resolvedMarginMode = marginMode;
|
|
2264
2881
|
const showModal = () => {
|
|
2265
2882
|
ui.modal.show(props.modalId, {
|
|
2266
2883
|
symbol,
|
|
2267
|
-
curLeverage:
|
|
2884
|
+
curLeverage: leverage,
|
|
2885
|
+
marginMode: resolvedMarginMode
|
|
2268
2886
|
});
|
|
2269
2887
|
};
|
|
2270
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2888
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-flex oui-items-center oui-gap-1", children: [
|
|
2889
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2890
|
+
"div",
|
|
2891
|
+
{
|
|
2892
|
+
className: ui.cn(
|
|
2893
|
+
"oui-flex oui-h-[18px] oui-items-center",
|
|
2894
|
+
"oui-rounded oui-bg-line-6 oui-px-2",
|
|
2895
|
+
"oui-text-2xs oui-font-semibold oui-text-base-contrast-36"
|
|
2896
|
+
),
|
|
2897
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: resolvedMarginMode === void 0 ? "--" : resolvedMarginMode === types.MarginMode.ISOLATED ? t("marginMode.isolated") : t("marginMode.cross") })
|
|
2898
|
+
}
|
|
2899
|
+
),
|
|
2900
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2901
|
+
"div",
|
|
2902
|
+
{
|
|
2903
|
+
className: ui.cn(
|
|
2904
|
+
"oui-flex oui-h-[18px] oui-items-center oui-gap-1",
|
|
2905
|
+
"oui-rounded oui-bg-line-6 oui-px-2",
|
|
2906
|
+
"oui-text-2xs oui-font-semibold oui-text-base-contrast-36",
|
|
2907
|
+
"oui-cursor-pointer"
|
|
2908
|
+
),
|
|
2909
|
+
onClick: showModal,
|
|
2910
|
+
children: [
|
|
2911
|
+
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 }),
|
|
2912
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2913
|
+
ui.ChevronRightIcon,
|
|
2914
|
+
{
|
|
2915
|
+
size: 12,
|
|
2916
|
+
className: "oui-text-base-contrast-36",
|
|
2917
|
+
opacity: 1
|
|
2918
|
+
}
|
|
2919
|
+
)
|
|
2920
|
+
]
|
|
2921
|
+
}
|
|
2922
|
+
)
|
|
2923
|
+
] });
|
|
2282
2924
|
};
|
|
2283
|
-
var LeverageDisplay = ({
|
|
2284
|
-
|
|
2285
|
-
|
|
2925
|
+
var LeverageDisplay = ({
|
|
2926
|
+
symbol,
|
|
2927
|
+
marginMode
|
|
2928
|
+
}) => {
|
|
2929
|
+
const leverage = hooks.useLeverageBySymbol(symbol, marginMode);
|
|
2930
|
+
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
2931
|
};
|
|
2287
2932
|
var renderQuantity = (value) => {
|
|
2288
2933
|
const symbolInfo = useSymbolContext();
|
|
@@ -2436,11 +3081,13 @@ var useShareButtonScript = (props) => {
|
|
|
2436
3081
|
const { position, sharePnLConfig, iconSize } = props;
|
|
2437
3082
|
const { getFirstRefCode } = hooks.useReferralInfo();
|
|
2438
3083
|
const symbolsInfo = hooks.useSymbolsInfo();
|
|
2439
|
-
const { data: accountInfo } = hooks.useAccountInfo();
|
|
2440
3084
|
const refCode = React2.useMemo(() => {
|
|
2441
3085
|
return getFirstRefCode()?.code;
|
|
2442
3086
|
}, [getFirstRefCode]);
|
|
2443
|
-
const symbolLeverage = hooks.useLeverageBySymbol(
|
|
3087
|
+
const symbolLeverage = hooks.useLeverageBySymbol(
|
|
3088
|
+
position.symbol,
|
|
3089
|
+
position.margin_mode ?? types.MarginMode.CROSS
|
|
3090
|
+
);
|
|
2444
3091
|
const getHistoryEntity = () => {
|
|
2445
3092
|
const netPnL = position.netPnL || 0;
|
|
2446
3093
|
const openPrice = Math.abs(position.avg_open_price);
|
|
@@ -2449,10 +3096,22 @@ var useShareButtonScript = (props) => {
|
|
|
2449
3096
|
const symbolInfo = symbolsInfo[position.symbol];
|
|
2450
3097
|
const baseIMR = symbolInfo("base_imr");
|
|
2451
3098
|
const IMR_Factor = symbolInfo("imr_factor");
|
|
2452
|
-
if (netPnL !== 0 && quantity !== 0 && openPrice !== 0 &&
|
|
3099
|
+
if (netPnL !== 0 && quantity !== 0 && openPrice !== 0 && baseIMR && // IMR_Factor is possible to be 0
|
|
2453
3100
|
typeof IMR_Factor !== "undefined") {
|
|
2454
3101
|
const notional = perp.positions.notional(quantity, openPrice);
|
|
2455
|
-
const maxLeverage = position.leverage
|
|
3102
|
+
const maxLeverage = position.leverage || symbolLeverage;
|
|
3103
|
+
if (!maxLeverage) {
|
|
3104
|
+
return {
|
|
3105
|
+
side: position.side,
|
|
3106
|
+
pnl: netPnL,
|
|
3107
|
+
roi,
|
|
3108
|
+
openPrice,
|
|
3109
|
+
closePrice: Math.abs(position.avg_close_price),
|
|
3110
|
+
openTime: position.open_timestamp,
|
|
3111
|
+
closeTime: position.close_timestamp,
|
|
3112
|
+
quantity: position.closed_position_qty
|
|
3113
|
+
};
|
|
3114
|
+
}
|
|
2456
3115
|
const imr = perp.account.IMR({
|
|
2457
3116
|
maxLeverage,
|
|
2458
3117
|
baseIMR,
|
|
@@ -2496,7 +3155,8 @@ var useShareButtonScript = (props) => {
|
|
|
2496
3155
|
symbol: position.symbol,
|
|
2497
3156
|
// when position.leverage is empty, use leverage from useSymbolLeverage
|
|
2498
3157
|
leverage: position.leverage || symbolLeverage,
|
|
2499
|
-
...entity
|
|
3158
|
+
...entity,
|
|
3159
|
+
marginMode: position.margin_mode
|
|
2500
3160
|
},
|
|
2501
3161
|
refCode,
|
|
2502
3162
|
...sharePnLConfig
|
|
@@ -2811,7 +3471,7 @@ var useColumn = (config) => {
|
|
|
2811
3471
|
positionReverse
|
|
2812
3472
|
} = config;
|
|
2813
3473
|
const { t } = i18n.useTranslation();
|
|
2814
|
-
|
|
3474
|
+
const { isMobile } = ui.useScreen();
|
|
2815
3475
|
const column = React2.useMemo(
|
|
2816
3476
|
() => [
|
|
2817
3477
|
{
|
|
@@ -2854,7 +3514,8 @@ var useColumn = (config) => {
|
|
|
2854
3514
|
{
|
|
2855
3515
|
symbol: value,
|
|
2856
3516
|
leverage: record.leverage,
|
|
2857
|
-
modalId: uiLeverage.SymbolLeverageDialogId
|
|
3517
|
+
modalId: uiLeverage.SymbolLeverageDialogId,
|
|
3518
|
+
marginMode: record.margin_mode
|
|
2858
3519
|
}
|
|
2859
3520
|
),
|
|
2860
3521
|
/* @__PURE__ */ jsxRuntime.jsx(RwaStatusTag, { symbol: value })
|
|
@@ -3043,17 +3704,13 @@ var useColumn = (config) => {
|
|
|
3043
3704
|
ui.Tooltip,
|
|
3044
3705
|
{
|
|
3045
3706
|
className: "oui-max-w-[280px] oui-bg-base-8 oui-p-3 oui-text-2xs oui-text-base-contrast-54",
|
|
3046
|
-
content: /* @__PURE__ */ jsxRuntime.
|
|
3707
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3047
3708
|
ui.Flex,
|
|
3048
3709
|
{
|
|
3049
3710
|
direction: "column",
|
|
3050
3711
|
gap: 3,
|
|
3051
3712
|
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
|
-
]
|
|
3713
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: t("positions.column.margin.tooltip") })
|
|
3057
3714
|
}
|
|
3058
3715
|
),
|
|
3059
3716
|
children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-underline oui-decoration-dotted", children: t("positions.column.margin") })
|
|
@@ -3063,7 +3720,26 @@ var useColumn = (config) => {
|
|
|
3063
3720
|
onSort: true,
|
|
3064
3721
|
width: 140,
|
|
3065
3722
|
rule: "price",
|
|
3066
|
-
render: (value) =>
|
|
3723
|
+
render: (value, record) => {
|
|
3724
|
+
const isIsolated = record.margin_mode === "ISOLATED";
|
|
3725
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 2, itemAlign: "center", children: [
|
|
3726
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { children: isIsolated ? record.margin ?? "--" : "--" }),
|
|
3727
|
+
isIsolated && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3728
|
+
ui.IconButton,
|
|
3729
|
+
{
|
|
3730
|
+
color: "secondary",
|
|
3731
|
+
onClick: (e) => {
|
|
3732
|
+
e.stopPropagation();
|
|
3733
|
+
ui.modal.show(AdjustMarginDialogId, {
|
|
3734
|
+
position: record,
|
|
3735
|
+
symbol: record.symbol
|
|
3736
|
+
});
|
|
3737
|
+
},
|
|
3738
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ui.AddCircleIcon, { size: 16, fill: "currentColor", opacity: 1 })
|
|
3739
|
+
}
|
|
3740
|
+
)
|
|
3741
|
+
] });
|
|
3742
|
+
}
|
|
3067
3743
|
},
|
|
3068
3744
|
// {
|
|
3069
3745
|
// title: t("funding.fundingFee"),
|
|
@@ -3128,7 +3804,8 @@ var SymbolToken = (props) => {
|
|
|
3128
3804
|
{
|
|
3129
3805
|
symbol: item.symbol,
|
|
3130
3806
|
leverage: item.leverage,
|
|
3131
|
-
modalId: uiLeverage.SymbolLeverageSheetId
|
|
3807
|
+
modalId: uiLeverage.SymbolLeverageSheetId,
|
|
3808
|
+
marginMode: item.margin_mode
|
|
3132
3809
|
}
|
|
3133
3810
|
)
|
|
3134
3811
|
] }),
|
|
@@ -3211,11 +3888,8 @@ var Qty = (props) => {
|
|
|
3211
3888
|
var Margin = (props) => {
|
|
3212
3889
|
const { item } = props;
|
|
3213
3890
|
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
|
-
] });
|
|
3891
|
+
const isIsolated = item.margin_mode === "ISOLATED";
|
|
3892
|
+
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
3893
|
const marginLabel = /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-underline oui-decoration-dotted", children: t("positions.column.margin") });
|
|
3220
3894
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3221
3895
|
ui.Statistic,
|
|
@@ -3232,7 +3906,23 @@ var Margin = (props) => {
|
|
|
3232
3906
|
root: "oui-text-xs",
|
|
3233
3907
|
label: "oui-text-2xs"
|
|
3234
3908
|
},
|
|
3235
|
-
children: /* @__PURE__ */ jsxRuntime.
|
|
3909
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 1, children: [
|
|
3910
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { dp: 2, intensity: 80, children: isIsolated ? item.margin ?? "--" : "--" }),
|
|
3911
|
+
isIsolated && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3912
|
+
ui.IconButton,
|
|
3913
|
+
{
|
|
3914
|
+
color: "secondary",
|
|
3915
|
+
onClick: (e) => {
|
|
3916
|
+
e.stopPropagation();
|
|
3917
|
+
ui.modal.show(AdjustMarginSheetId, {
|
|
3918
|
+
position: item,
|
|
3919
|
+
symbol: item.symbol
|
|
3920
|
+
});
|
|
3921
|
+
},
|
|
3922
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ui.AddCircleIcon, { size: 16, fill: "currentColor", opacity: 1 })
|
|
3923
|
+
}
|
|
3924
|
+
)
|
|
3925
|
+
] })
|
|
3236
3926
|
}
|
|
3237
3927
|
);
|
|
3238
3928
|
};
|
|
@@ -3637,7 +4327,7 @@ var Positions = (props) => {
|
|
|
3637
4327
|
columns,
|
|
3638
4328
|
bordered: true,
|
|
3639
4329
|
dataSource,
|
|
3640
|
-
generatedRowKey: (record) => record.symbol
|
|
4330
|
+
generatedRowKey: (record, index) => `${record.symbol}-${index}`,
|
|
3641
4331
|
renderRowContainer: (record, index, children) => {
|
|
3642
4332
|
return /* @__PURE__ */ jsxRuntime.jsx(SymbolProvider, { symbol: record.symbol, children: /* @__PURE__ */ jsxRuntime.jsx(PositionsRowProvider, { position: record, children }) });
|
|
3643
4333
|
},
|
|
@@ -3709,7 +4399,7 @@ var CombinePositions = (props) => {
|
|
|
3709
4399
|
dataSource,
|
|
3710
4400
|
expanded: true,
|
|
3711
4401
|
getSubRows: (row) => row.children,
|
|
3712
|
-
generatedRowKey: (record) => `${record.account_id}${record.symbol || ""}`,
|
|
4402
|
+
generatedRowKey: (record, index) => `${record.account_id}${record.symbol || ""}-${index}`,
|
|
3713
4403
|
onCell: (column, record) => {
|
|
3714
4404
|
const isGroup = (record.children ?? []).length > 0;
|
|
3715
4405
|
if (isGroup) {
|
|
@@ -3768,14 +4458,14 @@ var usePositionHistoryColumn = (props) => {
|
|
|
3768
4458
|
onSort: (r1, r2) => {
|
|
3769
4459
|
return r1.symbol?.localeCompare(r2.symbol || "");
|
|
3770
4460
|
},
|
|
3771
|
-
render: (value, record) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
4461
|
+
render: (value, record) => /* @__PURE__ */ jsxRuntime.jsx(SymbolInfo2, { record, onSymbolChange })
|
|
3772
4462
|
},
|
|
3773
4463
|
// quantity
|
|
3774
4464
|
{
|
|
3775
4465
|
title: t("positions.history.column.closed&maxClosed"),
|
|
3776
4466
|
dataIndex: "close_maxClose",
|
|
3777
4467
|
width: 200,
|
|
3778
|
-
render: (value, record) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
4468
|
+
render: (value, record) => /* @__PURE__ */ jsxRuntime.jsx(Quantity2, { record })
|
|
3779
4469
|
},
|
|
3780
4470
|
// net pnl
|
|
3781
4471
|
{
|
|
@@ -3883,7 +4573,7 @@ var usePositionHistoryColumn = (props) => {
|
|
|
3883
4573
|
);
|
|
3884
4574
|
return column;
|
|
3885
4575
|
};
|
|
3886
|
-
var
|
|
4576
|
+
var SymbolInfo2 = (props) => {
|
|
3887
4577
|
const { record, onSymbolChange } = props;
|
|
3888
4578
|
const { t } = i18n.useTranslation();
|
|
3889
4579
|
const tags = React2.useMemo(() => {
|
|
@@ -3997,7 +4687,7 @@ var SymbolInfo = (props) => {
|
|
|
3997
4687
|
] })
|
|
3998
4688
|
] });
|
|
3999
4689
|
};
|
|
4000
|
-
var
|
|
4690
|
+
var Quantity2 = (props) => {
|
|
4001
4691
|
const { record } = props;
|
|
4002
4692
|
const { base_dp } = useSymbolContext();
|
|
4003
4693
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -4130,6 +4820,8 @@ var usePositionHistoryScript = (props) => {
|
|
|
4130
4820
|
const netPnL = item.realized_pnl - item.accumulated_funding_fee - item.trading_fee;
|
|
4131
4821
|
return {
|
|
4132
4822
|
...item,
|
|
4823
|
+
// convert margin_mode to MarginMode
|
|
4824
|
+
margin_mode: item.margin_mode === 1 || item.margin_mode === types.MarginMode.ISOLATED ? types.MarginMode.ISOLATED : types.MarginMode.CROSS,
|
|
4133
4825
|
netPnL
|
|
4134
4826
|
};
|
|
4135
4827
|
}
|
|
@@ -4743,7 +5435,7 @@ var PositionHistory = (props) => {
|
|
|
4743
5435
|
columns: column,
|
|
4744
5436
|
bordered: true,
|
|
4745
5437
|
dataSource: props.dataSource,
|
|
4746
|
-
generatedRowKey: (record) => `${record.symbol}_${record.position_id}`,
|
|
5438
|
+
generatedRowKey: (record, index) => `${record.symbol}_${record.position_id}_${index}`,
|
|
4747
5439
|
renderRowContainer: (record, index, children) => /* @__PURE__ */ jsxRuntime.jsx(SymbolProvider, { symbol: record.symbol, children }),
|
|
4748
5440
|
manualPagination: false,
|
|
4749
5441
|
pagination,
|
|
@@ -5536,7 +6228,8 @@ var useCloseAllPositionsScript = (options) => {
|
|
|
5536
6228
|
order_type: types.OrderType.MARKET,
|
|
5537
6229
|
side,
|
|
5538
6230
|
order_quantity: quantity,
|
|
5539
|
-
reduce_only: true
|
|
6231
|
+
reduce_only: true,
|
|
6232
|
+
margin_mode: position.margin_mode
|
|
5540
6233
|
};
|
|
5541
6234
|
}),
|
|
5542
6235
|
[]
|