From 69f3c693b12d8ab9da3a3ad31c5df73e7bdf57b4 Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Tue, 12 Nov 2024 13:09:52 +0100 Subject: [PATCH 01/62] fix: update to competition accounts --- src/chains/neutron/pion-1.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/chains/neutron/pion-1.ts b/src/chains/neutron/pion-1.ts index 1b1ea4ec1..b4e042e27 100644 --- a/src/chains/neutron/pion-1.ts +++ b/src/chains/neutron/pion-1.ts @@ -13,13 +13,13 @@ const Pion1: ChainConfig = { sell: 'factory/neutron1ke0vqqzyymlp5esr8gjwuzh94ysnpvj8er5hm7/UUSDC', }, contracts: { - redBank: 'neutron1f8ag222s4rnytkweym7lfncrxhtee3za5uk54r5n2rjxvsl9slzq36f66d', - incentives: 'neutron12hvgykldx0vxly59ta0ufjz776wxkl9k3r8ugln7xn6zus34a44s2vqw26', - oracle: 'neutron1pev35y62g6vte0s9t67gsf6m8d60x36t7wr0p0ghjl9r3h5mwl0q4h2zwc', - params: 'neutron1q66e3jv2j9r0duzwzt37fwl7h5njhr2kqs0fxmaa58sfqke80a2ss5hrz7', - creditManager: 'neutron13vyqc4efsnc357ze97ppv9h954zjasuj9d0w8es3mk9ea8sg6mvsr3xkjg', - accountNft: 'neutron1hx27cs7jjuvwq4hqgxn4av8agnspy2nwvrrq8e9f80jkeyrwrh8s8x645z', - perps: 'neutron1yu66sjvgg8shfjxkdlxcqh8yg6tmymsgve8lv62q6k4wrs5mt0pq6ard0n', + redBank: 'neutron1vxvqs075q7y9tvpmt60xjmejrfvuw8mcvgqkug67des96y7psalqrl4cn6', + incentives: 'neutron10a4rt7utgqrpf24jeluc2gt42r83f0ammxnmntq687ycwh7ugysqnfwduy', + oracle: 'neutron13a7vspwpf3vnjq292xsvk8l8y0r7uwn4vtaev04zyl7r0wu8slzsveq09g', + params: 'neutron13pwuvh2kwlvs9q4cm9yfm5xymghle066hq40m2yagg6sh7c09ncqzey946', + creditManager: 'neutron13jm8hk5znqk5t5mlvgphvfea300kayqhhy8hdhmrdtsfypkl7ehqke4d2m', + accountNft: 'neutron1l9vthzck3t7z2ys943jwaxskkjaws3qexhyuhsytqpx8t9ht6lyq4tre4d', + perps: 'neutron1ey5vc5yvlauea7aryuvuxphxvr473ayjxw7h30eq62s4uzcjsx4qsvnfxs', pyth: 'neutron15ldst8t80982akgr8w8ekcytejzkmfpgdkeq4xgtge48qs7435jqp87u3t', }, endpoints: { From 19c5f52c9272d02cca7af32af874dcbdaeffb225 Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Tue, 12 Nov 2024 13:45:19 +0100 Subject: [PATCH 02/62] fix: expand try catch of chart store --- src/components/trade/TradeChart/index.tsx | 46 +++++++++++------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/components/trade/TradeChart/index.tsx b/src/components/trade/TradeChart/index.tsx index 158cc9ad5..afa874ee7 100644 --- a/src/components/trade/TradeChart/index.tsx +++ b/src/components/trade/TradeChart/index.tsx @@ -129,36 +129,36 @@ export default function TradeChart(props: Props) { }, [props.buyAsset.decimals, props.isPerps, props.liquidationPrice, props.perpsPosition]) const intitalChartLoad = useCallback(() => { - const chart = chartWidget.activeChart() - if (!chart) return - const chartStore = JSON.parse(localStorage.getItem(LocalStorageKeys.TV_CHART_STORE) ?? '{}') - const currentChartStore = chartStore[chartName] - if (!currentChartStore) return - currentChartStore.forEach((shape: TradingViewShape) => { - try { + try { + const chart = chartWidget.activeChart() + if (!chart) return + const chartStore = JSON.parse(localStorage.getItem(LocalStorageKeys.TV_CHART_STORE) ?? '{}') + const currentChartStore = chartStore[chartName] + if (!currentChartStore) return + currentChartStore.forEach((shape: TradingViewShape) => { if (Array.isArray(shape.points)) { if (shape.points.length === 0) return chart.createMultipointShape(shape.points, shape.shape) } else { chart.createShape(shape.points, shape.shape) } - } catch (e) { - const shapeName = shape.shape - console.info(`Failed to draw '${shape.shape}', reason:`, e) - } - }) - if (!isPerps || !onCreateLimitOrder) return - chartWidget.onContextMenu((unixTime, price) => { - return [ - { - position: 'top', - text: 'Set Limit Order Price', - click: () => { - onCreateLimitOrder(price) + }) + if (!isPerps || !onCreateLimitOrder) return + chartWidget.onContextMenu((unixTime, price) => { + return [ + { + position: 'top', + text: 'Set Limit Order Price', + click: () => { + onCreateLimitOrder(price) + }, }, - }, - ] - }) + ] + }) + } catch (e) { + console.info('Error on loading chart', e) + return + } }, [chartName, onCreateLimitOrder, isPerps]) const updateShapes = useCallback(() => { From 0854c275389be2e0595787c6b21c136d529b6d66 Mon Sep 17 00:00:00 2001 From: Monkmansteve Date: Wed, 13 Nov 2024 02:36:42 +0200 Subject: [PATCH 03/62] feature: add custom status for positions, make stop order/limit order distinction and remove SL/TP --- .../BalancesTable/Columns/EntryPrice.tsx | 57 ++++++++++++++----- .../Columns/{Type.tsx => Status.tsx} | 18 +++--- .../BalancesTable/Columns/TradeDirection.tsx | 2 +- .../Columns/usePerpsBalancesColumns.tsx | 8 ++- src/components/perps/BalancesTable/index.tsx | 4 +- .../BalancesTable/usePerpsBalancesData.ts | 8 ++- src/components/perps/Module/Summary.tsx | 4 +- src/types/app.d.ts | 2 +- src/utils/perps.ts | 15 ++++- 9 files changed, 84 insertions(+), 34 deletions(-) rename src/components/perps/BalancesTable/Columns/{Type.tsx => Status.tsx} (64%) diff --git a/src/components/perps/BalancesTable/Columns/EntryPrice.tsx b/src/components/perps/BalancesTable/Columns/EntryPrice.tsx index 20d7b233e..5e963438d 100644 --- a/src/components/perps/BalancesTable/Columns/EntryPrice.tsx +++ b/src/components/perps/BalancesTable/Columns/EntryPrice.tsx @@ -10,13 +10,13 @@ export const ENTRY_PRICE_META = (isOrderTable: boolean) => { accessorKey: 'entryPrice', header: () => (
- {isOrderTable ? 'Limit Price' : 'Entry Price'} + {isOrderTable ? 'Trigger Condition' : 'Entry Price'} Current Price
), - meta: { className: 'min-w-40 w-40' }, + meta: { className: 'min-w-48 w-48' }, } } @@ -24,28 +24,57 @@ type Props = { entryPrice: BigNumber currentPrice: BigNumber asset: Asset + type: string + tradeDirection: 'long' | 'short' } export default function EntryPrice(props: Props) { const entryPrice = props.entryPrice.shiftedBy(props.asset.decimals - PRICE_ORACLE_DECIMALS) - const currentPrice = props.currentPrice.shiftedBy(props.asset.decimals - PRICE_ORACLE_DECIMALS) + const getTriggerCondition = () => { + const priceDisplay = ( + + ) + + if (props.type === 'limit') { + return ( +
+
+ {props.tradeDirection === 'long' ? '<=' : '>='} + {priceDisplay} +
+
+ ) + } + + if (props.type === 'stop') { + return ( +
+
+ {props.tradeDirection === 'long' ? '>=' : '<='} + {priceDisplay} +
+
+ ) + } + + return null + } + return ( - } + title={getTriggerCondition()} sub={ +
- {type} + {displayStatus} - {showIndicators && (hasStopLoss || hasTakeProfit) && ( + {/* {showIndicators && (hasStopLoss || hasTakeProfit) && (
{hasStopLoss && ( SL @@ -29,7 +31,7 @@ export function Type({ type, hasStopLoss, hasTakeProfit, showIndicators }: Props TP )}
- )} + )} */}
) } diff --git a/src/components/perps/BalancesTable/Columns/TradeDirection.tsx b/src/components/perps/BalancesTable/Columns/TradeDirection.tsx index 84f08ec46..ef9a39e1d 100644 --- a/src/components/perps/BalancesTable/Columns/TradeDirection.tsx +++ b/src/components/perps/BalancesTable/Columns/TradeDirection.tsx @@ -18,7 +18,7 @@ type Props = { export default function TradeDirection(props: Props) { const { tradeDirection, className, previousTradeDirection } = props return ( -
+
{previousTradeDirection && ( <> ), }, @@ -98,7 +100,7 @@ export default function usePerpsBalancesColumns(props: Props) { const typeColumn = useMemo>( () => ({ - ...TYPE_META, + ...STATUS_META, cell: ({ row }) => { const position = row.original const { hasStopLoss, hasTakeProfit } = checkStopLossAndTakeProfit( @@ -106,7 +108,7 @@ export default function usePerpsBalancesColumns(props: Props) { activeLimitOrders, ) return ( - 0 ? activeLimitOrders.length : undefined, renderContent: () => ( action.toString().includes('execute_perp_order'), ) as ExceutePerpsOrder | undefined + const limitOrderCondition = limitOrder.order.conditions.find((condition) => condition.toString().includes('oracle_price'), ) as TriggerCondition | undefined @@ -73,7 +75,9 @@ export default function usePerpsBalancesTable() { const asset = perpAssets.find(byDenom(perpOrder.denom))! const amount = BN(perpOrder.order_size) const liquidationPrice = computeLiquidationPrice(perpOrder.denom, 'asset') + if (!asset) return + activeLimitOrders.push({ orderId: limitOrder.order.order_id, asset, @@ -81,7 +85,7 @@ export default function usePerpsBalancesTable() { baseDenom: perpsConfig.base_denom, tradeDirection: BN(perpOrder.order_size).isGreaterThanOrEqualTo(0) ? 'long' : 'short', amount: amount.abs(), - type: 'limit', + type: isStopOrder(perpOrder, perpTrigger), pnl: { net: BNCoin.fromCoin(limitOrder.order.keeper_fee).negated(), realized: { diff --git a/src/components/perps/Module/Summary.tsx b/src/components/perps/Module/Summary.tsx index 15d5fd5cf..f1871149c 100644 --- a/src/components/perps/Module/Summary.tsx +++ b/src/components/perps/Module/Summary.tsx @@ -151,9 +151,9 @@ export default function PerpsSummary(props: Props) { let comparison: 'less_than' | 'greater_than' if (tradeDirection === 'long') { - comparison = 'greater_than' - } else { comparison = 'less_than' + } else { + comparison = 'greater_than' } await submitLimitOrder({ diff --git a/src/types/app.d.ts b/src/types/app.d.ts index 8caa45ee2..11fcbfd02 100644 --- a/src/types/app.d.ts +++ b/src/types/app.d.ts @@ -21,7 +21,7 @@ type ActionCoin = import('types/generated/mars-credit-manager/MarsCreditManager. type Action = import('types/generated/mars-credit-manager/MarsCreditManager.types').Action type BNCoin = import('types/classes/BNCoin').BNCoin -type PositionType = 'deposit' | 'borrow' | 'lend' | 'vault' | 'perp' | 'market' | 'limit' +type PositionType = 'deposit' | 'borrow' | 'lend' | 'vault' | 'perp' | 'market' | 'limit' | 'stop' type TableType = 'balances' | 'strategies' | 'perps' type AccountKind = import('types/generated/mars-credit-manager/MarsCreditManager.types').AccountKind diff --git a/src/utils/perps.ts b/src/utils/perps.ts index 29f3f528b..15044d331 100644 --- a/src/utils/perps.ts +++ b/src/utils/perps.ts @@ -32,6 +32,19 @@ export const checkStopLossAndTakeProfit = ( return { hasStopLoss, hasTakeProfit } } +export const isStopOrder = (perpOrder: any, perpTrigger: any): PositionType => { + const isLong = BN(perpOrder.order_size).isGreaterThanOrEqualTo(0) + + if (isLong) { + return perpTrigger.comparison !== 'less_than' + ? ('stop' as PositionType) + : ('limit' as PositionType) + } + return perpTrigger.comparison !== 'greater_than' + ? ('stop' as PositionType) + : ('limit' as PositionType) +} + export const convertTriggerOrderResponseToPerpPosition = ( limitOrder: TriggerOrderResponse, perpAssets: Asset[], @@ -61,7 +74,7 @@ export const convertTriggerOrderResponseToPerpPosition = ( baseDenom: perpsConfig.base_denom, tradeDirection, amount: amount.abs(), - type: 'limit' as PositionType, + type: isStopOrder(perpOrder, perpTrigger), pnl: { net: BNCoin.fromCoin(limitOrder.order.keeper_fee).negated(), realized: { From 57f5558faa47ab02ad8b32b41bafef0d2ef581b1 Mon Sep 17 00:00:00 2001 From: Monkmansteve Date: Wed, 13 Nov 2024 09:21:32 +0200 Subject: [PATCH 04/62] feature: fix action on stops and reduce only on limits --- .../perps/BalancesTable/Columns/Manage.tsx | 2 +- src/components/perps/Module/PerpsModule.tsx | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/components/perps/BalancesTable/Columns/Manage.tsx b/src/components/perps/BalancesTable/Columns/Manage.tsx index 02936f307..0e4f8afcb 100644 --- a/src/components/perps/BalancesTable/Columns/Manage.tsx +++ b/src/components/perps/BalancesTable/Columns/Manage.tsx @@ -212,7 +212,7 @@ export default function Manage(props: Props) { ], ) - if (props.perpPosition.type === 'limit') + if (props.perpPosition.type === 'limit' || props.perpPosition.type === 'stop') return (
{ + if (!currentPerpPosition || !isStopOrder) { + return + } + + const isOppositeDirection = + (currentPerpPosition.tradeDirection === 'long' && stopTradeDirection === 'short') || + (currentPerpPosition.tradeDirection === 'short' && stopTradeDirection === 'long') + console.log('isOppositeDirection', isOppositeDirection) + if (isOppositeDirection) { + setIsReduceOnly(true) + } + }, [currentPerpPosition, isStopOrder, stopTradeDirection]) + useEffect(() => { validateReduceOnlyOrder() }, [validateReduceOnlyOrder, amount, isReduceOnly]) From a394e3ff09e8b5e461464b88320d26bda5319871 Mon Sep 17 00:00:00 2001 From: Monkmansteve Date: Wed, 13 Nov 2024 09:23:30 +0200 Subject: [PATCH 05/62] refactor: log --- src/components/perps/Module/PerpsModule.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/perps/Module/PerpsModule.tsx b/src/components/perps/Module/PerpsModule.tsx index 4d78455da..53b87c458 100644 --- a/src/components/perps/Module/PerpsModule.tsx +++ b/src/components/perps/Module/PerpsModule.tsx @@ -142,7 +142,7 @@ export function PerpsModule() { const isOppositeDirection = (currentPerpPosition.tradeDirection === 'long' && stopTradeDirection === 'short') || (currentPerpPosition.tradeDirection === 'short' && stopTradeDirection === 'long') - console.log('isOppositeDirection', isOppositeDirection) + if (isOppositeDirection) { setIsReduceOnly(true) } From 35c3f274b04686fe12633f6b04f3c0e59451f69f Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Wed, 13 Nov 2024 10:14:40 +0100 Subject: [PATCH 06/62] change wording for stop orders in the chart --- src/components/trade/TradeChart/index.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/trade/TradeChart/index.tsx b/src/components/trade/TradeChart/index.tsx index afa874ee7..b068362d6 100644 --- a/src/components/trade/TradeChart/index.tsx +++ b/src/components/trade/TradeChart/index.tsx @@ -52,8 +52,8 @@ function getLimitOrderText( currentPosition: 'long' | 'short' | null, positionAmount: BigNumber | null, ) { - let label = 'Limit' - + let label = order.type === 'stop' ? 'Stop' : 'Limit' + console.log(order) if (positionAmount && order.amount.abs().isEqualTo(positionAmount.abs())) { const isClosing = (currentPosition === 'long' && order.tradeDirection === 'short') || @@ -78,6 +78,7 @@ function isAutomaticAddedLine(shapeName: string, shape: any) { return ( shape.text.includes('Limit') || + shape.text.includes('Stop') || shape.text.includes('Entry') || shape.text.includes('Liquidation') || shape.text.includes('Close') From 9371d279947a8c5501340252a142b37550e09d39 Mon Sep 17 00:00:00 2001 From: Monkmansteve Date: Wed, 13 Nov 2024 11:19:03 +0200 Subject: [PATCH 07/62] feature: remove arrow in limit orders if no position is open, cap leverage slider --- src/components/perps/Module/PerpsModule.tsx | 6 +++--- src/components/perps/Module/Summary.tsx | 22 ++++++++++++++++----- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/components/perps/Module/PerpsModule.tsx b/src/components/perps/Module/PerpsModule.tsx index 53b87c458..d8a0a1b3c 100644 --- a/src/components/perps/Module/PerpsModule.tsx +++ b/src/components/perps/Module/PerpsModule.tsx @@ -371,10 +371,10 @@ export function PerpsModule() { const effectiveLeverage = useMemo(() => { if (amount.isGreaterThan(maxAmount)) { - return 0 + return maxLeverage } return Math.max(leverage, 0) - }, [amount, maxAmount, leverage]) + }, [amount, maxAmount, leverage, maxLeverage]) const isAmountExceedingMax = useMemo(() => { return amount.isGreaterThan(maxAmount) @@ -478,7 +478,7 @@ export function PerpsModule() { value={effectiveLeverage} onChange={onChangeLeverage} type={tradeDirection} - disabled={isDisabledAmountInput || amount.isGreaterThan(maxAmount)} + disabled={isDisabledAmountInput} /> {maxLeverage > 5 && ( - {previousLeverage && !previousAmount.isZero() && ( - <> + {previousLeverage && !previousAmount.isZero() ? ( +
{formatLeverage(previousLeverage)}
previousLeverage ? 'text-error' : 'text-success')} + className={classNames( + leverage > previousLeverage ? 'text-error' : 'text-success', + 'transition-colors duration-200', + )} />
- + previousLeverage ? 'text-error' : 'text-success', + 'transition-colors duration-200', + )} + > + {formatLeverage(leverage)} + +
+ ) : ( + {formatLeverage(leverage)} )} - {formatLeverage(leverage)}
) From 567d74f418aa20edeb01bfa2c52b19955ab0e6d9 Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Tue, 12 Nov 2024 13:09:52 +0100 Subject: [PATCH 08/62] fix: update to competition accounts --- src/chains/neutron/pion-1.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/chains/neutron/pion-1.ts b/src/chains/neutron/pion-1.ts index 1b1ea4ec1..b4e042e27 100644 --- a/src/chains/neutron/pion-1.ts +++ b/src/chains/neutron/pion-1.ts @@ -13,13 +13,13 @@ const Pion1: ChainConfig = { sell: 'factory/neutron1ke0vqqzyymlp5esr8gjwuzh94ysnpvj8er5hm7/UUSDC', }, contracts: { - redBank: 'neutron1f8ag222s4rnytkweym7lfncrxhtee3za5uk54r5n2rjxvsl9slzq36f66d', - incentives: 'neutron12hvgykldx0vxly59ta0ufjz776wxkl9k3r8ugln7xn6zus34a44s2vqw26', - oracle: 'neutron1pev35y62g6vte0s9t67gsf6m8d60x36t7wr0p0ghjl9r3h5mwl0q4h2zwc', - params: 'neutron1q66e3jv2j9r0duzwzt37fwl7h5njhr2kqs0fxmaa58sfqke80a2ss5hrz7', - creditManager: 'neutron13vyqc4efsnc357ze97ppv9h954zjasuj9d0w8es3mk9ea8sg6mvsr3xkjg', - accountNft: 'neutron1hx27cs7jjuvwq4hqgxn4av8agnspy2nwvrrq8e9f80jkeyrwrh8s8x645z', - perps: 'neutron1yu66sjvgg8shfjxkdlxcqh8yg6tmymsgve8lv62q6k4wrs5mt0pq6ard0n', + redBank: 'neutron1vxvqs075q7y9tvpmt60xjmejrfvuw8mcvgqkug67des96y7psalqrl4cn6', + incentives: 'neutron10a4rt7utgqrpf24jeluc2gt42r83f0ammxnmntq687ycwh7ugysqnfwduy', + oracle: 'neutron13a7vspwpf3vnjq292xsvk8l8y0r7uwn4vtaev04zyl7r0wu8slzsveq09g', + params: 'neutron13pwuvh2kwlvs9q4cm9yfm5xymghle066hq40m2yagg6sh7c09ncqzey946', + creditManager: 'neutron13jm8hk5znqk5t5mlvgphvfea300kayqhhy8hdhmrdtsfypkl7ehqke4d2m', + accountNft: 'neutron1l9vthzck3t7z2ys943jwaxskkjaws3qexhyuhsytqpx8t9ht6lyq4tre4d', + perps: 'neutron1ey5vc5yvlauea7aryuvuxphxvr473ayjxw7h30eq62s4uzcjsx4qsvnfxs', pyth: 'neutron15ldst8t80982akgr8w8ekcytejzkmfpgdkeq4xgtge48qs7435jqp87u3t', }, endpoints: { From 9ebc4a417abab15b23d07b195678a1ff33c8eb14 Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Wed, 13 Nov 2024 11:05:07 +0100 Subject: [PATCH 09/62] fix: text size --- src/components/perps/BalancesTable/Columns/Status.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/perps/BalancesTable/Columns/Status.tsx b/src/components/perps/BalancesTable/Columns/Status.tsx index 7ebfd017d..3285a47aa 100644 --- a/src/components/perps/BalancesTable/Columns/Status.tsx +++ b/src/components/perps/BalancesTable/Columns/Status.tsx @@ -19,7 +19,7 @@ export function Status({ type, hasStopLoss, hasTakeProfit, showIndicators }: Pro return (
- + {displayStatus} {/* {showIndicators && (hasStopLoss || hasTakeProfit) && ( From 9c13154a398d54d3a00418ed6ef3ac0e907fa9e5 Mon Sep 17 00:00:00 2001 From: Monkmansteve Date: Wed, 13 Nov 2024 15:49:57 +0200 Subject: [PATCH 10/62] feature: ui-changes --- .../BalancesTable/Columns/EntryPrice.tsx | 8 +- .../BalancesTable/Columns/TradeDirection.tsx | 137 ++++++++++++------ .../Columns/usePerpsBalancesColumns.tsx | 27 +++- src/components/perps/BalancesTable/index.tsx | 1 + .../BalancesTable/usePerpsBalancesData.ts | 69 +-------- src/components/perps/Module/PerpsModule.tsx | 25 +--- src/hooks/perps/usePerpsLimitOrdersRows.ts | 1 - src/hooks/perps/useSubmitLimitOrder.ts | 2 +- src/types/app.d.ts | 2 + src/utils/perps.ts | 1 + 10 files changed, 135 insertions(+), 138 deletions(-) diff --git a/src/components/perps/BalancesTable/Columns/EntryPrice.tsx b/src/components/perps/BalancesTable/Columns/EntryPrice.tsx index 5e963438d..958fb8282 100644 --- a/src/components/perps/BalancesTable/Columns/EntryPrice.tsx +++ b/src/components/perps/BalancesTable/Columns/EntryPrice.tsx @@ -32,7 +32,7 @@ export default function EntryPrice(props: Props) { const entryPrice = props.entryPrice.shiftedBy(props.asset.decimals - PRICE_ORACLE_DECIMALS) const currentPrice = props.currentPrice.shiftedBy(props.asset.decimals - PRICE_ORACLE_DECIMALS) - const getTriggerCondition = () => { + const getDisplayValue = () => { const priceDisplay = ( ) + if (props.type === 'market') { + return
{priceDisplay}
+ } + if (props.type === 'limit') { return (
@@ -71,7 +75,7 @@ export default function EntryPrice(props: Props) { return ( - {previousTradeDirection && ( - <> - - {previousTradeDirection} - - -
- -
- - )} - +
+ {previousTradeDirection && ( + <> + + {previousTradeDirection} + +
+ +
+ )} - > - {tradeDirection} - + + {tradeDirection} + +
+ {positionEffect && ( + + {positionEffect} + + )}
) } diff --git a/src/components/perps/BalancesTable/Columns/usePerpsBalancesColumns.tsx b/src/components/perps/BalancesTable/Columns/usePerpsBalancesColumns.tsx index 3b1f14279..7b47694bc 100644 --- a/src/components/perps/BalancesTable/Columns/usePerpsBalancesColumns.tsx +++ b/src/components/perps/BalancesTable/Columns/usePerpsBalancesColumns.tsx @@ -8,13 +8,13 @@ import { PERP_NAME_META, PerpName } from 'components/perps/BalancesTable/Columns import PnL, { PNL_META } from 'components/perps/BalancesTable/Columns/PnL' import Size, { SIZE_META, sizeSortingFn } from 'components/perps/BalancesTable/Columns/Size' import TradeDirection, { - PERP_TYPE_META, + TRADE_DIRECTION_META, } from 'components/perps/BalancesTable/Columns/TradeDirection' -import { Status, STATUS_META } from 'components/perps/BalancesTable/Columns/Status' import { PRICE_ORACLE_DECIMALS } from 'constants/query' -import usePerpsLimitOrderRows from 'hooks/perps/usePerpsLimitOrdersRows' import { demagnify } from 'utils/formatters' import { BN } from 'utils/helpers' +import { Status, STATUS_META } from 'components/perps/BalancesTable/Columns/Status' +import usePerpsLimitOrderRows from 'hooks/perps/usePerpsLimitOrdersRows' import { checkStopLossAndTakeProfit } from 'utils/perps' interface Props { @@ -32,23 +32,35 @@ export default function usePerpsBalancesColumns(props: Props) { cell: ({ row }) => , }, { - ...PERP_TYPE_META, - cell: ({ row }) => , + ...TRADE_DIRECTION_META, + id: 'direction', + cell: ({ row }) => { + const { type, tradeDirection, reduce_only, amount, denom } = row.original + return ( + + ) + }, }, { ...SIZE_META, + id: 'entryPrice', cell: ({ row }) => { const { asset, amount, type, entryPrice } = row.original const demagnifiedAmount = BN(demagnify(amount, asset)) let value if (type === 'limit') { - // For limit orders, calculate adjusted value value = demagnifiedAmount .times(entryPrice) .shiftedBy(asset.decimals - PRICE_ORACLE_DECIMALS) } else { - // For market orders/positions, use value directly value = demagnifiedAmount.times(BN(asset.price?.amount || 0)) } @@ -56,7 +68,6 @@ export default function usePerpsBalancesColumns(props: Props) { }, sortingFn: sizeSortingFn, }, - ...(isOrderTable ? [] : [ diff --git a/src/components/perps/BalancesTable/index.tsx b/src/components/perps/BalancesTable/index.tsx index 1603495cd..f5e7cfc73 100644 --- a/src/components/perps/BalancesTable/index.tsx +++ b/src/components/perps/BalancesTable/index.tsx @@ -14,6 +14,7 @@ export default function PerpsBalancesTable() { const activeLimitOrders = usePerpsLimitOrderRows() const columns = usePerpsBalancesColumns({ isOrderTable: false }) const limitOrderColumns = usePerpsBalancesColumns({ isOrderTable: true }) + const [searchParams, setSearchParams] = useSearchParams() const onClickRow = useCallback( diff --git a/src/components/perps/BalancesTable/usePerpsBalancesData.ts b/src/components/perps/BalancesTable/usePerpsBalancesData.ts index 47bc79094..ed45c0a74 100644 --- a/src/components/perps/BalancesTable/usePerpsBalancesData.ts +++ b/src/components/perps/BalancesTable/usePerpsBalancesData.ts @@ -1,27 +1,22 @@ import { useMemo } from 'react' -import { BN_ONE, BN_ZERO } from 'constants/math' +import { BN_ZERO } from 'constants/math' import useCurrentAccount from 'hooks/accounts/useCurrentAccount' import useDepositEnabledAssets from 'hooks/assets/useDepositEnabledAssets' import usePerpsEnabledAssets from 'hooks/assets/usePerpsEnabledAssets' import usePerpsConfig from 'hooks/perps/usePerpsConfig' -import usePerpsLimitOrders from 'hooks/perps/usePerpsLimitOrders' -import { BNCoin } from 'types/classes/BNCoin' import { getAccountNetValue } from 'utils/accounts' import { byDenom } from 'utils/array' import { demagnify } from 'utils/formatters' import { BN } from 'utils/helpers' import { PRICE_ORACLE_DECIMALS } from 'constants/query' import useHealthComputer from 'hooks/health-computer/useHealthComputer' -import { isStopOrder } from 'utils/perps' export default function usePerpsBalancesTable() { const currentAccount = useCurrentAccount() const perpAssets = usePerpsEnabledAssets() - const { data: limitOrders } = usePerpsLimitOrders() const { data: perpsConfig } = usePerpsConfig() - const allAssets = useDepositEnabledAssets() const { computeLiquidationPrice } = useHealthComputer(currentAccount) @@ -30,7 +25,7 @@ export default function usePerpsBalancesTable() { const netValue = getAccountNetValue(currentAccount, allAssets) - const activePerpsPositions = currentAccount.perps.map((position) => { + return currentAccount.perps.map((position) => { const asset = perpAssets.find(byDenom(position.denom))! const liquidationPrice = computeLiquidationPrice(position.denom, 'perp') @@ -41,6 +36,7 @@ export default function usePerpsBalancesTable() { denom: position.denom, baseDenom: position.baseDenom, type: 'market', + reduce_only: position.reduce_only, pnl: position.pnl, entryPrice: position.entryPrice, currentPrice: position.currentPrice, @@ -52,62 +48,5 @@ export default function usePerpsBalancesTable() { .toNumber(), } as PerpPositionRow }) - - if (!limitOrders) return activePerpsPositions - - if (!perpsConfig?.base_denom) return activePerpsPositions - const zeroCoin = BNCoin.fromDenomAndBigNumber(perpsConfig.base_denom, BN_ZERO) - const activeLimitOrders: PerpPositionRow[] = [] - limitOrders - .filter((order) => order['account_id'] === currentAccount.id) - .forEach((limitOrder) => { - const limitOrderAction = limitOrder.order.actions.find((action) => - action.toString().includes('execute_perp_order'), - ) as ExceutePerpsOrder | undefined - - const limitOrderCondition = limitOrder.order.conditions.find((condition) => - condition.toString().includes('oracle_price'), - ) as TriggerCondition | undefined - - if (!limitOrderAction || !limitOrderCondition) return - const perpOrder = limitOrderAction.execute_perp_order - const perpTrigger = limitOrderCondition.oracle_price - const asset = perpAssets.find(byDenom(perpOrder.denom))! - const amount = BN(perpOrder.order_size) - const liquidationPrice = computeLiquidationPrice(perpOrder.denom, 'asset') - - if (!asset) return - - activeLimitOrders.push({ - orderId: limitOrder.order.order_id, - asset, - denom: perpOrder.denom, - baseDenom: perpsConfig.base_denom, - tradeDirection: BN(perpOrder.order_size).isGreaterThanOrEqualTo(0) ? 'long' : 'short', - amount: amount.abs(), - type: isStopOrder(perpOrder, perpTrigger), - pnl: { - net: BNCoin.fromCoin(limitOrder.order.keeper_fee).negated(), - realized: { - fees: zeroCoin, - funding: zeroCoin, - net: zeroCoin, - price: zeroCoin, - }, - unrealized: { - fees: zeroCoin, - funding: zeroCoin, - net: zeroCoin, - price: zeroCoin, - }, - }, - entryPrice: BN(perpTrigger.price), - currentPrice: asset.price?.amount ?? BN_ZERO, - liquidationPrice: BN(liquidationPrice ?? '0'), - leverage: 1, - }) - }) - - return [...activePerpsPositions, ...activeLimitOrders] - }, [currentAccount, perpsConfig, allAssets, limitOrders, perpAssets, computeLiquidationPrice]) + }, [currentAccount, perpsConfig, allAssets, perpAssets, computeLiquidationPrice]) } diff --git a/src/components/perps/Module/PerpsModule.tsx b/src/components/perps/Module/PerpsModule.tsx index d8a0a1b3c..ac78cc618 100644 --- a/src/components/perps/Module/PerpsModule.tsx +++ b/src/components/perps/Module/PerpsModule.tsx @@ -134,20 +134,6 @@ export function PerpsModule() { return true }, [isReduceOnly, currentPerpPosition, amount]) - useEffect(() => { - if (!currentPerpPosition || !isStopOrder) { - return - } - - const isOppositeDirection = - (currentPerpPosition.tradeDirection === 'long' && stopTradeDirection === 'short') || - (currentPerpPosition.tradeDirection === 'short' && stopTradeDirection === 'long') - - if (isOppositeDirection) { - setIsReduceOnly(true) - } - }, [currentPerpPosition, isStopOrder, stopTradeDirection]) - useEffect(() => { validateReduceOnlyOrder() }, [validateReduceOnlyOrder, amount, isReduceOnly]) @@ -316,15 +302,14 @@ export function PerpsModule() { amount.isZero() || amount.isGreaterThan(maxAmount) || warningMessages.isNotEmpty() if (isStopOrder) { - if (!currentPerpPosition || stopPrice.isZero()) return true + if (stopPrice.isZero()) return true const currentPrice = perpsAsset?.price?.amount ?? BN_ZERO if (currentPrice.isZero()) return true - if (currentPerpPosition.tradeDirection === 'long') { - return stopPrice.isGreaterThanOrEqualTo(currentPrice) + if (stopTradeDirection === 'long') { + return stopPrice.isLessThanOrEqualTo(currentPrice) } - - return stopPrice.isLessThanOrEqualTo(currentPrice) + return stopPrice.isGreaterThanOrEqualTo(currentPrice) } if (isLimitOrder) { @@ -337,8 +322,8 @@ export function PerpsModule() { maxAmount, warningMessages, isStopOrder, - currentPerpPosition, stopPrice, + stopTradeDirection, perpsAsset?.price?.amount, isLimitOrder, limitPriceInfo, diff --git a/src/hooks/perps/usePerpsLimitOrdersRows.ts b/src/hooks/perps/usePerpsLimitOrdersRows.ts index 8628050e5..6c6b7e879 100644 --- a/src/hooks/perps/usePerpsLimitOrdersRows.ts +++ b/src/hooks/perps/usePerpsLimitOrdersRows.ts @@ -11,7 +11,6 @@ export default function usePerpsLimitOrderRows() { const perpAssets = usePerpsEnabledAssets() const { data: limitOrders } = usePerpsLimitOrders() const { data: perpsConfig } = usePerpsConfig() - const { computeLiquidationPrice } = useHealthComputer(currentAccount) return useMemo(() => { diff --git a/src/hooks/perps/useSubmitLimitOrder.ts b/src/hooks/perps/useSubmitLimitOrder.ts index bec5b14be..b2795b3de 100644 --- a/src/hooks/perps/useSubmitLimitOrder.ts +++ b/src/hooks/perps/useSubmitLimitOrder.ts @@ -86,7 +86,7 @@ export function useSubmitLimitOrder() { keeperFee, tradeDirection, price: adjustedLimitPrice, - reduceOnly: isReduceOnly, + isReduceOnly, comparison, } }, diff --git a/src/types/app.d.ts b/src/types/app.d.ts index 11fcbfd02..e70dd396b 100644 --- a/src/types/app.d.ts +++ b/src/types/app.d.ts @@ -338,6 +338,7 @@ interface PerpsPosition { currentPrice: BigNumber entryPrice: BigNumber type: PositionType + reduce_only?: boolean } interface PerpsLimitOrder { @@ -354,6 +355,7 @@ interface PerpPositionRow extends PerpsPosition { orderId?: string hasStopLoss?: boolean hasTakeProfit?: boolean + reduce_only?: boolean } interface PerpsPnL { diff --git a/src/utils/perps.ts b/src/utils/perps.ts index 15044d331..a707ea6c9 100644 --- a/src/utils/perps.ts +++ b/src/utils/perps.ts @@ -75,6 +75,7 @@ export const convertTriggerOrderResponseToPerpPosition = ( tradeDirection, amount: amount.abs(), type: isStopOrder(perpOrder, perpTrigger), + reduce_only: perpOrder.reduce_only ?? false, pnl: { net: BNCoin.fromCoin(limitOrder.order.keeper_fee).negated(), realized: { From 6d15431fb158fe921a965276423a3a1a94577845 Mon Sep 17 00:00:00 2001 From: Monkmansteve Date: Wed, 13 Nov 2024 16:05:06 +0200 Subject: [PATCH 11/62] feature: fix failing build --- .../account/AccountPerpPositionTable/Columns/Asset.tsx | 2 +- src/components/perps/Module/Summary.tsx | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/account/AccountPerpPositionTable/Columns/Asset.tsx b/src/components/account/AccountPerpPositionTable/Columns/Asset.tsx index 4c93473f0..ee9e47084 100644 --- a/src/components/account/AccountPerpPositionTable/Columns/Asset.tsx +++ b/src/components/account/AccountPerpPositionTable/Columns/Asset.tsx @@ -92,7 +92,7 @@ export default function Asset(props: Props) { {row.amount.isZero() ? ( ) : ( - + )}
diff --git a/src/components/perps/Module/Summary.tsx b/src/components/perps/Module/Summary.tsx index 623f41728..50f5e7550 100644 --- a/src/components/perps/Module/Summary.tsx +++ b/src/components/perps/Module/Summary.tsx @@ -238,6 +238,7 @@ export default function PerpsSummary(props: Props) { ? tradeDirection : (previousTradeDirection ?? 'long') } + type={isLimitOrder ? 'limit' : 'stop'} className='capitalize !text-sm' /> )} @@ -378,7 +379,7 @@ function ManageSummary( } = props const size = useMemo(() => previousAmount.plus(amount).abs(), [amount, previousAmount]) - + const isLimitOrder = props.orderType === OrderType.LIMIT if (amount.isZero()) return null return ( @@ -402,6 +403,7 @@ function ManageSummary( tradeDirection={ isNewPosition || isDirectionChange ? tradeDirection : previousTradeDirection } + type={isLimitOrder ? 'limit' : 'stop'} previousTradeDirection={isDirectionChange ? previousTradeDirection : undefined} /> From a2f7cdae56e6f228580b6221f14a3e1d06411d9b Mon Sep 17 00:00:00 2001 From: Monkmansteve Date: Wed, 13 Nov 2024 16:12:00 +0200 Subject: [PATCH 12/62] feature: remove double check --- src/components/perps/BalancesTable/Columns/TradeDirection.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/perps/BalancesTable/Columns/TradeDirection.tsx b/src/components/perps/BalancesTable/Columns/TradeDirection.tsx index c1f9abace..d38186598 100644 --- a/src/components/perps/BalancesTable/Columns/TradeDirection.tsx +++ b/src/components/perps/BalancesTable/Columns/TradeDirection.tsx @@ -63,7 +63,7 @@ export default function TradeDirection({ const currentPosition = currentAccount?.perps.find(byDenom(denom ?? '')) const positionEffect = showPositionEffect - ? amount && denom && type !== 'market' + ? amount && denom ? getPositionEffect(currentPosition, tradeDirection, BN(amount), type, reduce_only) : '' : '' From 9e5e622ec6fd83d168211f42cb25ad19d3c71ba0 Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Wed, 13 Nov 2024 16:11:36 +0100 Subject: [PATCH 13/62] fix: trade direction on mobile --- src/components/perps/BalancesTable/Columns/TradeDirection.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/perps/BalancesTable/Columns/TradeDirection.tsx b/src/components/perps/BalancesTable/Columns/TradeDirection.tsx index d38186598..31c8f285e 100644 --- a/src/components/perps/BalancesTable/Columns/TradeDirection.tsx +++ b/src/components/perps/BalancesTable/Columns/TradeDirection.tsx @@ -1,6 +1,6 @@ -import Text from 'components/common/Text' import classNames from 'classnames' import { ArrowRight } from 'components/common/Icons' +import Text from 'components/common/Text' import useCurrentAccount from 'hooks/accounts/useCurrentAccount' import { byDenom } from 'utils/array' import { BN } from 'utils/helpers' @@ -8,7 +8,7 @@ import { BN } from 'utils/helpers' export const TRADE_DIRECTION_META = { accessorKey: 'tradeDirection', header: 'Direction', - meta: { className: 'w-40 text-center' }, + meta: { className: 'w-40 min-w-40' }, } interface Props { From 19e44167f69a895425b5edb99ae447bc46d5ecc2 Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Thu, 14 Nov 2024 11:25:23 +0100 Subject: [PATCH 14/62] tidy: remove getOpeningFee --- src/api/perps/getOpeningFee.ts | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 src/api/perps/getOpeningFee.ts diff --git a/src/api/perps/getOpeningFee.ts b/src/api/perps/getOpeningFee.ts deleted file mode 100644 index f89d41c65..000000000 --- a/src/api/perps/getOpeningFee.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { getPerpsQueryClient } from 'api/cosmwasm-client' -import { BNCoin } from 'types/classes/BNCoin' - -export default async function getOpeningFee( - chainConfig: ChainConfig, - denom: string, - amount: string, -) { - const perpsClient = await getPerpsQueryClient(chainConfig) - - return perpsClient - .openingFee({ denom, size: amount as any }) - .then((resp) => BNCoin.fromCoin(resp.fee)) -} From 9b5ab7272fe3c5a2e91039f566c396806e05cc34 Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Thu, 14 Nov 2024 15:04:26 +0100 Subject: [PATCH 15/62] =?UTF-8?q?fix:=20added=20=E2=80=98Close=20Position?= =?UTF-8?q?=E2=80=99=20to=20the=20direction=20logic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BalancesTable/Columns/TradeDirection.tsx | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/components/perps/BalancesTable/Columns/TradeDirection.tsx b/src/components/perps/BalancesTable/Columns/TradeDirection.tsx index 31c8f285e..f813c5037 100644 --- a/src/components/perps/BalancesTable/Columns/TradeDirection.tsx +++ b/src/components/perps/BalancesTable/Columns/TradeDirection.tsx @@ -32,20 +32,18 @@ function getPositionEffect( if (!currentPosition) return '' if (orderType === 'market') return '' - if (currentPosition.tradeDirection === orderDirection) { - return 'Increase Position' - } - - if (isReduceOnly) return 'Reduce Position' + if (currentPosition.tradeDirection === orderDirection) return 'Increase Position' if (currentPosition.tradeDirection !== orderDirection) { - if (orderAmount.abs().isGreaterThan(currentPosition.amount.abs())) { - return 'Flip Position' - } - + if (orderAmount.abs().isGreaterThan(currentPosition.amount.abs())) return 'Flip Position' + if (orderAmount.abs().isEqualTo(currentPosition.amount.abs())) return 'Close Position' return 'Reduce Position' } + if (isReduceOnly) { + if (orderAmount.abs().isGreaterThan(currentPosition.amount.abs())) return 'Close Position' + return 'Reduce Position' + } return '' } From b2e58da5496c928b29833eeae1806febda45153e Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Thu, 14 Nov 2024 15:18:16 +0100 Subject: [PATCH 16/62] fix: fixed account preview update --- .../BalancesTable/Columns/TradeDirection.tsx | 9 +++--- src/components/perps/Module/PerpsModule.tsx | 31 +++++++------------ 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/src/components/perps/BalancesTable/Columns/TradeDirection.tsx b/src/components/perps/BalancesTable/Columns/TradeDirection.tsx index f813c5037..55dff9030 100644 --- a/src/components/perps/BalancesTable/Columns/TradeDirection.tsx +++ b/src/components/perps/BalancesTable/Columns/TradeDirection.tsx @@ -34,16 +34,17 @@ function getPositionEffect( if (currentPosition.tradeDirection === orderDirection) return 'Increase Position' + if (isReduceOnly) { + if (orderAmount.abs().isGreaterThan(currentPosition.amount.abs())) return 'Close Position' + return 'Reduce Position' + } + if (currentPosition.tradeDirection !== orderDirection) { if (orderAmount.abs().isGreaterThan(currentPosition.amount.abs())) return 'Flip Position' if (orderAmount.abs().isEqualTo(currentPosition.amount.abs())) return 'Close Position' return 'Reduce Position' } - if (isReduceOnly) { - if (orderAmount.abs().isGreaterThan(currentPosition.amount.abs())) return 'Close Position' - return 'Reduce Position' - } return '' } diff --git a/src/components/perps/Module/PerpsModule.tsx b/src/components/perps/Module/PerpsModule.tsx index ac78cc618..ce62427e0 100644 --- a/src/components/perps/Module/PerpsModule.tsx +++ b/src/components/perps/Module/PerpsModule.tsx @@ -6,6 +6,7 @@ import { Callout, CalloutType } from 'components/common/Callout' import Card from 'components/common/Card' import Divider from 'components/common/Divider' import LeverageSlider from 'components/common/LeverageSlider' +import LimitPriceInput from 'components/common/LimitPriceInput' import OrderTypeSelector from 'components/common/OrderTypeSelector' import SwitchWithLabel from 'components/common/Switch/SwitchWithLabel' import Text from 'components/common/Text' @@ -26,6 +27,7 @@ import useCurrentAccount from 'hooks/accounts/useCurrentAccount' import { useUpdatedAccount } from 'hooks/accounts/useUpdatedAccount' import useAssets from 'hooks/assets/useAssets' import usePerpsAsset from 'hooks/perps/usePerpsAsset' +import { usePerpsOrderForm } from 'hooks/perps/usePerpsOrderForm' import usePerpsVault from 'hooks/perps/usePerpsVault' import useTradingFeeAndPrice from 'hooks/perps/useTradingFeeAndPrice' import useAutoLend from 'hooks/wallet/useAutoLend' @@ -34,8 +36,6 @@ import { OrderType } from 'types/enums' import { byDenom } from 'utils/array' import getPerpsPosition from 'utils/getPerpsPosition' import { capitalizeFirstLetter } from 'utils/helpers' -import { usePerpsOrderForm } from 'hooks/perps/usePerpsOrderForm' -import LimitPriceInput from 'components/common/LimitPriceInput' export function PerpsModule() { const [tradeDirection, setTradeDirection] = useState('long') @@ -160,8 +160,15 @@ export function PerpsModule() { setStopPrice(BN_ZERO) setSelectedOrderType(orderType) setIsReduceOnly(false) + simulatePerps(currentPerpPosition, isAutoLendEnabledForCurrentAccount) }, - [updateAmount, setLimitPrice], + [ + updateAmount, + setLimitPrice, + simulatePerps, + currentPerpPosition, + isAutoLendEnabledForCurrentAccount, + ], ) const onChangeStopTradeDirection = useCallback( @@ -248,23 +255,7 @@ export function PerpsModule() { useEffect(() => { if (!tradingFee || !perpsVault || perpsVaultModal) return - if (isLimitOrder) { - return - } - - if (isStopOrder && currentPerpPosition) { - const newPosition = getPerpsPosition( - perpsVault.denom, - perpsAsset, - currentPerpPosition.amount.negated(), - stopTradeDirection, - tradingFee, - currentPerpPosition, - stopPrice, - ) - simulatePerps(newPosition, isAutoLendEnabledForCurrentAccount) - return - } + if (isLimitOrder || isStopOrder) return const newAmount = currentPerpPosition?.amount.plus(amount) ?? amount const previousTradeDirection = currentPerpPosition?.amount.isLessThan(0) ? 'short' : 'long' From 28d379cf6d8ac07947737125a5a315af63070344 Mon Sep 17 00:00:00 2001 From: Monkmansteve Date: Thu, 14 Nov 2024 16:32:34 +0200 Subject: [PATCH 17/62] feature: revert contract affresses --- src/chains/neutron/pion-1.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/chains/neutron/pion-1.ts b/src/chains/neutron/pion-1.ts index b4e042e27..1b1ea4ec1 100644 --- a/src/chains/neutron/pion-1.ts +++ b/src/chains/neutron/pion-1.ts @@ -13,13 +13,13 @@ const Pion1: ChainConfig = { sell: 'factory/neutron1ke0vqqzyymlp5esr8gjwuzh94ysnpvj8er5hm7/UUSDC', }, contracts: { - redBank: 'neutron1vxvqs075q7y9tvpmt60xjmejrfvuw8mcvgqkug67des96y7psalqrl4cn6', - incentives: 'neutron10a4rt7utgqrpf24jeluc2gt42r83f0ammxnmntq687ycwh7ugysqnfwduy', - oracle: 'neutron13a7vspwpf3vnjq292xsvk8l8y0r7uwn4vtaev04zyl7r0wu8slzsveq09g', - params: 'neutron13pwuvh2kwlvs9q4cm9yfm5xymghle066hq40m2yagg6sh7c09ncqzey946', - creditManager: 'neutron13jm8hk5znqk5t5mlvgphvfea300kayqhhy8hdhmrdtsfypkl7ehqke4d2m', - accountNft: 'neutron1l9vthzck3t7z2ys943jwaxskkjaws3qexhyuhsytqpx8t9ht6lyq4tre4d', - perps: 'neutron1ey5vc5yvlauea7aryuvuxphxvr473ayjxw7h30eq62s4uzcjsx4qsvnfxs', + redBank: 'neutron1f8ag222s4rnytkweym7lfncrxhtee3za5uk54r5n2rjxvsl9slzq36f66d', + incentives: 'neutron12hvgykldx0vxly59ta0ufjz776wxkl9k3r8ugln7xn6zus34a44s2vqw26', + oracle: 'neutron1pev35y62g6vte0s9t67gsf6m8d60x36t7wr0p0ghjl9r3h5mwl0q4h2zwc', + params: 'neutron1q66e3jv2j9r0duzwzt37fwl7h5njhr2kqs0fxmaa58sfqke80a2ss5hrz7', + creditManager: 'neutron13vyqc4efsnc357ze97ppv9h954zjasuj9d0w8es3mk9ea8sg6mvsr3xkjg', + accountNft: 'neutron1hx27cs7jjuvwq4hqgxn4av8agnspy2nwvrrq8e9f80jkeyrwrh8s8x645z', + perps: 'neutron1yu66sjvgg8shfjxkdlxcqh8yg6tmymsgve8lv62q6k4wrs5mt0pq6ard0n', pyth: 'neutron15ldst8t80982akgr8w8ekcytejzkmfpgdkeq4xgtge48qs7435jqp87u3t', }, endpoints: { From 44b9de354ba45f4d2eeb0195522c3c2a891345bd Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Fri, 15 Nov 2024 08:52:49 +0100 Subject: [PATCH 18/62] feat: make banner closable added funding rate remember function --- src/components/common/Banner.tsx | 25 ++++++++++++++++--- src/components/perps/PerpsBanner.tsx | 15 +++++++++-- .../perps/PerpsInfo/FundingRate.tsx | 10 +++++++- src/constants/defaultSettings.ts | 2 ++ src/constants/localStorageKeys.ts | 2 ++ 5 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/components/common/Banner.tsx b/src/components/common/Banner.tsx index 98b4b94c3..2efc2c008 100644 --- a/src/components/common/Banner.tsx +++ b/src/components/common/Banner.tsx @@ -1,17 +1,20 @@ import classNames from 'classnames' +import AssetImage from 'components/common/assets/AssetImage' +import Button from 'components/common/Button' import Text from 'components/common/Text' import React from 'react' -import AssetImage from 'components/common/assets/AssetImage' +import { Cross } from './Icons' interface Props { asset?: Asset title: React.ReactNode description: string button: React.ReactNode + onClose?: () => void } export default function Banner(props: Props) { - const { asset, title, description, button } = props + const { asset, title, description, button, onClose } = props return (
-
+ {onClose && ( +
+
+ )} +
{asset && }
- {title} + + {title} + {description} diff --git a/src/components/perps/PerpsBanner.tsx b/src/components/perps/PerpsBanner.tsx index a360cdffc..a4b29edbd 100644 --- a/src/components/perps/PerpsBanner.tsx +++ b/src/components/perps/PerpsBanner.tsx @@ -1,6 +1,10 @@ import Banner from 'components/common/Banner' import { Deposit } from 'components/earn/farm/common/Table/Columns/Deposit' +import { getDefaultChainSettings } from 'constants/defaultSettings' +import { LocalStorageKeys } from 'constants/localStorageKeys' import useWhitelistedAssets from 'hooks/assets/useWhitelistedAssets' +import useChainConfig from 'hooks/chain/useChainConfig' +import useLocalStorage from 'hooks/localStorage/useLocalStorage' import usePerpsVault from 'hooks/perps/usePerpsVault' import { byDenom } from 'utils/array' import { formatValue } from 'utils/formatters' @@ -8,17 +12,24 @@ import { formatValue } from 'utils/formatters' export default function PerpsBanner() { const { data: vault } = usePerpsVault() const whitelistedAssets = useWhitelistedAssets() + const chainConfig = useChainConfig() const asset = whitelistedAssets.find(byDenom(vault?.denom ?? '')) + const [showPerpsVaultBanner, setShowPerpsVaultBanner] = useLocalStorage( + LocalStorageKeys.SHOW_PERPS_VAULT_BANNER, + getDefaultChainSettings(chainConfig).showPerpsVaultBanner, + ) + if (!showPerpsVaultBanner) return null return ( setShowPerpsVaultBanner(false)} title={ <> - Counterparty vault: Earn up to{' '} + Counterparty vault APY:{' '} {formatValue(vault?.apy ?? 0, { - suffix: '% APY', + suffix: '%', maxDecimals: 2, minDecimals: 0, abbreviated: false, diff --git a/src/components/perps/PerpsInfo/FundingRate.tsx b/src/components/perps/PerpsInfo/FundingRate.tsx index 2c8e7dc6f..f1b6e0961 100644 --- a/src/components/perps/PerpsInfo/FundingRate.tsx +++ b/src/components/perps/PerpsInfo/FundingRate.tsx @@ -6,6 +6,10 @@ import { Tooltip } from 'components/common/Tooltip' import { BN_ZERO } from 'constants/math' import useToggle from 'hooks/common/useToggle' import usePerpsMarket from 'hooks/perps/usePerpsMarket' +import useLocalStorage from 'hooks/localStorage/useLocalStorage' +import { LocalStorageKeys } from 'constants/localStorageKeys' +import { getDefaultChainSettings } from 'constants/defaultSettings' +import useChainConfig from 'hooks/chain/useChainConfig' type Interval = '1H' | '1D' | '1W' | '1M' | '1Y' @@ -19,7 +23,11 @@ enum Intervals { export default function FundingRate() { const market = usePerpsMarket() - const [interval, setInterval] = useState('1H') + const chainConfig = useChainConfig() + const [interval, setInterval] = useLocalStorage( + LocalStorageKeys.FUNDING_RATE_INTERVAL, + getDefaultChainSettings(chainConfig).fundingRateInterval, + ) const [show, toggleShow] = useToggle(false) const fundingRate = useMemo(() => { diff --git a/src/constants/defaultSettings.ts b/src/constants/defaultSettings.ts index 863b68c62..398f3b24f 100644 --- a/src/constants/defaultSettings.ts +++ b/src/constants/defaultSettings.ts @@ -24,5 +24,7 @@ export const getDefaultChainSettings = (chainConfig: ChainConfig) => { showSummary: true, perpsKeeperFee: BNCoin.fromDenomAndBigNumber('usd', BN_ZERO_ONE).toCoin(), tvChartStore: JSON.stringify({}), + showPerpsVaultBanner: true, + fundingRateInterval: '1H', } } diff --git a/src/constants/localStorageKeys.ts b/src/constants/localStorageKeys.ts index 86e0b9308..90699946e 100644 --- a/src/constants/localStorageKeys.ts +++ b/src/constants/localStorageKeys.ts @@ -26,4 +26,6 @@ export enum LocalStorageKeys { REWARDS_CENTER_TYPE = 'rewardsCenterType', SHOW_SUMMARY = 'showSummary', TV_CHART_STORE = 'tvChartStore', + SHOW_PERPS_VAULT_BANNER = 'showPerpsVaultBanner', + FUNDING_RATE_INTERVAL = 'fundingRateInterval', } From d01136dceb784fd913b52c72b11184955a7bac8e Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Fri, 15 Nov 2024 08:54:48 +0100 Subject: [PATCH 19/62] env: change to comp contracts --- src/chains/neutron/pion-1.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/chains/neutron/pion-1.ts b/src/chains/neutron/pion-1.ts index 1b1ea4ec1..b4e042e27 100644 --- a/src/chains/neutron/pion-1.ts +++ b/src/chains/neutron/pion-1.ts @@ -13,13 +13,13 @@ const Pion1: ChainConfig = { sell: 'factory/neutron1ke0vqqzyymlp5esr8gjwuzh94ysnpvj8er5hm7/UUSDC', }, contracts: { - redBank: 'neutron1f8ag222s4rnytkweym7lfncrxhtee3za5uk54r5n2rjxvsl9slzq36f66d', - incentives: 'neutron12hvgykldx0vxly59ta0ufjz776wxkl9k3r8ugln7xn6zus34a44s2vqw26', - oracle: 'neutron1pev35y62g6vte0s9t67gsf6m8d60x36t7wr0p0ghjl9r3h5mwl0q4h2zwc', - params: 'neutron1q66e3jv2j9r0duzwzt37fwl7h5njhr2kqs0fxmaa58sfqke80a2ss5hrz7', - creditManager: 'neutron13vyqc4efsnc357ze97ppv9h954zjasuj9d0w8es3mk9ea8sg6mvsr3xkjg', - accountNft: 'neutron1hx27cs7jjuvwq4hqgxn4av8agnspy2nwvrrq8e9f80jkeyrwrh8s8x645z', - perps: 'neutron1yu66sjvgg8shfjxkdlxcqh8yg6tmymsgve8lv62q6k4wrs5mt0pq6ard0n', + redBank: 'neutron1vxvqs075q7y9tvpmt60xjmejrfvuw8mcvgqkug67des96y7psalqrl4cn6', + incentives: 'neutron10a4rt7utgqrpf24jeluc2gt42r83f0ammxnmntq687ycwh7ugysqnfwduy', + oracle: 'neutron13a7vspwpf3vnjq292xsvk8l8y0r7uwn4vtaev04zyl7r0wu8slzsveq09g', + params: 'neutron13pwuvh2kwlvs9q4cm9yfm5xymghle066hq40m2yagg6sh7c09ncqzey946', + creditManager: 'neutron13jm8hk5znqk5t5mlvgphvfea300kayqhhy8hdhmrdtsfypkl7ehqke4d2m', + accountNft: 'neutron1l9vthzck3t7z2ys943jwaxskkjaws3qexhyuhsytqpx8t9ht6lyq4tre4d', + perps: 'neutron1ey5vc5yvlauea7aryuvuxphxvr473ayjxw7h30eq62s4uzcjsx4qsvnfxs', pyth: 'neutron15ldst8t80982akgr8w8ekcytejzkmfpgdkeq4xgtge48qs7435jqp87u3t', }, endpoints: { From d66f844d5e22a7e71199b6644727730f2e771bfd Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Fri, 15 Nov 2024 08:59:35 +0100 Subject: [PATCH 20/62] fix: move toast to bottom right --- src/components/common/Toaster/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/common/Toaster/index.tsx b/src/components/common/Toaster/index.tsx index c10b387e7..cc5061203 100644 --- a/src/components/common/Toaster/index.tsx +++ b/src/components/common/Toaster/index.tsx @@ -100,6 +100,7 @@ export default function Toaster() { closeOnClick: false, hideProgressBar: true, autoClose: false, + position: 'bottom-right', }) } From 4aad4f32c39016cfb8b4eb66820b88746c48a441 Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Fri, 15 Nov 2024 09:02:08 +0100 Subject: [PATCH 21/62] fix: typing --- src/components/perps/PerpsInfo/FundingRate.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/perps/PerpsInfo/FundingRate.tsx b/src/components/perps/PerpsInfo/FundingRate.tsx index f1b6e0961..2a01e98b1 100644 --- a/src/components/perps/PerpsInfo/FundingRate.tsx +++ b/src/components/perps/PerpsInfo/FundingRate.tsx @@ -1,15 +1,15 @@ -import { useMemo, useState } from 'react' +import { useMemo } from 'react' import { FormattedNumber } from 'components/common/FormattedNumber' import { ChevronDown } from 'components/common/Icons' import { Tooltip } from 'components/common/Tooltip' +import { getDefaultChainSettings } from 'constants/defaultSettings' +import { LocalStorageKeys } from 'constants/localStorageKeys' import { BN_ZERO } from 'constants/math' +import useChainConfig from 'hooks/chain/useChainConfig' import useToggle from 'hooks/common/useToggle' -import usePerpsMarket from 'hooks/perps/usePerpsMarket' import useLocalStorage from 'hooks/localStorage/useLocalStorage' -import { LocalStorageKeys } from 'constants/localStorageKeys' -import { getDefaultChainSettings } from 'constants/defaultSettings' -import useChainConfig from 'hooks/chain/useChainConfig' +import usePerpsMarket from 'hooks/perps/usePerpsMarket' type Interval = '1H' | '1D' | '1W' | '1M' | '1Y' @@ -26,7 +26,7 @@ export default function FundingRate() { const chainConfig = useChainConfig() const [interval, setInterval] = useLocalStorage( LocalStorageKeys.FUNDING_RATE_INTERVAL, - getDefaultChainSettings(chainConfig).fundingRateInterval, + getDefaultChainSettings(chainConfig).fundingRateInterval as Interval, ) const [show, toggleShow] = useToggle(false) From 4fbdb8036e015f0e602e541f118591cf996d93fe Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Fri, 15 Nov 2024 09:05:46 +0100 Subject: [PATCH 22/62] fix: fixed perps reset after execute --- src/components/common/AssetAmountInput.tsx | 3 ++- src/components/perps/Module/PerpsModule.tsx | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/common/AssetAmountInput.tsx b/src/components/common/AssetAmountInput.tsx index 7d521e7e7..c8755fab6 100644 --- a/src/components/common/AssetAmountInput.tsx +++ b/src/components/common/AssetAmountInput.tsx @@ -5,6 +5,7 @@ import DisplayCurrency from 'components/common/DisplayCurrency' import NumberInput from 'components/common/NumberInput' import { BN_ZERO } from 'constants/math' import { BNCoin } from 'types/classes/BNCoin' +import { formatValue } from 'utils/formatters' interface Props { label?: string @@ -108,7 +109,7 @@ export default function AssetAmountInput(props: Props) {
{maxButtonLabel ?? 'Max:'} - {maxValue} + {formatValue(maxValue, { abbreviated: false })}
updateAmount(BN_ZERO)} + onTxExecuted={() => { + updateAmount(BN_ZERO) + simulatePerps(currentPerpPosition, isAutoLendEnabledForCurrentAccount) + }} disabled={isDisabledExecution} orderType={selectedOrderType} limitPrice={isLimitOrder ? limitPrice : BN_ZERO} From 0514a35c805958a97f061e463fcfb143f8fe64ab Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Fri, 15 Nov 2024 09:08:16 +0100 Subject: [PATCH 23/62] fix: chainSelect mutation of clients --- src/components/header/ChainSelect.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/header/ChainSelect.tsx b/src/components/header/ChainSelect.tsx index 4f75c2ae8..bb12d45fb 100644 --- a/src/components/header/ChainSelect.tsx +++ b/src/components/header/ChainSelect.tsx @@ -105,6 +105,7 @@ export default function ChainSelect(props: Props) { onSelect(chainConfig) mutate(`chains/${chainConfig.id}/accounts/default`) mutate(`chains/${chainConfig.id}/accounts/high_levered_strategy`) + mutate(`chains/${chainConfig.id}/clients`) } : () => { if (chainConfig) { From 53dad1014e15042b4be5b4914087615bed1d78fc Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Fri, 15 Nov 2024 10:08:01 +0100 Subject: [PATCH 24/62] fix: columns and bad state --- src/components/common/Footer.tsx | 9 ++++++--- src/components/perps/BalancesTable/Columns/Size.tsx | 1 + .../perps/BalancesTable/Columns/TradeDirection.tsx | 1 + .../BalancesTable/Columns/usePerpsBalancesColumns.tsx | 6 ++---- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/components/common/Footer.tsx b/src/components/common/Footer.tsx index 73fefce49..8e5b64203 100644 --- a/src/components/common/Footer.tsx +++ b/src/components/common/Footer.tsx @@ -3,6 +3,7 @@ import { DocURL } from 'types/enums' import useAssets from 'hooks/assets/useAssets' import usePerpsVault from 'hooks/perps/usePerpsVault' +import { useEffect } from 'react' import useStore from 'store' import packageInfo from '../../../package.json' @@ -13,9 +14,11 @@ export default function Footer() { const storeAssets = useStore((s) => s.assets) const perpsBaseDenom = useStore((s) => s.perpsBaseDenom) - if (storeAssets.length === 0 && !isLoadingAssets) useStore.setState({ assets }) - if (!perpsBaseDenom && !isLoadingVault && vault) - useStore.setState({ perpsBaseDenom: vault.denom }) + useEffect(() => { + if (storeAssets.length === 0 && !isLoadingAssets) useStore.setState({ assets }) + if (!perpsBaseDenom && !isLoadingVault && vault) + useStore.setState({ perpsBaseDenom: vault.denom }) + }, [assets, isLoadingAssets, isLoadingVault, perpsBaseDenom, storeAssets.length, vault]) const version = `v${packageInfo.version}` return ( diff --git a/src/components/perps/BalancesTable/Columns/Size.tsx b/src/components/perps/BalancesTable/Columns/Size.tsx index 2a5559a48..3388bb74c 100644 --- a/src/components/perps/BalancesTable/Columns/Size.tsx +++ b/src/components/perps/BalancesTable/Columns/Size.tsx @@ -8,6 +8,7 @@ import { BNCoin } from 'types/classes/BNCoin' import { demagnify, getPerpsPriceDecimals } from 'utils/formatters' export const SIZE_META = { + id: 'size', accessorKey: 'size', header: () => (
diff --git a/src/components/perps/BalancesTable/Columns/TradeDirection.tsx b/src/components/perps/BalancesTable/Columns/TradeDirection.tsx index 55dff9030..897103192 100644 --- a/src/components/perps/BalancesTable/Columns/TradeDirection.tsx +++ b/src/components/perps/BalancesTable/Columns/TradeDirection.tsx @@ -6,6 +6,7 @@ import { byDenom } from 'utils/array' import { BN } from 'utils/helpers' export const TRADE_DIRECTION_META = { + id: 'direction', accessorKey: 'tradeDirection', header: 'Direction', meta: { className: 'w-40 min-w-40' }, diff --git a/src/components/perps/BalancesTable/Columns/usePerpsBalancesColumns.tsx b/src/components/perps/BalancesTable/Columns/usePerpsBalancesColumns.tsx index 7b47694bc..a35f7ee53 100644 --- a/src/components/perps/BalancesTable/Columns/usePerpsBalancesColumns.tsx +++ b/src/components/perps/BalancesTable/Columns/usePerpsBalancesColumns.tsx @@ -7,14 +7,14 @@ import Manage, { MANAGE_META } from 'components/perps/BalancesTable/Columns/Mana import { PERP_NAME_META, PerpName } from 'components/perps/BalancesTable/Columns/PerpName' import PnL, { PNL_META } from 'components/perps/BalancesTable/Columns/PnL' import Size, { SIZE_META, sizeSortingFn } from 'components/perps/BalancesTable/Columns/Size' +import { Status, STATUS_META } from 'components/perps/BalancesTable/Columns/Status' import TradeDirection, { TRADE_DIRECTION_META, } from 'components/perps/BalancesTable/Columns/TradeDirection' import { PRICE_ORACLE_DECIMALS } from 'constants/query' +import usePerpsLimitOrderRows from 'hooks/perps/usePerpsLimitOrdersRows' import { demagnify } from 'utils/formatters' import { BN } from 'utils/helpers' -import { Status, STATUS_META } from 'components/perps/BalancesTable/Columns/Status' -import usePerpsLimitOrderRows from 'hooks/perps/usePerpsLimitOrdersRows' import { checkStopLossAndTakeProfit } from 'utils/perps' interface Props { @@ -33,7 +33,6 @@ export default function usePerpsBalancesColumns(props: Props) { }, { ...TRADE_DIRECTION_META, - id: 'direction', cell: ({ row }) => { const { type, tradeDirection, reduce_only, amount, denom } = row.original return ( @@ -50,7 +49,6 @@ export default function usePerpsBalancesColumns(props: Props) { }, { ...SIZE_META, - id: 'entryPrice', cell: ({ row }) => { const { asset, amount, type, entryPrice } = row.original const demagnifiedAmount = BN(demagnify(amount, asset)) From ac72dc852af8d70674f0604a0d43c676a50813f4 Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Fri, 15 Nov 2024 10:26:56 +0100 Subject: [PATCH 25/62] feat: made indicators persistant --- src/components/trade/TradeChart/constants.ts | 2 ++ src/components/trade/TradeChart/index.tsx | 27 +++++++++++++++----- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/components/trade/TradeChart/constants.ts b/src/components/trade/TradeChart/constants.ts index 2cab4f55a..a0b145a74 100644 --- a/src/components/trade/TradeChart/constants.ts +++ b/src/components/trade/TradeChart/constants.ts @@ -16,6 +16,7 @@ export const disabledFeatures: ChartingLibraryFeatureset[] = [ 'symbol_info', 'go_to_date', 'timeframes_toolbar', + 'create_volume_indicator_by_default', ] export const enabledFeatures: ChartingLibraryFeatureset[] = [ @@ -47,6 +48,7 @@ export const disabledFeaturesMobile: ChartingLibraryFeatureset[] = [ 'symbol_info', 'go_to_date', 'timeframes_toolbar', + 'create_volume_indicator_by_default', ] export const enabledFeaturesMobile: ChartingLibraryFeatureset[] = [ diff --git a/src/components/trade/TradeChart/index.tsx b/src/components/trade/TradeChart/index.tsx index b068362d6..59d0df111 100644 --- a/src/components/trade/TradeChart/index.tsx +++ b/src/components/trade/TradeChart/index.tsx @@ -134,9 +134,9 @@ export default function TradeChart(props: Props) { const chart = chartWidget.activeChart() if (!chart) return const chartStore = JSON.parse(localStorage.getItem(LocalStorageKeys.TV_CHART_STORE) ?? '{}') - const currentChartStore = chartStore[chartName] - if (!currentChartStore) return - currentChartStore.forEach((shape: TradingViewShape) => { + const currentChartShapeStore = chartStore[chartName] + if (!currentChartShapeStore) return + currentChartShapeStore.forEach((shape: TradingViewShape) => { if (Array.isArray(shape.points)) { if (shape.points.length === 0) return chart.createMultipointShape(shape.points, shape.shape) @@ -144,6 +144,11 @@ export default function TradeChart(props: Props) { chart.createShape(shape.points, shape.shape) } }) + const currentChartStudyStore = chartStore[`${chartName}-studies`] + if (!currentChartStudyStore) return + currentChartStudyStore.forEach((studyName: string) => { + chart.createStudy(studyName) + }) if (!isPerps || !onCreateLimitOrder) return chartWidget.onContextMenu((unixTime, price) => { return [ @@ -162,13 +167,16 @@ export default function TradeChart(props: Props) { } }, [chartName, onCreateLimitOrder, isPerps]) - const updateShapes = useCallback(() => { + const updateShapesAndStudies = useCallback(() => { const chart = chartWidget.activeChart() const settings = getTradingViewSettings(theme) const oraclePriceDecimalDiff = props.buyAsset.decimals - PRICE_ORACLE_DECIMALS const { downColor, upColor } = settings.chartStyle const currentShapes = [] as TradingViewShape[] + const currentStudies = [] as string[] const allShapes = chart.getAllShapes() + const allStudies = chart.getAllStudies() + allShapes.forEach((shape) => { const currentShape = chart.getShapeById(shape.id).getProperties() const currentShapePoints = chart.getShapeById(shape.id).getPoints() @@ -182,9 +190,14 @@ export default function TradeChart(props: Props) { } }) + allStudies.forEach((study) => { + currentStudies.push(study.name) + }) + const newTvChartStore = JSON.stringify({ ...JSON.parse(tvChartStore), [chartName]: currentShapes, + [`${chartName}-studies`]: currentStudies, }) setTvChartStore(newTvChartStore) @@ -336,15 +349,15 @@ export default function TradeChart(props: Props) { useEffect(() => { if (!chartWidget) return chartWidget.onChartReady(() => { - updateShapes() + updateShapesAndStudies() chartWidget .activeChart() .onIntervalChanged() .subscribe(null, () => { - updateShapes() + updateShapesAndStudies() }) }) - }, [updateShapes]) + }, [updateShapesAndStudies]) return ( Date: Fri, 15 Nov 2024 10:29:37 +0100 Subject: [PATCH 26/62] fix: disable local store implementaiton of trading view --- src/components/trade/TradeChart/constants.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/trade/TradeChart/constants.ts b/src/components/trade/TradeChart/constants.ts index a0b145a74..940954547 100644 --- a/src/components/trade/TradeChart/constants.ts +++ b/src/components/trade/TradeChart/constants.ts @@ -17,12 +17,12 @@ export const disabledFeatures: ChartingLibraryFeatureset[] = [ 'go_to_date', 'timeframes_toolbar', 'create_volume_indicator_by_default', + 'use_localstorage_for_settings', ] export const enabledFeatures: ChartingLibraryFeatureset[] = [ 'timezone_menu', 'header_settings', - 'use_localstorage_for_settings', 'chart_zoom', 'horz_touch_drag_scroll', 'vert_touch_drag_scroll', @@ -49,11 +49,11 @@ export const disabledFeaturesMobile: ChartingLibraryFeatureset[] = [ 'go_to_date', 'timeframes_toolbar', 'create_volume_indicator_by_default', + 'use_localstorage_for_settings', ] export const enabledFeaturesMobile: ChartingLibraryFeatureset[] = [ 'horz_touch_drag_scroll', - 'use_localstorage_for_settings', 'chart_zoom', 'hide_left_toolbar_by_default', ] From 8f46fb5e551bd6e35b7550950c559f30b65fbebd Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Fri, 15 Nov 2024 10:29:37 +0100 Subject: [PATCH 27/62] fix: disable local store implementaiton of trading view --- src/components/trade/TradeChart/constants.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/trade/TradeChart/constants.ts b/src/components/trade/TradeChart/constants.ts index a0b145a74..940954547 100644 --- a/src/components/trade/TradeChart/constants.ts +++ b/src/components/trade/TradeChart/constants.ts @@ -17,12 +17,12 @@ export const disabledFeatures: ChartingLibraryFeatureset[] = [ 'go_to_date', 'timeframes_toolbar', 'create_volume_indicator_by_default', + 'use_localstorage_for_settings', ] export const enabledFeatures: ChartingLibraryFeatureset[] = [ 'timezone_menu', 'header_settings', - 'use_localstorage_for_settings', 'chart_zoom', 'horz_touch_drag_scroll', 'vert_touch_drag_scroll', @@ -49,11 +49,11 @@ export const disabledFeaturesMobile: ChartingLibraryFeatureset[] = [ 'go_to_date', 'timeframes_toolbar', 'create_volume_indicator_by_default', + 'use_localstorage_for_settings', ] export const enabledFeaturesMobile: ChartingLibraryFeatureset[] = [ 'horz_touch_drag_scroll', - 'use_localstorage_for_settings', 'chart_zoom', 'hide_left_toolbar_by_default', ] From 07bb12176c9f7d6eb1ea3b7852f01beb49e13a2d Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Fri, 15 Nov 2024 10:40:33 +0100 Subject: [PATCH 28/62] fix: fixed the size in the Perp Positions Table --- src/components/perps/BalancesTable/Columns/Size.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/perps/BalancesTable/Columns/Size.tsx b/src/components/perps/BalancesTable/Columns/Size.tsx index 3388bb74c..34646afcd 100644 --- a/src/components/perps/BalancesTable/Columns/Size.tsx +++ b/src/components/perps/BalancesTable/Columns/Size.tsx @@ -38,7 +38,7 @@ export default function Size(props: Props) { From 018bec4638c349e221cf391f0d4ab329a0defc5c Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Fri, 15 Nov 2024 11:58:48 +0100 Subject: [PATCH 29/62] fix: add a try catch to updating the chart --- src/components/trade/TradeChart/index.tsx | 173 +++++++++++----------- 1 file changed, 89 insertions(+), 84 deletions(-) diff --git a/src/components/trade/TradeChart/index.tsx b/src/components/trade/TradeChart/index.tsx index 59d0df111..ad27e88c8 100644 --- a/src/components/trade/TradeChart/index.tsx +++ b/src/components/trade/TradeChart/index.tsx @@ -168,106 +168,111 @@ export default function TradeChart(props: Props) { }, [chartName, onCreateLimitOrder, isPerps]) const updateShapesAndStudies = useCallback(() => { - const chart = chartWidget.activeChart() - const settings = getTradingViewSettings(theme) - const oraclePriceDecimalDiff = props.buyAsset.decimals - PRICE_ORACLE_DECIMALS - const { downColor, upColor } = settings.chartStyle - const currentShapes = [] as TradingViewShape[] - const currentStudies = [] as string[] - const allShapes = chart.getAllShapes() - const allStudies = chart.getAllStudies() - - allShapes.forEach((shape) => { - const currentShape = chart.getShapeById(shape.id).getProperties() - const currentShapePoints = chart.getShapeById(shape.id).getPoints() - if (isAutomaticAddedLine(shape.name, currentShape)) { - chart.removeEntity(shape.id) - } else { - currentShapes.push({ - points: currentShapePoints, - shape: { ...currentShape, shape: shape.name as TradingViewShapeNames }, - }) - } - }) - - allStudies.forEach((study) => { - currentStudies.push(study.name) - }) - - const newTvChartStore = JSON.stringify({ - ...JSON.parse(tvChartStore), - [chartName]: currentShapes, - [`${chartName}-studies`]: currentStudies, - }) - setTvChartStore(newTvChartStore) - - if (entryPrice) { - chart.createShape( - { price: entryPrice, time: moment().unix() }, - { - shape: 'horizontal_line', - lock: true, - disableSelection: true, - zOrder: 'top', - text: 'Entry', - overrides: { - linecolor: tradeDirection === 'long' ? upColor : downColor, - textcolor: tradeDirection === 'long' ? upColor : downColor, - linestyle: 0, - linewidth: 1, - showLabel: true, - }, - }, - ) - } + try { + const chart = chartWidget.activeChart() + const settings = getTradingViewSettings(theme) + const oraclePriceDecimalDiff = props.buyAsset.decimals - PRICE_ORACLE_DECIMALS + const { downColor, upColor } = settings.chartStyle + const currentShapes = [] as TradingViewShape[] + const currentStudies = [] as string[] + const allShapes = chart.getAllShapes() + const allStudies = chart.getAllStudies() + + allShapes.forEach((shape) => { + const currentShape = chart.getShapeById(shape.id).getProperties() + const currentShapePoints = chart.getShapeById(shape.id).getPoints() + if (isAutomaticAddedLine(shape.name, currentShape)) { + chart.removeEntity(shape.id) + } else { + currentShapes.push({ + points: currentShapePoints, + shape: { ...currentShape, shape: shape.name as TradingViewShapeNames }, + }) + } + }) - if (liquidationPrice) { - chart.createShape( - { price: liquidationPrice, time: moment().unix() }, - { - shape: 'horizontal_line', - lock: true, - disableSelection: true, - text: 'Liquidation', - zOrder: 'top', - overrides: { - linecolor: '#fdb021', - linestyle: 0, - linewidth: 1, - textcolor: '#fdb021', - showLabel: true, - }, - }, - ) - } - if (props.limitOrders) { - const currentPosition = props.perpsPosition?.amount.isGreaterThan(0) ? 'long' : 'short' - const positionAmount = props.perpsPosition?.amount || null + allStudies.forEach((study) => { + currentStudies.push(study.name) + }) - props.limitOrders.forEach((order) => { - const price = order.entryPrice.shiftedBy(oraclePriceDecimalDiff).toNumber() + const newTvChartStore = JSON.stringify({ + ...JSON.parse(tvChartStore), + [chartName]: currentShapes, + [`${chartName}-studies`]: currentStudies, + }) + setTvChartStore(newTvChartStore) + if (entryPrice) { chart.createShape( + { price: entryPrice, time: moment().unix() }, { - price: price, - time: moment().unix(), + shape: 'horizontal_line', + lock: true, + disableSelection: true, + zOrder: 'top', + text: 'Entry', + overrides: { + linecolor: tradeDirection === 'long' ? upColor : downColor, + textcolor: tradeDirection === 'long' ? upColor : downColor, + linestyle: 0, + linewidth: 1, + showLabel: true, + }, }, + ) + } + + if (liquidationPrice) { + chart.createShape( + { price: liquidationPrice, time: moment().unix() }, { shape: 'horizontal_line', lock: true, disableSelection: true, + text: 'Liquidation', zOrder: 'top', - text: getLimitOrderText(order, props.buyAsset, currentPosition, positionAmount), overrides: { - linecolor: order.tradeDirection === 'long' ? upColor : downColor, - textcolor: order.tradeDirection === 'long' ? upColor : downColor, - showLabel: true, - linestyle: 2, + linecolor: '#fdb021', + linestyle: 0, linewidth: 1, + textcolor: '#fdb021', + showLabel: true, }, }, ) - }) + } + if (props.limitOrders) { + const currentPosition = props.perpsPosition?.amount.isGreaterThan(0) ? 'long' : 'short' + const positionAmount = props.perpsPosition?.amount || null + + props.limitOrders.forEach((order) => { + const price = order.entryPrice.shiftedBy(oraclePriceDecimalDiff).toNumber() + + chart.createShape( + { + price: price, + time: moment().unix(), + }, + { + shape: 'horizontal_line', + lock: true, + disableSelection: true, + zOrder: 'top', + text: getLimitOrderText(order, props.buyAsset, currentPosition, positionAmount), + overrides: { + linecolor: order.tradeDirection === 'long' ? upColor : downColor, + textcolor: order.tradeDirection === 'long' ? upColor : downColor, + showLabel: true, + linestyle: 2, + linewidth: 1, + }, + }, + ) + }) + } + } catch (e) { + console.info('Error on updating chart', e) + return } }, [ chartName, From cd19a49ee3513aa040730b958a7eac67cad71375 Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Fri, 15 Nov 2024 12:01:05 +0100 Subject: [PATCH 30/62] fix: re-enable local storage --- src/components/trade/TradeChart/constants.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/trade/TradeChart/constants.ts b/src/components/trade/TradeChart/constants.ts index 940954547..a60c728ac 100644 --- a/src/components/trade/TradeChart/constants.ts +++ b/src/components/trade/TradeChart/constants.ts @@ -17,7 +17,6 @@ export const disabledFeatures: ChartingLibraryFeatureset[] = [ 'go_to_date', 'timeframes_toolbar', 'create_volume_indicator_by_default', - 'use_localstorage_for_settings', ] export const enabledFeatures: ChartingLibraryFeatureset[] = [ @@ -27,6 +26,7 @@ export const enabledFeatures: ChartingLibraryFeatureset[] = [ 'horz_touch_drag_scroll', 'vert_touch_drag_scroll', 'control_bar', + 'use_localstorage_for_settings', ] export const disabledFeaturesMobile: ChartingLibraryFeatureset[] = [ @@ -49,11 +49,11 @@ export const disabledFeaturesMobile: ChartingLibraryFeatureset[] = [ 'go_to_date', 'timeframes_toolbar', 'create_volume_indicator_by_default', - 'use_localstorage_for_settings', ] export const enabledFeaturesMobile: ChartingLibraryFeatureset[] = [ 'horz_touch_drag_scroll', 'chart_zoom', 'hide_left_toolbar_by_default', + 'use_localstorage_for_settings', ] From 69019161e7efe37e6b5167397f992b5ab3f1ef21 Mon Sep 17 00:00:00 2001 From: Monkmansteve Date: Fri, 15 Nov 2024 11:21:56 +0200 Subject: [PATCH 31/62] feature: add set stop price in tradingview context menu and fix small bugs --- src/components/common/LimitPriceInput.tsx | 3 +- .../Columns/usePerpsBalancesColumns.tsx | 8 ++-- src/components/perps/BalancesTable/index.tsx | 1 + src/components/perps/Module/PerpsModule.tsx | 10 ++-- src/components/perps/PerpsChart.tsx | 18 ++++++-- src/components/trade/TradeChart/index.tsx | 19 ++++++-- src/hooks/perps/usePerpsOrderForm.ts | 46 +++++++++++++++---- src/utils/perps.ts | 9 ++-- 8 files changed, 85 insertions(+), 29 deletions(-) diff --git a/src/components/common/LimitPriceInput.tsx b/src/components/common/LimitPriceInput.tsx index f66189744..5c1558bde 100644 --- a/src/components/common/LimitPriceInput.tsx +++ b/src/components/common/LimitPriceInput.tsx @@ -4,6 +4,7 @@ import { BNCoin } from 'types/classes/BNCoin' import DisplayCurrency from 'components/common/DisplayCurrency' import classNames from 'classnames' import { BN_ZERO } from 'constants/math' +import { getPerpsPriceDecimals } from 'utils/formatters' interface Props { label?: string @@ -48,7 +49,7 @@ export default function LimitPriceInput(props: Props) { asset={{ ...asset, decimals: 0 }} amount={inputValue} className='border-none bg-transparent outline-none flex-1 !text-left' - maxDecimals={6} + maxDecimals={getPerpsPriceDecimals(inputValue)} disabled={disabled} onChange={handleChange} onFocus={onFocus} diff --git a/src/components/perps/BalancesTable/Columns/usePerpsBalancesColumns.tsx b/src/components/perps/BalancesTable/Columns/usePerpsBalancesColumns.tsx index a35f7ee53..b4d1ac2cc 100644 --- a/src/components/perps/BalancesTable/Columns/usePerpsBalancesColumns.tsx +++ b/src/components/perps/BalancesTable/Columns/usePerpsBalancesColumns.tsx @@ -49,17 +49,18 @@ export default function usePerpsBalancesColumns(props: Props) { }, { ...SIZE_META, + id: 'size', cell: ({ row }) => { const { asset, amount, type, entryPrice } = row.original const demagnifiedAmount = BN(demagnify(amount, asset)) let value - if (type === 'limit') { + if (type === 'market') { + value = demagnifiedAmount.times(BN(asset.price?.amount || 0)) + } else { value = demagnifiedAmount .times(entryPrice) .shiftedBy(asset.decimals - PRICE_ORACLE_DECIMALS) - } else { - value = demagnifiedAmount.times(BN(asset.price?.amount || 0)) } return @@ -79,6 +80,7 @@ export default function usePerpsBalancesColumns(props: Props) { ]), { ...ENTRY_PRICE_META(isOrderTable), + id: isOrderTable ? 'triggerPrice' : 'entryPrice', cell: ({ row }) => ( [ { title: 'Perp Positions', + id: 'perp-positions', renderContent: () => (
(DEFAULT_STOP_PRICE_INFO) const isStopOrder = selectedOrderType === OrderType.STOP - const [stopPrice, setStopPrice] = useState(BN_ZERO) + + const { limitPrice, setLimitPrice, setStopPrice, orderType, stopPrice } = usePerpsOrderForm() useEffect(() => { if (!isStopOrder) { setStopPrice(BN_ZERO) } - }, [isStopOrder]) - - const { limitPrice, setLimitPrice, orderType } = usePerpsOrderForm() + }, [isStopOrder, setStopPrice]) useEffect(() => { if (orderType === 'limit') { @@ -165,6 +164,7 @@ export function PerpsModule() { [ updateAmount, setLimitPrice, + setStopPrice, simulatePerps, currentPerpPosition, isAutoLendEnabledForCurrentAccount, @@ -178,7 +178,7 @@ export function PerpsModule() { setStopPrice(BN_ZERO) setIsReduceOnly(false) }, - [updateAmount], + [updateAmount, setStopPrice], ) const onChangeAmount = useCallback( diff --git a/src/components/perps/PerpsChart.tsx b/src/components/perps/PerpsChart.tsx index 887af4bdc..fffdce47e 100644 --- a/src/components/perps/PerpsChart.tsx +++ b/src/components/perps/PerpsChart.tsx @@ -35,11 +35,12 @@ export function PerpsChart() { const { liquidationPrice } = useLiquidationPrice(liqPrice) - const { setLimitPrice, setOrderType, setSelectedOrderType } = usePerpsOrderForm() + const { setLimitPrice, setOrderType, setSelectedOrderType, setStopPrice } = usePerpsOrderForm() const onCreateLimitOrder = useCallback( - (price: number) => { - const newLimitPrice = BN(price) + (price: BigNumber) => { + const formattedPrice = price.toFixed(18, 1) + const newLimitPrice = BN(formattedPrice) setLimitPrice(newLimitPrice, true) setOrderType('limit') setSelectedOrderType(OrderType.LIMIT) @@ -47,6 +48,16 @@ export function PerpsChart() { [setLimitPrice, setOrderType, setSelectedOrderType], ) + const onCreateStopOrder = useCallback( + (price: BigNumber) => { + const formattedPrice = price.toFixed(18, 1) + setStopPrice(BN(formattedPrice), true) + setOrderType('stop') + setSelectedOrderType(OrderType.STOP) + }, + [setStopPrice, setOrderType, setSelectedOrderType], + ) + return (
) diff --git a/src/components/trade/TradeChart/index.tsx b/src/components/trade/TradeChart/index.tsx index ad27e88c8..9c61a5e4c 100644 --- a/src/components/trade/TradeChart/index.tsx +++ b/src/components/trade/TradeChart/index.tsx @@ -32,6 +32,7 @@ import { } from 'utils/charting_library' import { formatValue, getPerpsPriceDecimals, magnify } from 'utils/formatters' import { getTradingViewSettings } from 'utils/theme' +import { BN } from 'utils/helpers' interface Props { buyAsset: Asset @@ -41,7 +42,8 @@ interface Props { perpsPosition?: PerpsPosition liquidationPrice?: number limitOrders?: PerpPositionRow[] - onCreateLimitOrder?: (price: number) => void + onCreateLimitOrder?: (price: BigNumber) => void + onCreateStopOrder?: (price: BigNumber) => void } let chartWidget: IChartingLibraryWidget @@ -106,7 +108,7 @@ export default function TradeChart(props: Props) { ) const chartName = useMemo(() => getChartName(props), [props]) - const { onCreateLimitOrder, isPerps } = props + const { onCreateLimitOrder, onCreateStopOrder, isPerps } = props const [ratio, priceBuyAsset, priceSellAsset] = useMemo(() => { const priceBuyAsset = props.buyAsset?.price?.amount @@ -149,14 +151,21 @@ export default function TradeChart(props: Props) { currentChartStudyStore.forEach((studyName: string) => { chart.createStudy(studyName) }) - if (!isPerps || !onCreateLimitOrder) return + if (!isPerps || !onCreateLimitOrder || !onCreateStopOrder) return chartWidget.onContextMenu((unixTime, price) => { return [ { position: 'top', text: 'Set Limit Order Price', click: () => { - onCreateLimitOrder(price) + props.onCreateLimitOrder?.(BN(price)) + }, + }, + { + position: 'top', + text: 'Set Stop Order Price', + click: () => { + props.onCreateStopOrder?.(BN(price)) }, }, ] @@ -165,7 +174,7 @@ export default function TradeChart(props: Props) { console.info('Error on loading chart', e) return } - }, [chartName, onCreateLimitOrder, isPerps]) + }, [chartName, onCreateLimitOrder, onCreateStopOrder, isPerps]) const updateShapesAndStudies = useCallback(() => { try { diff --git a/src/hooks/perps/usePerpsOrderForm.ts b/src/hooks/perps/usePerpsOrderForm.ts index f0c8fc31d..c9f250927 100644 --- a/src/hooks/perps/usePerpsOrderForm.ts +++ b/src/hooks/perps/usePerpsOrderForm.ts @@ -4,27 +4,37 @@ import { OrderType } from 'types/enums' interface PerpsOrderFormState { limitPrice: BigNumber + stopPrice: BigNumber orderType: 'market' | 'limit' | 'stop' selectedOrderType: OrderType setLimitPrice: (price: BigNumber, fromTradingView?: boolean) => void - setOrderType: (type: 'market' | 'limit') => void + setStopPrice: (price: BigNumber, fromTradingView?: boolean) => void + setOrderType: (type: 'market' | 'limit' | 'stop') => void + setSelectedOrderType: (type: OrderType) => void +} + +interface PerpsOrderFormState { + limitPrice: BigNumber + stopPrice: BigNumber + orderType: 'market' | 'limit' | 'stop' + selectedOrderType: OrderType + setLimitPrice: (price: BigNumber, fromTradingView?: boolean) => void + setStopPrice: (price: BigNumber, fromTradingView?: boolean) => void + setOrderType: (type: 'market' | 'limit' | 'stop') => void setSelectedOrderType: (type: OrderType) => void } export const usePerpsOrderForm = create((set) => ({ limitPrice: new BigNumber(0), + stopPrice: new BigNumber(0), orderType: 'market', selectedOrderType: OrderType.MARKET, setLimitPrice: (price, fromTradingView = false) => { if (fromTradingView) { set({ limitPrice: price, - ...(fromTradingView - ? { - orderType: 'limit', - selectedOrderType: OrderType.LIMIT, - } - : {}), + orderType: 'limit', + selectedOrderType: OrderType.LIMIT, }) } else { set({ @@ -32,12 +42,30 @@ export const usePerpsOrderForm = create((set) => ({ }) } }, + setStopPrice: (price, fromTradingView = false) => { + if (fromTradingView) { + set({ + stopPrice: price, + orderType: 'stop', + selectedOrderType: OrderType.STOP, + }) + } else { + set({ + stopPrice: price, + }) + } + }, setOrderType: (type) => set({ orderType: type }), setSelectedOrderType: (type) => { set((state) => ({ selectedOrderType: type, - orderType: type === OrderType.MARKET ? 'market' : 'limit', - ...(type === OrderType.MARKET ? { limitPrice: new BigNumber(0) } : {}), + orderType: type === OrderType.MARKET ? 'market' : type === OrderType.LIMIT ? 'limit' : 'stop', + ...(type === OrderType.MARKET + ? { + limitPrice: new BigNumber(0), + stopPrice: new BigNumber(0), + } + : {}), })) }, })) diff --git a/src/utils/perps.ts b/src/utils/perps.ts index a707ea6c9..7bf0dffea 100644 --- a/src/utils/perps.ts +++ b/src/utils/perps.ts @@ -103,19 +103,22 @@ export const validateStopOrderPrice = ( currentPrice: BigNumber, tradeDirection: TradeDirection, ): { isValid: boolean; errorMessage: string | null } => { - if (stopPrice.isZero() || currentPrice.isZero()) { + const formattedStopPrice = BN(stopPrice.toFixed(18, 1)) + const formattedCurrentPrice = BN(currentPrice.toFixed(18, 1)) + + if (formattedStopPrice.isZero() || formattedCurrentPrice.isZero()) { return { isValid: false, errorMessage: null } } if (tradeDirection === 'long') { - if (stopPrice.isLessThanOrEqualTo(currentPrice)) { + if (formattedStopPrice.isLessThanOrEqualTo(formattedCurrentPrice)) { return { isValid: false, errorMessage: 'Stop price must be below current price for long positions', } } } else { - if (stopPrice.isGreaterThanOrEqualTo(currentPrice)) { + if (formattedStopPrice.isGreaterThanOrEqualTo(formattedCurrentPrice)) { return { isValid: false, errorMessage: 'Stop price must be above current price for short positions', From 506b9b1a9aa49f60d0578b61cb2432702acb078f Mon Sep 17 00:00:00 2001 From: Monkmansteve Date: Fri, 15 Nov 2024 11:52:00 +0200 Subject: [PATCH 32/62] fix: set maxDecimals to 18 in LimitPriceInput component --- src/components/common/LimitPriceInput.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/common/LimitPriceInput.tsx b/src/components/common/LimitPriceInput.tsx index 5c1558bde..8196d9df0 100644 --- a/src/components/common/LimitPriceInput.tsx +++ b/src/components/common/LimitPriceInput.tsx @@ -49,7 +49,7 @@ export default function LimitPriceInput(props: Props) { asset={{ ...asset, decimals: 0 }} amount={inputValue} className='border-none bg-transparent outline-none flex-1 !text-left' - maxDecimals={getPerpsPriceDecimals(inputValue)} + maxDecimals={18} disabled={disabled} onChange={handleChange} onFocus={onFocus} From 79776715ca1c0005ce2b852695c5b7a8509defd2 Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Mon, 18 Nov 2024 08:11:58 +0100 Subject: [PATCH 33/62] feat: incentivized testnet contracts --- src/chains/neutron/pion-1.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/chains/neutron/pion-1.ts b/src/chains/neutron/pion-1.ts index b4e042e27..7bc082ce6 100644 --- a/src/chains/neutron/pion-1.ts +++ b/src/chains/neutron/pion-1.ts @@ -13,13 +13,13 @@ const Pion1: ChainConfig = { sell: 'factory/neutron1ke0vqqzyymlp5esr8gjwuzh94ysnpvj8er5hm7/UUSDC', }, contracts: { - redBank: 'neutron1vxvqs075q7y9tvpmt60xjmejrfvuw8mcvgqkug67des96y7psalqrl4cn6', - incentives: 'neutron10a4rt7utgqrpf24jeluc2gt42r83f0ammxnmntq687ycwh7ugysqnfwduy', - oracle: 'neutron13a7vspwpf3vnjq292xsvk8l8y0r7uwn4vtaev04zyl7r0wu8slzsveq09g', - params: 'neutron13pwuvh2kwlvs9q4cm9yfm5xymghle066hq40m2yagg6sh7c09ncqzey946', - creditManager: 'neutron13jm8hk5znqk5t5mlvgphvfea300kayqhhy8hdhmrdtsfypkl7ehqke4d2m', - accountNft: 'neutron1l9vthzck3t7z2ys943jwaxskkjaws3qexhyuhsytqpx8t9ht6lyq4tre4d', - perps: 'neutron1ey5vc5yvlauea7aryuvuxphxvr473ayjxw7h30eq62s4uzcjsx4qsvnfxs', + redBank: 'neutron19ucpt6vyha2k6tgnex880sladcqsguwynst4f8krh9vuxhktwkvq3yc3nl', + incentives: 'neutron1xqfgy03gulfyv6dnz9ezsjkgcvsvlaajskw35cluux9g05cmcu4sfdkuvc', + oracle: 'neutron12vejgch3jd74j99kdrpjf57f6zjlu425yyfscdjnmnn4vvyrazvqgvcp24', + params: 'neutron14a0qr0ahrg3f3yml06m9f0xmvw30ldf3scgashcjw5mrtyrc4aaq0v4tm9', + creditManager: 'neutron1zkxezh5e6jvg0h3kj50hz5d0yrgagkp0c3gcdr6stulw7fye9xlqygj2gz', + accountNft: 'neutron1pgk4ttz3ned9xvqlg79f4jumjet0443uqh2rga9ahalzgxqngtrqrszdna', + perps: 'neutron1dcv8sy6mhgjaum5tj8lghxgxx2jgf3gmcw6kg73rj70sx5sjpguslzv0xu', pyth: 'neutron15ldst8t80982akgr8w8ekcytejzkmfpgdkeq4xgtge48qs7435jqp87u3t', }, endpoints: { From 4a66f94cd35b994c0a87f40e0e1350916795273b Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Mon, 18 Nov 2024 09:31:15 +0100 Subject: [PATCH 34/62] feat: added DAODAO to mobile --- src/components/Wallet/WalletConnectProvider.tsx | 4 ++++ src/components/Wallet/WalletSelect.tsx | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/Wallet/WalletConnectProvider.tsx b/src/components/Wallet/WalletConnectProvider.tsx index 3d13dfa8e..50001b9fc 100644 --- a/src/components/Wallet/WalletConnectProvider.tsx +++ b/src/components/Wallet/WalletConnectProvider.tsx @@ -66,6 +66,10 @@ const mobileProviders: WalletMobileProvider[] = [ new CosmostationMobileProvider({ networks: getSupportedChainsInfos(WalletID.CosmostationMobile), }), + new CosmiframeExtensionProvider({ + allowedParentOrigins: DAODAO_ORIGINS, + networks: getSupportedChainsInfos(WalletID.DaoDao), + }) as any, ] const extensionProviders: WalletExtensionProvider[] = [ diff --git a/src/components/Wallet/WalletSelect.tsx b/src/components/Wallet/WalletSelect.tsx index abac0a932..328f73984 100644 --- a/src/components/Wallet/WalletSelect.tsx +++ b/src/components/Wallet/WalletSelect.tsx @@ -15,7 +15,6 @@ import useChainConfig from 'hooks/chain/useChainConfig' import useCurrentWallet from 'hooks/wallet/useCurrentWallet' import useStore from 'store' import { WalletID } from 'types/enums' -import { setNodeError } from 'utils/error' import { isAndroid, isIOS } from 'utils/mobile' interface Props { @@ -60,7 +59,6 @@ export default function WalletSelect(props: Props) { const { extensionProviders, mobileProviders, mobileConnect } = useShuttle() const [qrCodeUrl, setQRCodeUrl] = useState('') const [error, setError] = useState(props.error) - const errorStore = useStore((s) => s.errorStore) const [isLoading, setIsLoading] = useState(false) const recentWallet = useCurrentWallet() const handleConnectClick = (extensionProviderId: string) => { From 080efc84ff815e6fd5fa959eff31f58b790577eb Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Mon, 18 Nov 2024 13:21:42 +0100 Subject: [PATCH 35/62] fix: daodao mobile --- src/components/Wallet/WalletSelect.tsx | 72 ++++++++++++++------------ 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/src/components/Wallet/WalletSelect.tsx b/src/components/Wallet/WalletSelect.tsx index 328f73984..523769b09 100644 --- a/src/components/Wallet/WalletSelect.tsx +++ b/src/components/Wallet/WalletSelect.tsx @@ -1,7 +1,7 @@ import { useShuttle } from '@delphi-labs/shuttle-react' import moment from 'moment' import Image from 'next/image' -import React, { useEffect, useState } from 'react' +import React, { useEffect, useMemo, useState } from 'react' import { isMobile } from 'react-device-detect' import QRCode from 'react-qr-code' @@ -150,6 +150,11 @@ export default function WalletSelect(props: Props) { } }, [error?.message, error?.title]) + const filteredMobileProviders = useMemo( + () => (isDaodaoIframe ? sortedExtensionProviders : mobileProviders), + [isDaodaoIframe, mobileProviders, sortedExtensionProviders], + ) + if (qrCodeUrl) return ( )} - {!isDaodaoIframe && - mobileProviders.map((provider) => { - const walletId = provider.id as WalletID - return ( - - {Array.from(provider.networks.values()) - .filter((network) => network.chainId === chainConfig.id) - .map((network) => { - return ( - - isKeplrMobileInApp - ? handleConnectClick(walletId.replace('mobile-', '')) - : handleMobileConnectClick(walletId, network.chainId) - } - showLoader={isLoading === walletId} - /> - ) - })} - - ) - })} + {filteredMobileProviders.map((provider) => { + const walletId = provider.id as WalletID + return ( + + {Array.from(provider.networks.values()) + .filter((network) => network.chainId === chainConfig.id) + .map((network) => { + return ( + + isKeplrMobileInApp + ? handleConnectClick(walletId.replace('mobile-', '')) + : handleMobileConnectClick(walletId, network.chainId) + } + showLoader={isLoading === walletId} + /> + ) + })} + + ) + })} ) From 3e1a8ff11bbf8c78bd705c19838cc76738120cb5 Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Mon, 18 Nov 2024 13:48:55 +0100 Subject: [PATCH 36/62] fix: simplify DAODAO logic --- src/components/Wallet/WalletSelect.tsx | 75 +++++++++++++------------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/src/components/Wallet/WalletSelect.tsx b/src/components/Wallet/WalletSelect.tsx index 523769b09..8ba9ef571 100644 --- a/src/components/Wallet/WalletSelect.tsx +++ b/src/components/Wallet/WalletSelect.tsx @@ -1,7 +1,7 @@ import { useShuttle } from '@delphi-labs/shuttle-react' import moment from 'moment' import Image from 'next/image' -import React, { useEffect, useMemo, useState } from 'react' +import React, { useEffect, useState } from 'react' import { isMobile } from 'react-device-detect' import QRCode from 'react-qr-code' @@ -150,11 +150,6 @@ export default function WalletSelect(props: Props) { } }, [error?.message, error?.title]) - const filteredMobileProviders = useMemo( - () => (isDaodaoIframe ? sortedExtensionProviders : mobileProviders), - [isDaodaoIframe, mobileProviders, sortedExtensionProviders], - ) - if (qrCodeUrl) return (
- {!isMobile && ( + {!isMobile && !isDaodaoIframe && ( <> {sortedExtensionProviders.map((provider) => { const walletId = provider.id as WalletID @@ -219,38 +214,40 @@ export default function WalletSelect(props: Props) { })} )} - {filteredMobileProviders.map((provider) => { - const walletId = provider.id as WalletID - return ( - - {Array.from(provider.networks.values()) - .filter((network) => network.chainId === chainConfig.id) - .map((network) => { - return ( - - isKeplrMobileInApp - ? handleConnectClick(walletId.replace('mobile-', '')) - : handleMobileConnectClick(walletId, network.chainId) - } - showLoader={isLoading === walletId} - /> - ) - })} - - ) - })} + {!isDaodaoIframe && + isMobile && + mobileProviders.map((provider) => { + const walletId = provider.id as WalletID + return ( + + {Array.from(provider.networks.values()) + .filter((network) => network.chainId === chainConfig.id) + .map((network) => { + return ( + + isKeplrMobileInApp + ? handleConnectClick(walletId.replace('mobile-', '')) + : handleMobileConnectClick(walletId, network.chainId) + } + showLoader={isLoading === walletId} + /> + ) + })} + + ) + })}
) From 7c5aa57f355cfe447de0a3968e00453c75bd1673 Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Mon, 18 Nov 2024 13:55:48 +0100 Subject: [PATCH 37/62] fix: DAO DAO implementation --- src/components/Wallet/WalletSelect.tsx | 73 +++++++++++++------------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/src/components/Wallet/WalletSelect.tsx b/src/components/Wallet/WalletSelect.tsx index 8ba9ef571..2c4c315d1 100644 --- a/src/components/Wallet/WalletSelect.tsx +++ b/src/components/Wallet/WalletSelect.tsx @@ -1,7 +1,7 @@ import { useShuttle } from '@delphi-labs/shuttle-react' import moment from 'moment' import Image from 'next/image' -import React, { useEffect, useState } from 'react' +import React, { useEffect, useMemo, useState } from 'react' import { isMobile } from 'react-device-detect' import QRCode from 'react-qr-code' @@ -150,6 +150,8 @@ export default function WalletSelect(props: Props) { } }, [error?.message, error?.title]) + const showMobileWallets = useMemo(() => isMobile && !isDaodaoIframe, [isDaodaoIframe]) + if (qrCodeUrl) return (
- {!isMobile && !isDaodaoIframe && ( + {showMobileWallets ? ( + mobileProviders.map((provider) => { + const walletId = provider.id as WalletID + return ( + + {Array.from(provider.networks.values()) + .filter((network) => network.chainId === chainConfig.id) + .map((network) => { + return ( + + isKeplrMobileInApp + ? handleConnectClick(walletId.replace('mobile-', '')) + : handleMobileConnectClick(walletId, network.chainId) + } + showLoader={isLoading === walletId} + /> + ) + })} + + ) + }) + ) : ( <> {sortedExtensionProviders.map((provider) => { const walletId = provider.id as WalletID @@ -214,40 +249,6 @@ export default function WalletSelect(props: Props) { })} )} - {!isDaodaoIframe && - isMobile && - mobileProviders.map((provider) => { - const walletId = provider.id as WalletID - return ( - - {Array.from(provider.networks.values()) - .filter((network) => network.chainId === chainConfig.id) - .map((network) => { - return ( - - isKeplrMobileInApp - ? handleConnectClick(walletId.replace('mobile-', '')) - : handleMobileConnectClick(walletId, network.chainId) - } - showLoader={isLoading === walletId} - /> - ) - })} - - ) - })}
) From 55fdfb012577125d6cd6c1004a7b968169325f13 Mon Sep 17 00:00:00 2001 From: Monkmansteve Date: Mon, 25 Nov 2024 19:01:43 +0200 Subject: [PATCH 38/62] feature: update code owners, format max amount to number before passing to formatValue function --- .github/CODEOWNERS | 2 +- src/components/common/AssetAmountInput.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0fccc2b1e..7f93d365f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @bobthebuidlr @linkielink @Patricie29 @StefChatz \ No newline at end of file +* @linkielink @Patricie29 @StefChatz \ No newline at end of file diff --git a/src/components/common/AssetAmountInput.tsx b/src/components/common/AssetAmountInput.tsx index c8755fab6..bedc2279a 100644 --- a/src/components/common/AssetAmountInput.tsx +++ b/src/components/common/AssetAmountInput.tsx @@ -109,7 +109,7 @@ export default function AssetAmountInput(props: Props) {
{maxButtonLabel ?? 'Max:'} - {formatValue(maxValue, { abbreviated: false })} + {formatValue(Number(maxValue), { abbreviated: false })}
Date: Tue, 26 Nov 2024 18:12:34 +0200 Subject: [PATCH 39/62] feature: add keeper fee decimals correctly, add skew and perps markets without account --- src/components/common/AssetAmountInput.tsx | 6 +--- src/components/perps/PerpsInfo/Skew.tsx | 28 +++++++++++++++++++ src/components/perps/PerpsInfo/index.tsx | 2 ++ .../AssetSelector/AssetOverlay/index.tsx | 5 ++-- src/hooks/perps/usePerpsMarket.ts | 14 ++++++++-- src/types/app.d.ts | 4 +-- 6 files changed, 46 insertions(+), 13 deletions(-) create mode 100644 src/components/perps/PerpsInfo/Skew.tsx diff --git a/src/components/common/AssetAmountInput.tsx b/src/components/common/AssetAmountInput.tsx index bedc2279a..8d5c528b3 100644 --- a/src/components/common/AssetAmountInput.tsx +++ b/src/components/common/AssetAmountInput.tsx @@ -58,10 +58,6 @@ export default function AssetAmountInput(props: Props) { return val.isGreaterThan(1) ? val.toFixed(2) : val.toPrecision(2) }, [asset.decimals, max]) - useEffect(() => { - asset.decimals = isUSD ? 0 : asset.decimals - }, [asset, isUSD]) - useEffect(() => { if (!disabled) return setAmount(BN_ZERO) @@ -87,7 +83,7 @@ export default function AssetAmountInput(props: Props) { asset={asset} amount={amount} className='border-none bg-transparent outline-none flex-1 !text-left' - maxDecimals={isUSD ? 6 : asset.decimals} + maxDecimals={isUSD ? 3 : asset.decimals} // Set maxDecimals to 3 for USD max={capMax ? max : undefined} min={min} disabled={disabled} diff --git a/src/components/perps/PerpsInfo/Skew.tsx b/src/components/perps/PerpsInfo/Skew.tsx new file mode 100644 index 000000000..1ecdfdd17 --- /dev/null +++ b/src/components/perps/PerpsInfo/Skew.tsx @@ -0,0 +1,28 @@ +import DisplayCurrency from 'components/common/DisplayCurrency' +import { FormattedNumber } from 'components/common/FormattedNumber' +import usePerpsMarket from 'hooks/perps/usePerpsMarket' +import { BNCoin } from 'types/classes/BNCoin' + +export default function Skew() { + const perpsMarket = usePerpsMarket() + + if (!perpsMarket) return null + + const { openInterest } = perpsMarket + const totalOI = openInterest.total + + return ( +
+ + / + +
+ ) +} diff --git a/src/components/perps/PerpsInfo/index.tsx b/src/components/perps/PerpsInfo/index.tsx index 1a9b78e8f..f7001e499 100644 --- a/src/components/perps/PerpsInfo/index.tsx +++ b/src/components/perps/PerpsInfo/index.tsx @@ -6,6 +6,7 @@ import Text from 'components/common/Text' import FundingRate from 'components/perps/PerpsInfo/FundingRate' import usePerpsMarket from 'hooks/perps/usePerpsMarket' import { BNCoin } from 'types/classes/BNCoin' +import Skew from './Skew' export function PerpsInfo() { const market = usePerpsMarket() @@ -34,6 +35,7 @@ export function PerpsInfo() { /> } />, + } />, } />, ] }, [market]) diff --git a/src/components/trade/TradeModule/AssetSelector/AssetOverlay/index.tsx b/src/components/trade/TradeModule/AssetSelector/AssetOverlay/index.tsx index d1229c37b..3cc935b64 100644 --- a/src/components/trade/TradeModule/AssetSelector/AssetOverlay/index.tsx +++ b/src/components/trade/TradeModule/AssetSelector/AssetOverlay/index.tsx @@ -90,11 +90,10 @@ export default function AssetOverlay(props: Props) { }, [onChangeSearch, props], ) - const [activePerpsPositions, availablePerpsMarkets] = useMemo(() => { - if (!account) return [[], []] + if (!account) return [[], assets] const activePerpsPositions = assets.filter((assets) => - account?.perps?.find((perp) => perp.denom === assets.denom), + account.perps?.find((perp) => perp.denom === assets.denom), ) const availablePerpsMarkets = assets.filter( (assets) => !activePerpsPositions.find((perp) => perp.denom === assets.denom), diff --git a/src/hooks/perps/usePerpsMarket.ts b/src/hooks/perps/usePerpsMarket.ts index db9a47633..33edb6b1c 100644 --- a/src/hooks/perps/usePerpsMarket.ts +++ b/src/hooks/perps/usePerpsMarket.ts @@ -6,18 +6,26 @@ import { BN } from 'utils/helpers' export default function usePerpsMarket() { const { perpsAsset } = usePerpsAsset() - const perpsMarketState = usePerpsMarketState() return useMemo(() => { if (!perpsMarketState) return null + + const longOI = BN(perpsMarketState.long_oi) + const shortOI = BN(perpsMarketState.short_oi) + const totalOI = longOI.plus(shortOI) + + const skewPercentage = totalOI.isZero() ? BN(0) : longOI.minus(shortOI).div(totalOI).times(100) + return { // Funding rate is per 24h fundingRate: BN(perpsMarketState.current_funding_rate as any).times(100), asset: perpsAsset, openInterest: { - long: BN(perpsMarketState.long_oi), - short: BN(perpsMarketState.short_oi), + long: longOI, + short: shortOI, + total: totalOI, + skewPercentage: skewPercentage, }, } as PerpsMarket }, [perpsAsset, perpsMarketState]) diff --git a/src/types/app.d.ts b/src/types/app.d.ts index e70dd396b..87af8e5cc 100644 --- a/src/types/app.d.ts +++ b/src/types/app.d.ts @@ -216,6 +216,8 @@ interface PerpsMarket { openInterest: { long: BigNumber short: BigNumber + total: BigNumber + skewPercentage: BigNumber } } @@ -338,7 +340,6 @@ interface PerpsPosition { currentPrice: BigNumber entryPrice: BigNumber type: PositionType - reduce_only?: boolean } interface PerpsLimitOrder { @@ -355,7 +356,6 @@ interface PerpPositionRow extends PerpsPosition { orderId?: string hasStopLoss?: boolean hasTakeProfit?: boolean - reduce_only?: boolean } interface PerpsPnL { From 9bd15c5e3d5607cf7dd1cb1093b28df1d51db76f Mon Sep 17 00:00:00 2001 From: Monkmansteve Date: Tue, 26 Nov 2024 18:18:04 +0200 Subject: [PATCH 40/62] feature: add removed type --- src/types/app.d.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/types/app.d.ts b/src/types/app.d.ts index 87af8e5cc..4f3942e16 100644 --- a/src/types/app.d.ts +++ b/src/types/app.d.ts @@ -340,6 +340,7 @@ interface PerpsPosition { currentPrice: BigNumber entryPrice: BigNumber type: PositionType + reduce_only?: boolean } interface PerpsLimitOrder { @@ -356,6 +357,7 @@ interface PerpPositionRow extends PerpsPosition { orderId?: string hasStopLoss?: boolean hasTakeProfit?: boolean + reduce_only?: boolean } interface PerpsPnL { From cdcf6826fee524a141f583fd1f095638b836f638 Mon Sep 17 00:00:00 2001 From: Monkmansteve Date: Tue, 26 Nov 2024 20:19:57 +0200 Subject: [PATCH 41/62] feature: add correct decimals on modal --- src/components/Modals/KeeperFeeModal.tsx | 20 +++++++++++--------- src/components/common/AssetAmountInput.tsx | 2 +- src/components/perps/Module/KeeperFee.tsx | 6 +++++- src/constants/defaultSettings.ts | 4 ++-- src/constants/math.ts | 1 - 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/components/Modals/KeeperFeeModal.tsx b/src/components/Modals/KeeperFeeModal.tsx index e72f4b847..bb6fa501f 100644 --- a/src/components/Modals/KeeperFeeModal.tsx +++ b/src/components/Modals/KeeperFeeModal.tsx @@ -8,12 +8,10 @@ import { Callout, CalloutType } from 'components/common/Callout' import Text from 'components/common/Text' import { getDefaultChainSettings } from 'constants/defaultSettings' import { LocalStorageKeys } from 'constants/localStorageKeys' -import { BN_ZERO_ONE } from 'constants/math' import useAsset from 'hooks/assets/useAsset' import useChainConfig from 'hooks/chain/useChainConfig' import useLocalStorage from 'hooks/localStorage/useLocalStorage' import useStore from 'store' -import { magnify } from 'utils/formatters' import { BN } from 'utils/helpers' export default function KeeperFeeModal() { @@ -24,7 +22,6 @@ export default function KeeperFeeModal() { ) const [amount, setAmount] = useState(BN(keeperFee.amount)) const USD = useAsset('usd') - const onClose = useCallback(() => { useStore.setState({ keeperFeeModal: false }) }, []) @@ -34,14 +31,19 @@ export default function KeeperFeeModal() { }, [keeperFee]) const handleActionClick = () => { - setKeeperFee({ denom: keeperFee.denom, amount: amount.toString() }) + if (!USD) return + + setKeeperFee({ + denom: keeperFee.denom, + amount: amount.toString(), + }) onClose() } const onUpdateAmount = useCallback( - (amount: BigNumber) => { + (newAmount: BigNumber) => { if (!USD) return - setAmount(magnify(amount.toString(), USD)) + setAmount(newAmount) }, [USD], ) @@ -71,9 +73,9 @@ export default function KeeperFeeModal() { asset={USD} isUSD /> - {amount.isLessThan(BN_ZERO_ONE) && ( + {amount.isLessThan(100) && ( - You can not set the Keeper Fee to less than $0.10 as it is the minimum amount for the + You can not set the Keeper Fee to less than $1.00 as it is the minimum amount for the Keeper Fee. )} @@ -84,7 +86,7 @@ export default function KeeperFeeModal() {
diff --git a/src/utils/helpers.ts b/src/utils/helpers.ts index 7aefd2aaf..be5f3e0e6 100644 --- a/src/utils/helpers.ts +++ b/src/utils/helpers.ts @@ -47,6 +47,35 @@ export function mergeBNCoinArrays(array1: BNCoin[], array2: BNCoin[]) { return merged } +export function mergePerpsVaults(perpVaults: (PerpsVaultPositions | null)[]) { + const merged: PerpsVaultPositions = { + active: { + amount: BN_ZERO, + shares: BN_ZERO, + }, + denom: '', + unlocked: BN_ZERO, + unlocking: [] as PerpsVaultUnlockingPosition[], + } + + perpVaults.forEach((vault) => { + if (!vault || !merged) return + if (merged.active && vault.active) { + merged.active.amount = merged.active.amount.plus(vault.active.amount) + merged.active.shares = merged.active.shares.plus(vault.active.shares) + } + if (merged.unlocked && vault.unlocked) { + merged.unlocked = merged.unlocked.plus(vault.unlocked) + } + vault.unlocking.forEach((unlocking) => { + merged.unlocking.push(unlocking) + }) + merged.denom = vault.denom + }) + + return merged +} + export function getValueFromBNCoins(coins: BNCoin[], assets: Asset[]): BigNumber { let totalValue = BN_ZERO From 8ede482055b0cebfdacc6b00d68bd5f34d30206c Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Mon, 2 Dec 2024 10:33:09 +0100 Subject: [PATCH 61/62] env: updated endpoints --- src/chains/neutron/neutron-1.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/chains/neutron/neutron-1.ts b/src/chains/neutron/neutron-1.ts index b800753b1..e8d9e9d7f 100644 --- a/src/chains/neutron/neutron-1.ts +++ b/src/chains/neutron/neutron-1.ts @@ -79,9 +79,9 @@ const Neutron1: ChainConfig = { }, endpoints: { routes: 'https://app.astroport.fi/api/routes', - rpc: process.env.NEXT_PUBLIC_NEUTRON_RPC ?? 'https://rpc-kralum.neutron-1.neutron.org', - fallbackRpc: 'https://rpc.novel.remedy.tm.p2p.org', - rest: process.env.NEXT_PUBLIC_NEUTRON_REST ?? 'https://rest-kralum.neutron-1.neutron.org', + rpc: process.env.NEXT_PUBLIC_NEUTRON_RPC ?? 'https://rpc-lb.neutron.org', + fallbackRpc: 'https://neutron-rpc.cosmos-apis.com', + rest: process.env.NEXT_PUBLIC_NEUTRON_REST ?? 'https://rest-lb.neutron.org', swap: 'https://neutron.astroport.fi/swap', explorer: 'https://mintscan.io/neutron', dexAssets: 'https://neutron-cache-api.onrender.com/neutron-1/tokens', From 4b898ebf89ddc1ad3597da6b8cb54d18bb13a319 Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Mon, 2 Dec 2024 10:38:55 +0100 Subject: [PATCH 62/62] tidy: refactor --- src/components/common/Banner.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/common/Banner.tsx b/src/components/common/Banner.tsx index 2efc2c008..7b11a9cb7 100644 --- a/src/components/common/Banner.tsx +++ b/src/components/common/Banner.tsx @@ -1,9 +1,9 @@ import classNames from 'classnames' import AssetImage from 'components/common/assets/AssetImage' import Button from 'components/common/Button' +import { Cross } from 'components/common/Icons' import Text from 'components/common/Text' import React from 'react' -import { Cross } from './Icons' interface Props { asset?: Asset