dydx-v4-web/src/lib/tradeData.ts
James Jia - Test 4b86068d8f
Initial commit
2023-09-08 13:52:13 -07:00

136 lines
3.6 KiB
TypeScript

import { type Location, matchPath } from 'react-router-dom';
import { OrderSide } from '@dydxprotocol/v4-client-js';
import { StringGetterFunction } from '@/constants/localization';
import {
type Nullable,
AbacusOrderSide,
type AbacusOrderSides,
AbacusOrderTypes,
ValidationError,
ErrorType,
} from '@/constants/abacus';
import { AlertType } from '@/constants/alerts';
import { PERCENT_DECIMALS, USD_DECIMALS } from '@/constants/numbers';
import { TRADE_ROUTE } from '@/constants/routes';
import { PositionSide, TradeTypes } from '@/constants/trade';
import { MustBigNumber } from '@/lib/numbers';
export const getMarketIdFromLocation = (location: Location) => {
const { pathname } = location;
const tradeMatch = matchPath(TRADE_ROUTE, pathname);
return tradeMatch?.params.market;
};
export const getSelectedTradeType = (type: Nullable<AbacusOrderTypes>) => {
return type ? (type.rawValue as TradeTypes) : TradeTypes.LIMIT;
};
export const getSelectedOrderSide = (side: Nullable<AbacusOrderSides>) => {
return side === AbacusOrderSide.sell ? OrderSide.SELL : OrderSide.BUY;
};
export const hasPositionSideChanged = ({
currentSize,
postOrderSize,
}: {
currentSize?: Nullable<number>;
postOrderSize?: Nullable<number>;
}) => {
const currentSizeBN = MustBigNumber(currentSize);
const postOrderSizeBN = MustBigNumber(postOrderSize);
const currentPositionSide = currentSizeBN.gt(0)
? PositionSide.Long
: currentSizeBN.lt(0)
? PositionSide.Short
: PositionSide.None;
const newPositionSide = postOrderSizeBN.gt(0)
? PositionSide.Long
: postOrderSizeBN.lt(0)
? PositionSide.Short
: PositionSide.None;
return {
currentPositionSide,
newPositionSide,
positionSideHasChanged: postOrderSize !== undefined && currentPositionSide !== newPositionSide,
};
};
const formatErrorParam = ({
value,
format,
stepSizeDecimals,
tickSizeDecimals,
}: {
value: Nullable<string>;
format?: Nullable<string>;
stepSizeDecimals: Nullable<number>;
tickSizeDecimals: Nullable<number>;
}) => {
switch (format) {
case 'percent': {
const percentBN = MustBigNumber(value);
return `${percentBN.times(100).toFixed(PERCENT_DECIMALS)}%`;
}
case 'size': {
const sizeBN = MustBigNumber(value);
return sizeBN.toFixed(stepSizeDecimals ?? 0);
}
case 'price': {
const dollarBN = MustBigNumber(value);
return `$${dollarBN.toFixed(tickSizeDecimals ?? USD_DECIMALS)}`;
}
default: {
return value || '';
}
}
};
/**
* @description Returns the formatted input errors.
*/
export const getTradeInputAlert = ({
abacusInputErrors,
stringGetter,
stepSizeDecimals,
tickSizeDecimals,
}: {
abacusInputErrors: ValidationError[];
stringGetter: StringGetterFunction;
stepSizeDecimals: Nullable<number>;
tickSizeDecimals: Nullable<number>;
}) => {
const inputAlerts = abacusInputErrors.map(({ action: errorAction, resources, type }) => {
const { action, text } = resources || {};
const { stringKey: actionStringKey } = action || {};
const { stringKey: alertStringKey, params: stringParams } = text || {};
const params =
stringParams?.toArray() &&
Object.fromEntries(
stringParams
.toArray()
.map(({ key, value, format }) => [
key,
formatErrorParam({ value, format, stepSizeDecimals, tickSizeDecimals }),
])
);
return {
errorAction,
actionStringKey,
alertStringKey,
alertString: alertStringKey && stringGetter({ key: alertStringKey, params }),
type: type === ErrorType.warning ? AlertType.Warning : AlertType.Error,
};
});
return inputAlerts?.[0];
};