Compare commits

...

6 Commits

Author SHA1 Message Date
jaredvu
8f75d893bb
remove isConnected state from dydxClient 2023-10-18 09:52:17 -07:00
jaredvu
c54a5d6d49
Temp remove notif onClick 2023-10-17 23:52:15 -07:00
jaredvu
2345ef38a1
Fix tradingView initial load 2023-10-17 23:50:38 -07:00
jaredvu
73cbb4e04e
Fix goodTilTime string 2023-10-17 23:50:24 -07:00
jaredvu
52e1dcc4b0
Update to abacus0.7.0 2023-10-17 23:50:11 -07:00
jaredvu
cc3f7d1c09
Add Notification icon w/ stroke 2023-10-17 22:00:52 -07:00
15 changed files with 117 additions and 78 deletions

View File

@ -38,7 +38,7 @@
"@cosmjs/proto-signing": "^0.31.0", "@cosmjs/proto-signing": "^0.31.0",
"@cosmjs/stargate": "^0.31.0", "@cosmjs/stargate": "^0.31.0",
"@cosmjs/tendermint-rpc": "^0.31.0", "@cosmjs/tendermint-rpc": "^0.31.0",
"@dydxprotocol/v4-abacus": "^0.6.4", "@dydxprotocol/v4-abacus": "^0.7.0",
"@dydxprotocol/v4-client-js": "^0.36.1", "@dydxprotocol/v4-client-js": "^0.36.1",
"@dydxprotocol/v4-localization": "^0.1.30", "@dydxprotocol/v4-localization": "^0.1.30",
"@ethersproject/providers": "^5.7.2", "@ethersproject/providers": "^5.7.2",

8
pnpm-lock.yaml generated
View File

@ -27,8 +27,8 @@ dependencies:
specifier: ^0.31.0 specifier: ^0.31.0
version: 0.31.0 version: 0.31.0
'@dydxprotocol/v4-abacus': '@dydxprotocol/v4-abacus':
specifier: ^0.6.4 specifier: ^0.7.0
version: 0.6.4 version: 0.7.0
'@dydxprotocol/v4-client-js': '@dydxprotocol/v4-client-js':
specifier: ^0.36.1 specifier: ^0.36.1
version: 0.36.1 version: 0.36.1
@ -979,8 +979,8 @@ packages:
resolution: {integrity: sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==} resolution: {integrity: sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==}
dev: true dev: true
/@dydxprotocol/v4-abacus@0.6.4: /@dydxprotocol/v4-abacus@0.7.0:
resolution: {integrity: sha512-eH+/9Q/OnQtwzBwM1BJyXybFPdivGmFQWrxM71MFWGs6uIQGbZX775mpoa8deweSTyQ/QrRLRQ1mP2BPDgBQYg==} resolution: {integrity: sha512-XheqfIpOODfQFG860oH0fneVgp9qQKPMDTwrvFXaM/JtKH9ekOUUO6De72EsJ7qOuxWwl1WgoALA8b4tRs0tiw==}
dev: false dev: false
/@dydxprotocol/v4-client-js@0.36.1: /@dydxprotocol/v4-client-js@0.36.1:

View File

@ -6,6 +6,8 @@ import {
AddressConnectorIcon, AddressConnectorIcon,
ArrowIcon, ArrowIcon,
Bar3Icon, Bar3Icon,
BellIcon,
BellStrokeIcon,
BoxCloseIcon, BoxCloseIcon,
CalculatorIcon, CalculatorIcon,
CaretIcon, CaretIcon,
@ -71,6 +73,8 @@ export enum IconName {
AddressConnector = 'AddressConnector', AddressConnector = 'AddressConnector',
Arrow = 'Arrow', Arrow = 'Arrow',
Bar3 = 'Bar3', Bar3 = 'Bar3',
Bell = 'Bell',
BellStroked = 'BellStroked',
BoxClose = 'BoxClose', BoxClose = 'BoxClose',
Calculator = 'Calculator', Calculator = 'Calculator',
Caret = 'Caret', Caret = 'Caret',
@ -137,6 +141,8 @@ const icons = {
[IconName.AddressConnector]: AddressConnectorIcon, [IconName.AddressConnector]: AddressConnectorIcon,
[IconName.Arrow]: ArrowIcon, [IconName.Arrow]: ArrowIcon,
[IconName.Bar3]: Bar3Icon, [IconName.Bar3]: Bar3Icon,
[IconName.Bell]: BellIcon,
[IconName.BellStroked]: BellStrokeIcon,
[IconName.BoxClose]: BoxCloseIcon, [IconName.BoxClose]: BoxCloseIcon,
[IconName.Calculator]: CalculatorIcon, [IconName.Calculator]: CalculatorIcon,
[IconName.Caret]: CaretIcon, [IconName.Caret]: CaretIcon,
@ -213,7 +219,8 @@ export const Icon = styled(
iconComponent: Component = iconName && icons[iconName], iconComponent: Component = iconName && icons[iconName],
className, className,
...props ...props
}: ElementProps & StyleProps) => (Component ? <Component className={className} {...props} /> : null) }: ElementProps & StyleProps) =>
Component ? <Component className={className} {...props} /> : null
)` )`
width: 1em; width: 1em;
height: 1em; height: 1em;

View File

@ -59,16 +59,6 @@ export const TransactionType = Abacus.exchange.dydx.abacus.protocols.Transaction
const transactionTypes = [...TransactionType.values()] as const; const transactionTypes = [...TransactionType.values()] as const;
export type TransactionTypes = (typeof transactionTypes)[number]; export type TransactionTypes = (typeof transactionTypes)[number];
export type NetworkConfig = {
chainId: string;
indexerUrl: string;
indexerSocketUrl: string;
validatorUrl: string;
faucetUrl?: string | null;
};
export type ConnectNetworkEvent = CustomEvent<Partial<NetworkConfig>>;
// ------ State ------ // ------ State ------
export type AbacusApiState = Abacus.exchange.dydx.abacus.state.manager.ApiState; export type AbacusApiState = Abacus.exchange.dydx.abacus.state.manager.ApiState;
export const AbacusApiStatus = Abacus.exchange.dydx.abacus.state.manager.ApiStatus; export const AbacusApiStatus = Abacus.exchange.dydx.abacus.state.manager.ApiStatus;
@ -267,3 +257,20 @@ export const TRADE_TYPES: Record<
[AbacusOrderType.liquidation.name]: null, [AbacusOrderType.liquidation.name]: null,
[AbacusOrderType.trailingStop.name]: null, [AbacusOrderType.trailingStop.name]: null,
}; };
// Custom types involving Abacus
export type NetworkConfig = Partial<{
indexerUrl: Nullable<string>;
websocketUrl: Nullable<string>;
validatorUrl: Nullable<string>;
chainId: Nullable<string>;
faucetUrl: Nullable<string>;
USDC_DENOM: Nullable<string>;
USDC_DECIMALS: Nullable<number>;
USDC_GAS_DENOM: Nullable<string>;
CHAINTOKEN_DENOM: Nullable<string>;
CHAINTOKEN_DECIMALS: Nullable<number>;
}>;
export type ConnectNetworkEvent = CustomEvent<Partial<NetworkConfig>>;

View File

@ -33,7 +33,7 @@ export const useTradingView = ({
const marketIds = useSelector(getMarketIds, shallowEqual); const marketIds = useSelector(getMarketIds, shallowEqual);
const selectedLocale = useSelector(getSelectedLocale); const selectedLocale = useSelector(getSelectedLocale);
const selectedNetwork = useSelector(getSelectedNetwork); const selectedNetwork = useSelector(getSelectedNetwork);
const { getCandlesForDatafeed } = useDydxClient(); const { getCandlesForDatafeed, isConnected: isClientConnected } = useDydxClient();
const [savedTvChartConfig, setTvChartConfig] = useLocalStorage<object | undefined>({ const [savedTvChartConfig, setTvChartConfig] = useLocalStorage<object | undefined>({
key: LocalStorageKey.TradingViewChartConfig, key: LocalStorageKey.TradingViewChartConfig,
@ -44,7 +44,7 @@ export const useTradingView = ({
const hasMarkets = marketIds.length > 0; const hasMarkets = marketIds.length > 0;
useEffect(() => { useEffect(() => {
if (hasMarkets) { if (hasMarkets && isClientConnected) {
const widgetOptions = getWidgetOptions(); const widgetOptions = getWidgetOptions();
const widgetOverrides = getWidgetOverrides(appTheme); const widgetOverrides = getWidgetOverrides(appTheme);
const options = { const options = {
@ -75,7 +75,7 @@ export const useTradingView = ({
tvWidgetRef.current = null; tvWidgetRef.current = null;
setIsChartReady(false); setIsChartReady(false);
}; };
}, [getCandlesForDatafeed, hasMarkets, selectedLocale, selectedNetwork]); }, [getCandlesForDatafeed, isClientConnected, hasMarkets, selectedLocale, selectedNetwork]);
return { savedResolution }; return { savedResolution };
}; };

View File

@ -44,6 +44,9 @@ export const useCurrentMarketId = () => {
}, [validId]); }, [validId]);
useEffect(() => { useEffect(() => {
abacusStateManager.setMarket(marketId ?? DEFAULT_MARKETID); // Check for marketIds otherwise Abacus will silently fail its isMarketValid check
}, [selectedNetwork, marketId]); if (marketIds) {
abacusStateManager.setMarket(marketId ?? DEFAULT_MARKETID);
}
}, [selectedNetwork, marketIds, marketId]);
}; };

View File

@ -13,7 +13,7 @@ import {
import type { ResolutionString } from 'public/tradingview/charting_library'; import type { ResolutionString } from 'public/tradingview/charting_library';
import type { NetworkConfig, ConnectNetworkEvent } from '@/constants/abacus'; import type { ConnectNetworkEvent, NetworkConfig } from '@/constants/abacus';
import { type Candle, RESOLUTION_MAP } from '@/constants/candles'; import { type Candle, RESOLUTION_MAP } from '@/constants/candles';
import { getSelectedNetwork } from '@/state/appSelectors'; import { getSelectedNetwork } from '@/state/appSelectors';
@ -37,7 +37,7 @@ const useDydxClientContext = () => {
const selectedNetwork = useSelector(getSelectedNetwork); const selectedNetwork = useSelector(getSelectedNetwork);
const [networkConfig, setNetworkConfig] = useState<Partial<NetworkConfig>>(); const [networkConfig, setNetworkConfig] = useState<NetworkConfig>();
useEffect(() => { useEffect(() => {
const onConnectNetwork = (event: ConnectNetworkEvent) => setNetworkConfig(event.detail); const onConnectNetwork = (event: ConnectNetworkEvent) => setNetworkConfig(event.detail);
@ -57,14 +57,14 @@ const useDydxClientContext = () => {
if ( if (
networkConfig?.chainId && networkConfig?.chainId &&
networkConfig?.indexerUrl && networkConfig?.indexerUrl &&
networkConfig?.indexerSocketUrl && networkConfig?.websocketUrl &&
networkConfig?.validatorUrl networkConfig?.validatorUrl
) { ) {
try { try {
const initializedClient = await CompositeClient.connect( const initializedClient = await CompositeClient.connect(
new Network( new Network(
selectedNetwork, selectedNetwork,
new IndexerConfig(networkConfig.indexerUrl, networkConfig.indexerSocketUrl), new IndexerConfig(networkConfig.indexerUrl, networkConfig.websocketUrl),
new ValidatorConfig(networkConfig.validatorUrl, networkConfig.chainId, { new ValidatorConfig(networkConfig.validatorUrl, networkConfig.chainId, {
broadcastPollIntervalMs: 3_000, broadcastPollIntervalMs: 3_000,
broadcastTimeoutMs: 60_000, broadcastTimeoutMs: 60_000,
@ -209,6 +209,7 @@ const useDydxClientContext = () => {
networkConfig, networkConfig,
compositeClient, compositeClient,
faucetClient, faucetClient,
isConnected: !!compositeClient,
// Wallet Methods // Wallet Methods
getWalletFromEvmSignature, getWalletFromEvmSignature,

View File

@ -4,15 +4,14 @@ import { useSelector, shallowEqual, useDispatch } from 'react-redux';
import { groupBy } from 'lodash'; import { groupBy } from 'lodash';
import { AlertType } from '@/constants/alerts'; import { AlertType } from '@/constants/alerts';
import { AbacusOrderStatus, ORDER_SIDES, ORDER_STATUS_STRINGS } from '@/constants/abacus'; import { AbacusOrderStatus, ORDER_SIDES } from '@/constants/abacus';
import { DialogTypes } from '@/constants/dialogs'; import { DialogTypes } from '@/constants/dialogs';
import { STRING_KEYS } from '@/constants/localization'; import { STRING_KEYS, StringKey } from '@/constants/localization';
import { type NotificationTypeConfig, NotificationType } from '@/constants/notifications'; import { type NotificationTypeConfig, NotificationType } from '@/constants/notifications';
import { ORDER_SIDE_STRINGS, TRADE_TYPE_STRINGS, TradeTypes } from '@/constants/trade'; import { ORDER_SIDE_STRINGS } from '@/constants/trade';
import { useLocalNotifications } from '@/hooks/useLocalNotifications'; import { useLocalNotifications } from '@/hooks/useLocalNotifications';
import { AlertMessage } from '@/components/AlertMessage';
import { Icon, IconName } from '@/components/Icon'; import { Icon, IconName } from '@/components/Icon';
import { Output, OutputType } from '@/components/Output'; import { Output, OutputType } from '@/components/Output';
import { TransferStatusToast } from '@/views/TransferStatus'; import { TransferStatusToast } from '@/views/TransferStatus';
@ -69,11 +68,11 @@ export const notificationTypes = [
<OrderStatusIcon status={order.status} totalFilled={order.totalFilled ?? 0} /> <OrderStatusIcon status={order.status} totalFilled={order.totalFilled ?? 0} />
), ),
title: `${stringGetter({ title: `${stringGetter({
key: TRADE_TYPE_STRINGS[order.type.rawValue as TradeTypes].tradeTypeKey, key: order.resources.typeStringKey as StringKey,
})} ${ })} ${
order.status === AbacusOrderStatus.open && (order?.totalFilled ?? 0) > 0 order.status === AbacusOrderStatus.open && (order?.totalFilled ?? 0) > 0
? stringGetter({ key: STRING_KEYS.PARTIALLY_FILLED }) ? stringGetter({ key: STRING_KEYS.PARTIALLY_FILLED })
: stringGetter({ key: ORDER_STATUS_STRINGS[order.status.name] }) : stringGetter({ key: order.resources.statusStringKey as StringKey })
}`, }`,
description: `${stringGetter({ description: `${stringGetter({
key: ORDER_SIDE_STRINGS[ORDER_SIDES[order.side.name]], key: ORDER_SIDE_STRINGS[ORDER_SIDES[order.side.name]],
@ -91,18 +90,34 @@ export const notificationTypes = [
}, [orderIds]); }, [orderIds]);
}, },
useNotificationAction: () => { // useNotificationAction: () => {
const dispatch = useDispatch(); // const dispatch = useDispatch();
// const orders = useSelector(getSubaccountOrders, shallowEqual) || [];
// const ordersByOrderId = Object.fromEntries(orders.map((order) => [order.id, order]));
return (orderId) => { // const fills = useSelector(getSubaccountFills, shallowEqual) || [];
dispatch( // const fillsByOrderId = groupBy(fills, (fill) => fill.orderId);
openDialog({
type: DialogTypes.OrderDetails, // return (id) => {
dialogProps: { orderId }, // if (ordersByOrderId[id]) {
}) // dispatch(
); // openDialog({
}; // type: DialogTypes.OrderDetails,
}, // dialogProps: { orderId: id },
// })
// );
// } else if (fillsByOrderId[id]) {
// const fillId = fillsByOrderId[id][0].id;
// dispatch(
// openDialog({
// type: DialogTypes.FillDetails,
// dialogProps: { fillId },
// })
// );
// }
// };
// },
} as NotificationTypeConfig<string, [string, number]>, } as NotificationTypeConfig<string, [string, number]>,
{ {
type: NotificationType.SquidTransfer, type: NotificationType.SquidTransfer,
@ -138,7 +153,8 @@ export const notificationTypes = [
{stringGetter({ {stringGetter({
key: STRING_KEYS.SOMETHING_WENT_WRONG_WITH_MESSAGE, key: STRING_KEYS.SOMETHING_WENT_WRONG_WITH_MESSAGE,
params: { params: {
ERROR_MESSAGE: error.message || stringGetter({ key: STRING_KEYS.UNKNOWN_ERROR }), ERROR_MESSAGE:
error.message || stringGetter({ key: STRING_KEYS.UNKNOWN_ERROR }),
}, },
})} })}
</Styled.ErrorMessage> </Styled.ErrorMessage>
@ -182,8 +198,8 @@ Styled.TransferText = styled.span`
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
gap: 0.5ch; gap: 0.5ch;
` `;
Styled.ErrorMessage = styled.div` Styled.ErrorMessage = styled.div`
max-width: 13rem; max-width: 13rem;
`; `;

View File

@ -0,0 +1,3 @@
<svg width="16" height="18" viewBox="0 0 16 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.3811 13.235C11.9338 13.0512 13.4593 12.6847 14.9261 12.1433C13.6839 10.7673 12.9975 8.97875 13.0003 7.125V6.54167V6.5C13.0003 5.17392 12.4735 3.90215 11.5358 2.96447C10.5981 2.02678 9.32636 1.5 8.00028 1.5C6.67419 1.5 5.40242 2.02678 4.46474 2.96447C3.52706 3.90215 3.00028 5.17392 3.00028 6.5V7.125C3.00279 8.97886 2.3161 10.7675 1.07361 12.1433C2.51778 12.6767 4.04027 13.0475 5.61944 13.235M10.3811 13.235C8.79943 13.4226 7.20112 13.4226 5.61944 13.235M10.3811 13.235C10.5012 13.6099 10.5311 14.0078 10.4683 14.3964C10.4055 14.785 10.2518 15.1533 10.0198 15.4713C9.78772 15.7893 9.48386 16.048 9.13293 16.2263C8.78201 16.4047 8.39392 16.4976 8.00028 16.4976C7.60663 16.4976 7.21854 16.4047 6.86762 16.2263C6.51669 16.048 6.21283 15.7893 5.98079 15.4713C5.74875 15.1533 5.59508 14.785 5.53229 14.3964C5.46949 14.0078 5.49936 13.6099 5.61944 13.235" stroke="currentColor" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 24"><path fill="currentColor" d="M11 0C8.5 0 6.101.948 4.333 2.636 2.565 4.324 1.57 6.613 1.57 9v5.379l-1.11 1.06c-.22.21-.37.477-.43.768-.061.291-.03.593.089.867s.32.508.578.673c.259.165.562.253.873.253h18.86c.31 0 .614-.088.873-.253.258-.165.46-.399.578-.673.12-.274.15-.576.09-.867a1.48 1.48 0 0 0-.43-.768l-1.111-1.06V9c0-2.387-.993-4.676-2.762-6.364C15.9.948 13.501 0 11 0Zm0 24a4.83 4.83 0 0 1-3.334-1.318 4.399 4.399 0 0 1-1.38-3.182h9.428a4.399 4.399 0 0 1-1.38 3.182A4.83 4.83 0 0 1 11 24Z"/></svg> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 24"><path fill="currentColor" d="M11 0C8.5 0 6.101.948 4.333 2.636 2.565 4.324 1.57 6.613 1.57 9v5.379l-1.11 1.06c-.22.21-.37.477-.43.768-.061.291-.03.593.089.867s.32.508.578.673c.259.165.562.253.873.253h18.86c.31 0 .614-.088.873-.253.258-.165.46-.399.578-.673.12-.274.15-.576.09-.867a1.48 1.48 0 0 0-.43-.768l-1.111-1.06V9c0-2.387-.993-4.676-2.762-6.364C15.9.948 13.501 0 11 0Zm0 24a4.83 4.83 0 0 1-3.334-1.318 4.399 4.399 0 0 1-1.38-3.182h9.428a4.399 4.399 0 0 1-1.38 3.182A4.83 4.83 0 0 1 11 24Z"/></svg>

Before

Width:  |  Height:  |  Size: 563 B

After

Width:  |  Height:  |  Size: 564 B

View File

@ -2,6 +2,7 @@ export { default as AddressConnectorIcon } from './address-connector.svg';
export { default as ArrowIcon } from './arrow.svg'; export { default as ArrowIcon } from './arrow.svg';
export { default as Bar3Icon } from './bar3.svg'; export { default as Bar3Icon } from './bar3.svg';
export { default as BellIcon } from './bell.svg'; export { default as BellIcon } from './bell.svg';
export { default as BellStrokeIcon } from './bell-stroke.svg';
export { default as BoxCloseIcon } from './box-close.svg'; export { default as BoxCloseIcon } from './box-close.svg';
export { default as CalculatorIcon } from './calculator.svg'; export { default as CalculatorIcon } from './calculator.svg';
export { default as CaretIcon } from './caret-down.svg'; export { default as CaretIcon } from './caret-down.svg';

View File

@ -7,7 +7,7 @@ import { DialogTypes } from '@/constants/dialogs';
import { STRING_KEYS } from '@/constants/localization'; import { STRING_KEYS } from '@/constants/localization';
import { AppRoute } from '@/constants/routes'; import { AppRoute } from '@/constants/routes';
import { useStringGetter } from '@/hooks'; import { useStringGetter } from '@/hooks';
import { LogoShortIcon, BellIcon } from '@/icons'; import { LogoShortIcon, BellStrokeIcon } from '@/icons';
import { Icon, IconName } from '@/components/Icon'; import { Icon, IconName } from '@/components/Icon';
import { IconButton } from '@/components/IconButton'; import { IconButton } from '@/components/IconButton';
@ -131,7 +131,9 @@ export const HeaderDesktop = () => {
<VerticalSeparator /> <VerticalSeparator />
<NotificationsMenu <NotificationsMenu
slotTrigger={<Styled.IconButton shape={ButtonShape.Rectangle} iconComponent={BellIcon} />} slotTrigger={
<Styled.IconButton shape={ButtonShape.Rectangle} iconComponent={BellStrokeIcon} />
}
/> />
<VerticalSeparator /> <VerticalSeparator />
@ -165,7 +167,7 @@ Styled.Header = styled.header`
) )
var(--border-width) 1fr var(--border-width) auto; var(--border-width) 1fr var(--border-width) auto;
font-size: 0.9375em; font-size: 0.9375rem;
:before { :before {
backdrop-filter: blur(10px); backdrop-filter: blur(10px);
@ -214,7 +216,8 @@ Styled.NavAfter = styled.div`
} }
`; `;
Styled.IconButton = styled(IconButton)` Styled.IconButton = styled(IconButton)<{ size?: string }>`
${headerMixins.button} ${headerMixins.button}
--button-border: none; --button-border: none;
--button-icon-size: 1rem;
`; `;

View File

@ -61,18 +61,17 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
} }
async connectNetwork( async connectNetwork(
indexerUrl: string, paramsInJson: Nullable<string>,
indexerSocketUrl: string,
validatorUrl: string,
chainId: string,
faucetUrl: Nullable<string> | undefined,
callback: (p0: Nullable<string>) => void callback: (p0: Nullable<string>) => void
): Promise<void> { ): Promise<void> {
try { try {
const parsedParams = paramsInJson ? JSON.parse(paramsInJson) : {};
const { indexerUrl, websocketUrl, validatorUrl, chainId } = parsedParams;
const compositeClient = await CompositeClient.connect( const compositeClient = await CompositeClient.connect(
new Network( new Network(
chainId, chainId,
new IndexerConfig(indexerUrl, indexerSocketUrl), new IndexerConfig(indexerUrl, websocketUrl),
new ValidatorConfig(validatorUrl, chainId, { new ValidatorConfig(validatorUrl, chainId, {
broadcastPollIntervalMs: 3_000, broadcastPollIntervalMs: 3_000,
broadcastTimeoutMs: 60_000, broadcastTimeoutMs: 60_000,
@ -84,13 +83,7 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
// Dispatch custom event to notify other parts of the app that the network has been connected // Dispatch custom event to notify other parts of the app that the network has been connected
const customEvent = new CustomEvent('abacus:connectNetwork', { const customEvent = new CustomEvent('abacus:connectNetwork', {
detail: { detail: parsedParams,
indexerUrl,
indexerSocketUrl,
validatorUrl,
chainId,
faucetUrl,
},
}); });
globalThis.dispatchEvent(customEvent); globalThis.dispatchEvent(customEvent);
@ -99,9 +92,7 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
this.store?.dispatch( this.store?.dispatch(
openDialog({ type: DialogTypes.ExchangeOffline, dialogProps: { preventClose: true } }) openDialog({ type: DialogTypes.ExchangeOffline, dialogProps: { preventClose: true } })
); );
log('DydxChainTransactions/connectNetwork', error); log('DydxChainTransactions/connectNetwork', error);
return;
} }
} }
@ -251,7 +242,7 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
const msg = compositeClient.withdrawFromSubaccountMessage(subaccountClient, amount); const msg = compositeClient.withdrawFromSubaccountMessage(subaccountClient, amount);
resolve([msg]); resolve([msg]);
}), })
); );
const parsedTx = this.parseToPrimitives(tx); const parsedTx = this.parseToPrimitives(tx);
@ -266,7 +257,9 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
} }
} }
async simulateTransferNativeTokenTransaction(params: HumanReadableTransferPayload): Promise<string> { async simulateTransferNativeTokenTransaction(
params: HumanReadableTransferPayload
): Promise<string> {
if (!this.compositeClient || !this.localWallet) { if (!this.compositeClient || !this.localWallet) {
throw new Error('Missing compositeClient or localWallet'); throw new Error('Missing compositeClient or localWallet');
} }
@ -289,7 +282,7 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
resolve([msg]); resolve([msg]);
}), }),
GAS_PRICE_DYDX_DENOM, GAS_PRICE_DYDX_DENOM
); );
const parsedTx = this.parseToPrimitives(tx); const parsedTx = this.parseToPrimitives(tx);
@ -397,9 +390,10 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
break; break;
case QueryType.GetAccountBalances: case QueryType.GetAccountBalances:
if (!this.localWallet?.address) throw new Error('Missing localWallet'); if (!this.localWallet?.address) throw new Error('Missing localWallet');
const accountBalances = await this.compositeClient?.validatorClient.get.getAccountBalances( const accountBalances =
this.localWallet.address await this.compositeClient?.validatorClient.get.getAccountBalances(
); this.localWallet.address
);
const parsedAccountBalances = this.parseToPrimitives(accountBalances); const parsedAccountBalances = this.parseToPrimitives(accountBalances);
callback(JSON.stringify(parsedAccountBalances)); callback(JSON.stringify(parsedAccountBalances));
break; break;

View File

@ -29,7 +29,7 @@ export const AdvancedTradeOptions = () => {
const currentTradeFormConfig = useSelector(getInputTradeOptions, shallowEqual); const currentTradeFormConfig = useSelector(getInputTradeOptions, shallowEqual);
const inputTradeData = useSelector(getInputTradeData, shallowEqual); const inputTradeData = useSelector(getInputTradeData, shallowEqual);
const { execution, goodTil, postOnly, reduceOnly, timeInForce } = inputTradeData || {}; const { execution, goodTil, postOnly, reduceOnly, timeInForce, type } = inputTradeData || {};
const { executionOptions, needsGoodUntil, needsPostOnly, needsReduceOnly, timeInForceOptions } = const { executionOptions, needsGoodUntil, needsPostOnly, needsReduceOnly, timeInForceOptions } =
currentTradeFormConfig || {}; currentTradeFormConfig || {};
@ -37,6 +37,7 @@ export const AdvancedTradeOptions = () => {
const { duration, unit } = goodTil || {}; const { duration, unit } = goodTil || {};
const needsExecution = executionOptions || needsPostOnly || needsReduceOnly; const needsExecution = executionOptions || needsPostOnly || needsReduceOnly;
const hasTimeInForce = timeInForceOptions?.toArray()?.length;
return ( return (
<Styled.Collapsible <Styled.Collapsible
@ -47,7 +48,7 @@ export const AdvancedTradeOptions = () => {
> >
<Styled.AdvancedInputsContainer> <Styled.AdvancedInputsContainer>
<Styled.AdvancedInputsRow needsGoodUntil={needsGoodUntil}> <Styled.AdvancedInputsRow needsGoodUntil={needsGoodUntil}>
{timeInForceOptions?.toArray() && ( {hasTimeInForce && (
<Styled.SelectMenu <Styled.SelectMenu
value={timeInForce} value={timeInForce}
onValueChange={(selectedTimeInForceOption: string) => onValueChange={(selectedTimeInForceOption: string) =>
@ -72,7 +73,9 @@ export const AdvancedTradeOptions = () => {
id="trade-good-til-time" id="trade-good-til-time"
type={InputType.Number} type={InputType.Number}
decimals={INTEGER_DECIMALS} decimals={INTEGER_DECIMALS}
label={stringGetter({ key: STRING_KEYS.TIME })} label={stringGetter({
key: hasTimeInForce ? STRING_KEYS.TIME : STRING_KEYS.GOOD_TIL_TIME,
})}
onChange={({ value }: NumberFormatValues) => { onChange={({ value }: NumberFormatValues) => {
abacusStateManager.setTradeValue({ abacusStateManager.setTradeValue({
value: Number(value), value: Number(value),

View File

@ -178,10 +178,11 @@ export const NotificationsMenu = ({
}; };
const $UnreadIndicator = styled.div` const $UnreadIndicator = styled.div`
width: 0.5em; width: 0.5rem;
height: 0.5em; height: 0.5rem;
border-radius: 50%; border-radius: 50%;
background-color: var(--color-accent); background-color: var(--color-accent);
border: 1px solid var(--color-layer-2);
`; `;
const $TriggerContainer = styled.div` const $TriggerContainer = styled.div`
@ -192,8 +193,8 @@ const $TriggerUnreadIndicator = styled($UnreadIndicator)`
place-self: center; place-self: center;
position: relative; position: relative;
right: -0.425em; right: -0.2rem;
top: -0.425em; top: -0.325rem;
`; `;
const $Output = styled(Output)` const $Output = styled(Output)`