Skip to content

Commit

Permalink
Futures refactor (Kwenta#1702)
Browse files Browse the repository at this point in the history
* Futures refactor continued

* Refactor isolated margin transfer actions

* Refactor balances

* Refactor futures data polling

* Refactor orders and cross margin settings queries

* Multicall contract updates

* get positions by account type

* fetch all positions when provider ready

* fix initial position fetch

* Simplify polling pattern

* use market keys to index (Kwenta#1712)

use market keys to index

* Refactor isolated margin actions

* Move close isolated margin position to sdk and redux

* Refactor trade previews

* Fix cross margin leverage

* Improve cross margin preview speed

* Refactor trade inputs

* Fix shorts and dashboard orders count

* Futures refactor continued

* fix trade preview on position side change

* Clean up

* Update state/balances/selectors.ts

Co-authored-by: troyb.eth <me@troyb.xyz>

Co-authored-by: Troy <troy.burmeister@gmail.com>
Co-authored-by: troyb.eth <me@troyb.xyz>
  • Loading branch information
3 people authored Dec 12, 2022
1 parent 7d81864 commit f17b592
Show file tree
Hide file tree
Showing 119 changed files with 4,123 additions and 3,615 deletions.
4 changes: 4 additions & 0 deletions components/Loader/Loader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,8 @@ export const MiniLoader = () => {
return <Loader inline height="11px" width="11px" style={{ marginLeft: '10px' }} />;
};

export const ButtonLoader = () => {
return <Loader inline height="20x" width="20px" />;
};

export default Loader;
4 changes: 2 additions & 2 deletions components/TVChart/TVChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { ThemeContext } from 'styled-components';
import { chain } from 'wagmi';

import Connector from 'containers/Connector';
import { FuturesOrder } from 'queries/futures/types';
import { FuturesOrder } from 'sdk/types/futures';
import { ChartBody } from 'sections/exchange/TradeCard/Charts/common/styles';
import { currentThemeState } from 'store/ui';
import darkTheme from 'styles/theme/colors/dark';
Expand Down Expand Up @@ -88,9 +88,9 @@ export function TVChart({
};

const renderOrderLines = () => {
clearOrderLines();
_widget.current?.onChartReady(() => {
_widget.current?.chart().dataReady(() => {
clearOrderLines();
_oderLineRefs.current = openOrders.reduce<IPositionLineAdapter[]>((acc, order) => {
if (order.targetPrice) {
const color =
Expand Down
40 changes: 0 additions & 40 deletions constants/queryKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,6 @@ export const QUERY_KEYS = {
networkId,
currencyKey,
],
Markets: (networkId: NetworkId) => ['futures', 'marketsSummaries', networkId],
Market: (networkId: NetworkId, currencyKey: string | null) => [
'futures',
currencyKey,
Expand Down Expand Up @@ -215,46 +214,14 @@ export const QUERY_KEYS = {
networkId,
currencyKey,
],
FundingRates: (
networkId: NetworkId,
periodLength: number,
marketAssets: FuturesMarketAsset[]
) => ['futures', 'fundingRates', networkId, periodLength, marketAssets],
TradingVolumeForAll: (networkId: NetworkId) => ['futures', 'tradingVolumeForAll', networkId],
AllPositionHistory: (networkId: NetworkId, walletAddress: string) => [
'futures',
'allPositionHistory',
networkId,
walletAddress,
],
Position: (networkId: NetworkId, market: string | null, walletAddress: string) => [
'futures',
'position',
networkId,
market,
walletAddress,
],
MarketsPositions: (
networkId: NetworkId,
markets: string[] | [],
walletAddress: string,
crossMarginAddress: string
) => ['futures', 'marketsPositions', networkId, markets, walletAddress, crossMarginAddress],
Portfolio: (
networkId: NetworkId,
markets: string[] | [],
walletAddress: string | null,
crossMarginAddress: string | null,
freeMargin: number
) => [
'futures',
'positions',
networkId,
markets,
walletAddress,
crossMarginAddress,
freeMargin,
],
PositionHistory: (walletAddress: string | null, networkId: NetworkId) => [
'futures',
'accountPositions',
Expand Down Expand Up @@ -318,13 +285,6 @@ export const QUERY_KEYS = {
currencyKey: string | null
) => ['futures', 'currentRoundId', networkId, walletAddress, currencyKey],
OverviewStats: (networkId: NetworkId) => ['futures', 'overview-stats', networkId],
CrossMarginAccountOverview: (networkId: NetworkId, wallet: string, retryCount: number) => [
'futures',
'cross-margin-account-overview',
networkId,
wallet,
retryCount,
],
CrossMarginSettings: (networkId: NetworkId, settingsAddress: string) => [
'futures',
'cross-margin-settings',
Expand Down
2 changes: 1 addition & 1 deletion containers/Connector/Connector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const useConnector = () => {
setProviderReady(true);
});
transactionNotifier = new BaseTN(provider);
}, [provider, dispatch, handleNetworkChange]);
}, [provider, handleNetworkChange]);

useEffect(() => {
handleNetworkChange(network.id as NetworkId);
Expand Down
124 changes: 25 additions & 99 deletions contexts/RefetchContext.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import React, { useEffect } from 'react';
import { useRecoilValue, useSetRecoilState } from 'recoil';
import React from 'react';
import { useRecoilValue } from 'recoil';

import useGetAverageFundingRateForMarkets from 'queries/futures/useGetAverageFundingRateForMarkets';
import useGetCrossMarginAccountOverview from 'queries/futures/useGetCrossMarginAccountOverview';
import useGetCrossMarginSettings from 'queries/futures/useGetCrossMarginSettings';
import useGetFuturesOpenOrders from 'queries/futures/useGetFuturesOpenOrders';
import useGetFuturesPositionForMarket from 'queries/futures/useGetFuturesPositionForMarket';
import useGetFuturesPositionForMarkets from 'queries/futures/useGetFuturesPositionForMarkets';
import useGetFuturesPositionHistory from 'queries/futures/useGetFuturesPositionHistory';
import useGetFuturesVolumes from 'queries/futures/useGetFuturesVolumes';
import useQueryCrossMarginAccount from 'queries/futures/useQueryCrossMarginAccount';
import useLaggedDailyPrice from 'queries/rates/useLaggedDailyPrice';
import useSynthBalances from 'queries/synths/useSynthBalances';
import { Period } from 'sdk/constants/period';
import { futuresAccountState, futuresAccountTypeState, positionState } from 'store/futures';
import logError from 'utils/logError';
import { fetchBalances } from 'state/balances/actions';
import {
fetchCrossMarginBalanceInfo,
fetchFuturesPositionsForType,
fetchOpenOrders,
} from 'state/futures/actions';
import { selectFuturesType } from 'state/futures/selectors';
import { useAppDispatch, useAppSelector } from 'state/hooks';
import { futuresAccountState } from 'store/futures';
import { refetchWithComparator } from 'utils/queries';

type RefetchType =
| 'modify-position'
Expand All @@ -24,10 +23,7 @@ type RefetchType =
| 'account-margin-change'
| 'cross-margin-account-change';

type RefetchUntilType =
| 'wallet-balance-change'
| 'cross-margin-account-change'
| 'account-margin-change';
type RefetchUntilType = 'cross-margin-account-change';

type RefetchContextType = {
handleRefetch: (refetchType: RefetchType, timeout?: number) => void;
Expand All @@ -40,60 +36,42 @@ const RefetchContext = React.createContext<RefetchContextType>({
});

export const RefetchProvider: React.FC = ({ children }) => {
const selectedAccountType = useRecoilValue(futuresAccountTypeState);
const selectedAccountType = useAppSelector(selectFuturesType);
const { crossMarginAddress } = useRecoilValue(futuresAccountState);
const setPosition = useSetRecoilState(positionState);
const dispatch = useAppDispatch();

const synthsBalancesQuery = useSynthBalances();
const openOrdersQuery = useGetFuturesOpenOrders();
const positionQuery = useGetFuturesPositionForMarket();
const crossMarginAccountOverview = useGetCrossMarginAccountOverview();
const positionsQuery = useGetFuturesPositionForMarkets();
const positionHistoryQuery = useGetFuturesPositionHistory();
const queryCrossMarginAccount = useQueryCrossMarginAccount();

useGetAverageFundingRateForMarkets(Period.ONE_HOUR);
useLaggedDailyPrice();
useGetFuturesVolumes({ refetchInterval: 60000 });
useGetCrossMarginSettings();

useEffect(() => {
if (positionQuery.error) {
setPosition(null);
}
}, [positionQuery.error, setPosition]);

const handleRefetch = (refetchType: RefetchType, timeout?: number) => {
setTimeout(() => {
switch (refetchType) {
case 'modify-position':
openOrdersQuery.refetch();
positionsQuery.refetch();
dispatch(fetchOpenOrders());
positionHistoryQuery.refetch();
dispatch(fetchFuturesPositionsForType());
if (selectedAccountType === 'cross_margin') {
crossMarginAccountOverview.refetch();
dispatch(fetchCrossMarginBalanceInfo());
}
break;
case 'new-order':
positionsQuery.refetch();
openOrdersQuery.refetch();
dispatch(fetchFuturesPositionsForType());
dispatch(fetchOpenOrders());
break;
case 'close-position':
positionQuery.refetch();
positionsQuery.refetch();
dispatch(fetchFuturesPositionsForType());
positionHistoryQuery.refetch();
openOrdersQuery.refetch();
dispatch(fetchOpenOrders());
break;
case 'margin-change':
positionQuery.refetch();
positionsQuery.refetch();
dispatch(fetchFuturesPositionsForType());
positionHistoryQuery.refetch();
openOrdersQuery.refetch();
synthsBalancesQuery.refetch();
dispatch(fetchBalances());
break;
case 'account-margin-change':
crossMarginAccountOverview.refetch();
synthsBalancesQuery.refetch();
dispatch(fetchBalances());
break;
case 'cross-margin-account-change':
queryCrossMarginAccount();
Expand All @@ -104,23 +82,6 @@ export const RefetchProvider: React.FC = ({ children }) => {

const refetchUntilUpdate = async (refetchType: RefetchUntilType) => {
switch (refetchType) {
case 'account-margin-change':
return Promise.all([
refetchWithComparator(
crossMarginAccountOverview.refetch,
crossMarginAccountOverview,
(prev, next) =>
!next.data ||
prev?.data?.freeMargin?.toString() === next?.data?.freeMargin?.toString()
),
refetchWithComparator(
synthsBalancesQuery.refetch,
synthsBalancesQuery,
(prev, next) =>
!next.data ||
prev?.data.susdWalletBalance?.toString() === next?.data.susdWalletBalance?.toString()
),
]);
case 'cross-margin-account-change':
return refetchWithComparator(
queryCrossMarginAccount,
Expand All @@ -137,41 +98,6 @@ export const RefetchProvider: React.FC = ({ children }) => {
);
};

// Takes a comparitor which should return a bool condition to
// signal to continue retrying, comparing prev and new query result

const refetchWithComparator = async (
query: () => Promise<any>,
existingResult: any,
comparator: (previous: any, current: any) => boolean,
interval = 1000,
max = 25
) => {
return new Promise((res) => {
let count = 1;

const refetch = async (existingResult: any) => {
const timeout = setTimeout(async () => {
if (count > max) {
clearTimeout(timeout);
logError('refetch timeout');
res({ data: null, status: 'timeout' });
} else {
const next = await query();
count += 1;
if (!comparator(existingResult, next)) {
clearTimeout(timeout);
res({ data: next, status: 'complete' });
} else {
refetch(next);
}
}
}, interval);
};
refetch(existingResult);
});
};

export const useRefetchContext = () => {
return React.useContext(RefetchContext);
};
Expand Down
6 changes: 3 additions & 3 deletions hooks/useAverageEntryPrice.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useMemo } from 'react';
import { useRecoilValue } from 'recoil';

import { PositionHistory, PositionSide } from 'queries/futures/types';
import { potentialTradeDetailsState } from 'store/futures';
import { selectTradePreview } from 'state/futures/selectors';
import { useAppSelector } from 'state/hooks';

// Used to calculate the new average entry price of a modified position
const useAverageEntryPrice = (positionHistory?: PositionHistory) => {
const { data: previewTrade } = useRecoilValue(potentialTradeDetailsState);
const previewTrade = useAppSelector(selectTradePreview);

return useMemo(() => {
if (positionHistory && previewTrade) {
Expand Down
Loading

0 comments on commit f17b592

Please sign in to comment.