Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b9c192096 | ||
|
|
46752816ec | ||
|
|
f99f78780c | ||
|
|
f7037bca80 | ||
|
|
ba39720f05 |
@@ -16,6 +16,7 @@ NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
|
||||
NX_VEGA_CONSOLE_URL=https://console.fairground.wtf
|
||||
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
|
||||
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||
|
||||
# Cosmic elevator flags
|
||||
NX_SUCCESSOR_MARKETS=true
|
||||
|
||||
@@ -19,7 +19,7 @@ NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/m
|
||||
|
||||
|
||||
# TAG name of the current app version - TODO: bump to the latest upon release
|
||||
NX_APP_VERSION=v0.21.1-core-0.72.14
|
||||
NX_APP_VERSION=v0.21.2-core-0.72.14
|
||||
|
||||
# Cosmic elevator flags
|
||||
NX_SUCCESSOR_MARKETS=true
|
||||
|
||||
@@ -1,18 +1,58 @@
|
||||
import { DepositContainer } from '@vegaprotocol/deposits';
|
||||
import { GetStarted } from '../../components/welcome-dialog';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { Intent, TradingAnchorButton } from '@vegaprotocol/ui-toolkit';
|
||||
import { GetStartedCheckList } from '../../components/welcome-dialog';
|
||||
import {
|
||||
useGetOnboardingStep,
|
||||
useOnboardingStore,
|
||||
OnboardingStep,
|
||||
} from '../../components/welcome-dialog/use-get-onboarding-step';
|
||||
import { Links, Routes } from '../../pages/client-router';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export const Deposit = () => {
|
||||
return (
|
||||
<div className="py-16 px-8 flex w-full justify-center">
|
||||
<div className="lg:min-w-[700px] min-w-[300px] max-w-[700px]">
|
||||
<h1 className="text-4xl xl:text-5xl uppercase font-alpha calt">
|
||||
{t('Deposit')}
|
||||
</h1>
|
||||
<div className="mt-10">
|
||||
<DepositContainer />
|
||||
<GetStarted />
|
||||
</div>
|
||||
<div className="max-w-[600px] px-4 py-8 mx-auto lg:px-8">
|
||||
<h1 className="mb-6 text-4xl uppercase xl:text-5xl font-alpha calt">
|
||||
{t('Deposit')}
|
||||
</h1>
|
||||
<div className="flex flex-col gap-6">
|
||||
<DepositContainer />
|
||||
<DepositGetStarted />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const DepositGetStarted = () => {
|
||||
const onboardingDismissed = useOnboardingStore((store) => store.dismissed);
|
||||
const dismiss = useOnboardingStore((store) => store.dismiss);
|
||||
const step = useGetOnboardingStep();
|
||||
const wrapperClasses = classNames(
|
||||
'flex flex-col py-4 px-6 gap-4 rounded',
|
||||
'bg-vega-blue-300 dark:bg-vega-blue-700',
|
||||
'border border-vega-blue-350 dark:border-vega-blue-650'
|
||||
);
|
||||
|
||||
// Dont show unless still onboarding
|
||||
if (onboardingDismissed) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="pt-6 border-t border-default">
|
||||
<div className={wrapperClasses}>
|
||||
<h3 className="text-lg">{t('Get started')}</h3>
|
||||
<GetStartedCheckList />
|
||||
{step > OnboardingStep.ONBOARDING_DEPOSIT_STEP && (
|
||||
<TradingAnchorButton
|
||||
href={Links[Routes.HOME]()}
|
||||
onClick={() => dismiss()}
|
||||
intent={Intent.Info}
|
||||
>
|
||||
{t('Start trading')}
|
||||
</TradingAnchorButton>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -14,9 +14,9 @@ import { Settings } from '../settings';
|
||||
import { Tooltip } from '../../components/tooltip';
|
||||
import { WithdrawContainer } from '../withdraw-container';
|
||||
import { Routes as AppRoutes } from '../../pages/client-router';
|
||||
import { GetStarted } from '../welcome-dialog';
|
||||
import { useVegaWallet, useViewAsDialog } from '@vegaprotocol/wallet';
|
||||
import { useGetCurrentRouteId } from '../../lib/hooks/use-get-current-route-id';
|
||||
import { GetStarted } from '../welcome-dialog';
|
||||
|
||||
export enum ViewType {
|
||||
Order = 'Order',
|
||||
@@ -57,7 +57,7 @@ export const Sidebar = () => {
|
||||
const setViewAsDialogOpen = useViewAsDialog((state) => state.setOpen);
|
||||
const { pubKeys } = useVegaWallet();
|
||||
return (
|
||||
<div className="flex lg:flex-col gap-2 h-full p-1" data-testid="sidebar">
|
||||
<div className="flex h-full p-1 lg:flex-col gap-2" data-testid="sidebar">
|
||||
<nav className={navClasses}>
|
||||
{/* sidebar options that always show */}
|
||||
<SidebarButton
|
||||
@@ -197,7 +197,7 @@ export const SidebarButton = ({
|
||||
const SidebarDivider = () => {
|
||||
return (
|
||||
<div
|
||||
className="bg-vega-clight-600 dark:bg-vega-cdark-600 w-px h-4 lg:w-4 lg:h-px"
|
||||
className="w-px h-4 bg-vega-clight-600 dark:bg-vega-cdark-600 lg:w-4 lg:h-px"
|
||||
role="separator"
|
||||
/>
|
||||
);
|
||||
@@ -245,7 +245,6 @@ export const SidebarContent = () => {
|
||||
return (
|
||||
<ContentWrapper title={t('Deposit')}>
|
||||
<DepositContainer assetId={view.assetId} />
|
||||
<GetStarted />
|
||||
</ContentWrapper>
|
||||
);
|
||||
}
|
||||
@@ -254,7 +253,6 @@ export const SidebarContent = () => {
|
||||
return (
|
||||
<ContentWrapper title={t('Withdraw')}>
|
||||
<WithdrawContainer assetId={view.assetId} />
|
||||
<GetStarted />
|
||||
</ContentWrapper>
|
||||
);
|
||||
}
|
||||
@@ -263,7 +261,6 @@ export const SidebarContent = () => {
|
||||
return (
|
||||
<ContentWrapper title={t('Transfer')}>
|
||||
<TransferContainer assetId={view.assetId} />
|
||||
<GetStarted />
|
||||
</ContentWrapper>
|
||||
);
|
||||
}
|
||||
@@ -288,7 +285,7 @@ const ContentWrapper = ({
|
||||
}) => {
|
||||
return (
|
||||
<TinyScroll
|
||||
className="h-full overflow-auto py-4 pl-3 pr-4"
|
||||
className="h-full py-4 pl-3 pr-4 overflow-auto"
|
||||
// panes have p-1, since sidebar is on the right make pl less to account for additional pane space
|
||||
data-testid="sidebar-content"
|
||||
>
|
||||
|
||||
@@ -75,7 +75,7 @@ describe('GetStarted', () => {
|
||||
</MemoryRouter>
|
||||
);
|
||||
checkTicks(screen.getAllByRole('listitem'));
|
||||
expect(screen.getByRole('button', { name: 'Deposit' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('link', { name: 'Deposit' })).toBeInTheDocument();
|
||||
|
||||
mockStep = 4;
|
||||
rerender(
|
||||
@@ -87,10 +87,10 @@ describe('GetStarted', () => {
|
||||
);
|
||||
checkTicks(screen.getAllByRole('listitem'));
|
||||
expect(
|
||||
screen.getByRole('button', { name: 'Ready to trade' })
|
||||
screen.getByRole('link', { name: 'Ready to trade' })
|
||||
).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Ready to trade' }));
|
||||
fireEvent.click(screen.getByRole('link', { name: 'Ready to trade' }));
|
||||
|
||||
mockStep = 5;
|
||||
rerender(
|
||||
|
||||
@@ -3,13 +3,13 @@ import { t } from '@vegaprotocol/i18n';
|
||||
import {
|
||||
ExternalLink,
|
||||
Intent,
|
||||
TradingAnchorButton,
|
||||
TradingButton,
|
||||
VegaIcon,
|
||||
VegaIconNames,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
|
||||
import { Networks, useEnvironment } from '@vegaprotocol/environment';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import {
|
||||
OnboardingStep,
|
||||
useGetOnboardingStep,
|
||||
@@ -24,49 +24,84 @@ interface Props {
|
||||
}
|
||||
|
||||
const GetStartedButton = ({ step }: { step: OnboardingStep }) => {
|
||||
const navigate = useNavigate();
|
||||
const dismiss = useOnboardingStore((store) => store.dismiss);
|
||||
const setDialogOpen = useOnboardingStore((store) => store.setDialogOpen);
|
||||
const marketId = useGlobalStore((store) => store.marketId);
|
||||
const link = marketId ? Links[Routes.MARKET](marketId) : Links[Routes.HOME]();
|
||||
const openVegaWalletDialog = useVegaWalletDialogStore(
|
||||
(store) => store.openVegaWalletDialog
|
||||
);
|
||||
const setViews = useSidebar((store) => store.setViews);
|
||||
let buttonText = t('Get started');
|
||||
let onClickHandle = () => {
|
||||
openVegaWalletDialog();
|
||||
|
||||
const buttonProps = {
|
||||
size: 'small' as const,
|
||||
'data-testid': 'get-started-button',
|
||||
intent: Intent.Info,
|
||||
};
|
||||
|
||||
if (step <= OnboardingStep.ONBOARDING_CONNECT_STEP) {
|
||||
buttonText = t('Connect');
|
||||
return (
|
||||
<TradingButton {...buttonProps} onClick={() => openVegaWalletDialog()}>
|
||||
{t('Connect')}
|
||||
</TradingButton>
|
||||
);
|
||||
} else if (step === OnboardingStep.ONBOARDING_DEPOSIT_STEP) {
|
||||
buttonText = t('Deposit');
|
||||
onClickHandle = () => {
|
||||
navigate(link);
|
||||
setViews({ type: ViewType.Deposit }, Routes.MARKET);
|
||||
setDialogOpen(false);
|
||||
};
|
||||
return (
|
||||
<TradingAnchorButton
|
||||
{...buttonProps}
|
||||
href={Links[Routes.DEPOSIT]()}
|
||||
onClick={() => setDialogOpen(false)}
|
||||
>
|
||||
{t('Deposit')}
|
||||
</TradingAnchorButton>
|
||||
);
|
||||
} else if (step >= OnboardingStep.ONBOARDING_ORDER_STEP) {
|
||||
buttonText = t('Ready to trade');
|
||||
onClickHandle = () => {
|
||||
navigate(link);
|
||||
setViews({ type: ViewType.Order }, Routes.MARKET);
|
||||
dismiss();
|
||||
};
|
||||
return (
|
||||
<TradingAnchorButton
|
||||
{...buttonProps}
|
||||
href={marketId ? Links[Routes.MARKET](marketId) : Links[Routes.HOME]()}
|
||||
onClick={() => {
|
||||
setViews({ type: ViewType.Order }, Routes.MARKET);
|
||||
dismiss();
|
||||
}}
|
||||
>
|
||||
{t('Ready to trade')}
|
||||
</TradingAnchorButton>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<TradingButton
|
||||
onClick={onClickHandle}
|
||||
size="small"
|
||||
data-testid="get-started-button"
|
||||
intent={Intent.Info}
|
||||
>
|
||||
{buttonText}
|
||||
<TradingButton {...buttonProps} onClick={() => openVegaWalletDialog()}>
|
||||
{t('Get started')}
|
||||
</TradingButton>
|
||||
);
|
||||
};
|
||||
|
||||
export const GetStartedCheckList = () => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const currentStep = useGetOnboardingStep();
|
||||
return (
|
||||
<ul className="list-none">
|
||||
<Step
|
||||
step={1}
|
||||
text={t('Connect')}
|
||||
complete={Boolean(
|
||||
currentStep > OnboardingStep.ONBOARDING_CONNECT_STEP || pubKey
|
||||
)}
|
||||
/>
|
||||
<Step
|
||||
step={2}
|
||||
text={t('Deposit funds')}
|
||||
complete={currentStep > OnboardingStep.ONBOARDING_DEPOSIT_STEP}
|
||||
/>
|
||||
<Step
|
||||
step={3}
|
||||
text={t('Open a position')}
|
||||
complete={currentStep > OnboardingStep.ONBOARDING_ORDER_STEP}
|
||||
/>
|
||||
</ul>
|
||||
);
|
||||
};
|
||||
|
||||
export const GetStarted = ({ lead }: Props) => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const { VEGA_ENV, VEGA_NETWORKS } = useEnvironment();
|
||||
@@ -89,25 +124,7 @@ export const GetStarted = ({ lead }: Props) => {
|
||||
{lead && <h2>{lead}</h2>}
|
||||
<h3 className="text-lg">{t('Get started')}</h3>
|
||||
<div>
|
||||
<ul className="list-none">
|
||||
<Step
|
||||
step={1}
|
||||
text={t('Connect')}
|
||||
complete={Boolean(
|
||||
currentStep > OnboardingStep.ONBOARDING_CONNECT_STEP || pubKey
|
||||
)}
|
||||
/>
|
||||
<Step
|
||||
step={2}
|
||||
text={t('Deposit funds')}
|
||||
complete={currentStep > OnboardingStep.ONBOARDING_DEPOSIT_STEP}
|
||||
/>
|
||||
<Step
|
||||
step={3}
|
||||
text={t('Open a position')}
|
||||
complete={currentStep > OnboardingStep.ONBOARDING_ORDER_STEP}
|
||||
/>
|
||||
</ul>
|
||||
<GetStartedCheckList />
|
||||
</div>
|
||||
<div>
|
||||
<GetStartedButton step={currentStep} />
|
||||
|
||||
@@ -26,10 +26,7 @@ import {
|
||||
Pill,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
import {
|
||||
useEstimatePositionQuery,
|
||||
useOpenVolume,
|
||||
} from '@vegaprotocol/positions';
|
||||
import { useOpenVolume } from '@vegaprotocol/positions';
|
||||
import {
|
||||
toBigNum,
|
||||
removeDecimal,
|
||||
@@ -63,13 +60,14 @@ import {
|
||||
useAccountBalance,
|
||||
} from '@vegaprotocol/accounts';
|
||||
import { useDataProvider } from '@vegaprotocol/data-provider';
|
||||
import type { OrderFormValues } from '../../hooks';
|
||||
import {
|
||||
DealTicketType,
|
||||
dealTicketTypeToOrderType,
|
||||
isStopOrderType,
|
||||
} from '../../hooks/use-form-values';
|
||||
import type { OrderFormValues } from '../../hooks/use-form-values';
|
||||
import { useDealTicketFormValues } from '../../hooks/use-form-values';
|
||||
useDealTicketFormValues,
|
||||
usePositionEstimate,
|
||||
} from '../../hooks';
|
||||
import { DealTicketSizeIceberg } from './deal-ticket-size-iceberg';
|
||||
import noop from 'lodash/noop';
|
||||
import { isNonPersistentOrder } from '../../utils/time-in-force-persistance';
|
||||
@@ -253,16 +251,14 @@ export const DealTicket = ({
|
||||
side: normalizedOrder.side,
|
||||
});
|
||||
}
|
||||
const { data: positionEstimate } = useEstimatePositionQuery({
|
||||
variables: {
|
||||
marketId: market.id,
|
||||
openVolume,
|
||||
orders,
|
||||
collateralAvailable:
|
||||
marginAccountBalance || generalAccountBalance ? balance : undefined,
|
||||
},
|
||||
|
||||
const positionEstimate = usePositionEstimate({
|
||||
marketId: market.id,
|
||||
openVolume,
|
||||
orders,
|
||||
collateralAvailable:
|
||||
marginAccountBalance || generalAccountBalance ? balance : undefined,
|
||||
skip: !normalizedOrder,
|
||||
fetchPolicy: 'no-cache',
|
||||
});
|
||||
|
||||
const assetSymbol =
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './__generated__/EstimateOrder';
|
||||
export * from './use-estimate-fees';
|
||||
export * from './use-form-values';
|
||||
export * from './use-position-estimate';
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { usePositionEstimate } from './use-position-estimate';
|
||||
import * as positionsModule from '@vegaprotocol/positions';
|
||||
import type {
|
||||
EstimatePositionQuery,
|
||||
EstimatePositionQueryVariables,
|
||||
} from '@vegaprotocol/positions';
|
||||
import type { QueryResult } from '@apollo/client';
|
||||
|
||||
let mockData: object | undefined = {};
|
||||
|
||||
describe('usePositionEstimate', () => {
|
||||
const args = {
|
||||
marketId: 'marketId',
|
||||
openVolume: '10',
|
||||
orders: [],
|
||||
collateralAvailable: '200',
|
||||
skip: false,
|
||||
};
|
||||
it('should return proper data', () => {
|
||||
jest
|
||||
.spyOn(positionsModule, 'useEstimatePositionQuery')
|
||||
.mockReturnValue({ data: mockData } as unknown as QueryResult<
|
||||
EstimatePositionQuery,
|
||||
EstimatePositionQueryVariables
|
||||
>);
|
||||
const { result, rerender } = renderHook(() => usePositionEstimate(args));
|
||||
expect(result.current).toEqual(mockData);
|
||||
mockData = undefined;
|
||||
rerender(true);
|
||||
expect(result.current).toEqual({});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,38 @@
|
||||
import type {
|
||||
EstimatePositionQueryVariables,
|
||||
EstimatePositionQuery,
|
||||
} from '@vegaprotocol/positions';
|
||||
import { useEstimatePositionQuery } from '@vegaprotocol/positions';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
interface PositionEstimateProps extends EstimatePositionQueryVariables {
|
||||
skip: boolean;
|
||||
}
|
||||
|
||||
export const usePositionEstimate = ({
|
||||
marketId,
|
||||
openVolume,
|
||||
orders,
|
||||
collateralAvailable,
|
||||
skip,
|
||||
}: PositionEstimateProps) => {
|
||||
const [estimates, setEstimates] = useState<EstimatePositionQuery | undefined>(
|
||||
undefined
|
||||
);
|
||||
const { data } = useEstimatePositionQuery({
|
||||
variables: {
|
||||
marketId,
|
||||
openVolume,
|
||||
orders,
|
||||
collateralAvailable,
|
||||
},
|
||||
skip,
|
||||
fetchPolicy: 'no-cache',
|
||||
});
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
setEstimates(data);
|
||||
}
|
||||
}, [data]);
|
||||
return estimates;
|
||||
};
|
||||
@@ -658,7 +658,7 @@ export const LiquidityMonitoringParametersInfoPanel = ({
|
||||
parentMarket.liquidityMonitoringParameters.targetStakeParameters
|
||||
.scalingFactor,
|
||||
}
|
||||
: {};
|
||||
: undefined;
|
||||
|
||||
return <MarketInfoTable data={marketData} parentData={parentMarketData} />;
|
||||
};
|
||||
|
||||
@@ -15,6 +15,7 @@ const requestedTransactionUpdate = {
|
||||
status: EthTxStatus.Requested,
|
||||
error: null,
|
||||
confirmations: 0,
|
||||
notify: true,
|
||||
};
|
||||
|
||||
const mockDepositAsset = jest.fn();
|
||||
@@ -57,6 +58,7 @@ const createTransaction = (
|
||||
dialogOpen: false,
|
||||
txHash: null,
|
||||
receipt: null,
|
||||
notify: true,
|
||||
...transaction,
|
||||
});
|
||||
|
||||
@@ -158,6 +160,7 @@ describe('useVegaTransactionManager', () => {
|
||||
expect(update.mock.calls[1][1]).toEqual({
|
||||
status: EthTxStatus.Pending,
|
||||
txHash,
|
||||
notify: true,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -197,6 +200,7 @@ describe('useVegaTransactionManager', () => {
|
||||
expect(update.mock.calls[3][1]).toEqual({
|
||||
status: EthTxStatus.Confirmed,
|
||||
receipt,
|
||||
notify: true,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ export const useEthTransactionManager = () => {
|
||||
status: EthTxStatus.Requested,
|
||||
error: null,
|
||||
confirmations: 0,
|
||||
notify: true,
|
||||
});
|
||||
const {
|
||||
contract,
|
||||
@@ -48,6 +49,7 @@ export const useEthTransactionManager = () => {
|
||||
update(transaction.id, {
|
||||
status: EthTxStatus.Error,
|
||||
error: err as EthereumError,
|
||||
notify: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -61,6 +63,7 @@ export const useEthTransactionManager = () => {
|
||||
update(transaction.id, {
|
||||
status: EthTxStatus.Pending,
|
||||
txHash: tx.hash,
|
||||
notify: true,
|
||||
});
|
||||
|
||||
for (let i = 1; i <= requiredConfirmations; i++) {
|
||||
@@ -77,19 +80,31 @@ export const useEthTransactionManager = () => {
|
||||
}
|
||||
|
||||
if (requiresConfirmation) {
|
||||
update(transaction.id, { status: EthTxStatus.Complete, receipt });
|
||||
update(transaction.id, {
|
||||
status: EthTxStatus.Complete,
|
||||
receipt,
|
||||
});
|
||||
} else {
|
||||
update(transaction.id, { status: EthTxStatus.Confirmed, receipt });
|
||||
update(transaction.id, {
|
||||
status: EthTxStatus.Confirmed,
|
||||
receipt,
|
||||
notify: true,
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
if (err instanceof Error || isEthereumError(err)) {
|
||||
if (!isExpectedEthereumError(err)) {
|
||||
update(transaction.id, { status: EthTxStatus.Error, error: err });
|
||||
update(transaction.id, {
|
||||
status: EthTxStatus.Error,
|
||||
error: err,
|
||||
notify: true,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
update(transaction.id, {
|
||||
status: EthTxStatus.Error,
|
||||
error: new Error('Something went wrong'),
|
||||
notify: true,
|
||||
});
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -27,7 +27,13 @@ export interface EthStoredTxState extends EthTxState {
|
||||
methodName: ContractMethod;
|
||||
args: string[];
|
||||
requiredConfirmations: number;
|
||||
requiresConfirmation: boolean; // whether or not the tx needs external confirmation (IE from a subscription even)
|
||||
// whether or not the tx needs external confirmation (IE from a subscription even)
|
||||
requiresConfirmation: boolean;
|
||||
// whether or not to notify via toast
|
||||
// true = force open toast
|
||||
// false = force close toast
|
||||
// undefined = leave alone
|
||||
notify: boolean | undefined;
|
||||
assetId?: string;
|
||||
deposit?: DepositBusEventFieldsFragment;
|
||||
withdrawal?: WithdrawalBusEventFieldsFragment;
|
||||
@@ -49,7 +55,7 @@ export interface EthTransactionStore {
|
||||
update?: Partial<
|
||||
Pick<
|
||||
EthStoredTxState,
|
||||
'status' | 'error' | 'receipt' | 'confirmations' | 'txHash'
|
||||
'status' | 'error' | 'receipt' | 'confirmations' | 'txHash' | 'notify'
|
||||
>
|
||||
>
|
||||
) => void;
|
||||
@@ -89,6 +95,7 @@ export const useEthTransactionStore = create<EthTransactionStore>()(
|
||||
requiresConfirmation,
|
||||
assetId,
|
||||
withdrawal,
|
||||
notify: true,
|
||||
};
|
||||
set({ transactions: transactions.concat(transaction) });
|
||||
return transaction.id;
|
||||
@@ -135,6 +142,7 @@ export const useEthTransactionStore = create<EthTransactionStore>()(
|
||||
transaction.deposit = deposit;
|
||||
transaction.dialogOpen = true;
|
||||
transaction.updatedAt = new Date();
|
||||
transaction.notify = true;
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ReactNode } from 'react';
|
||||
import { useEffect } from 'react';
|
||||
import { useAssetsDataProvider } from '@vegaprotocol/assets';
|
||||
import { EtherscanLink } from '@vegaprotocol/environment';
|
||||
import { formatNumber, toBigNum } from '@vegaprotocol/utils';
|
||||
@@ -169,11 +170,13 @@ export const useEthereumTransactionToasts = () => {
|
||||
]);
|
||||
|
||||
const dismissTx = useEthTransactionStore((state) => state.dismiss);
|
||||
const updateTx = useEthTransactionStore((state) => state.update);
|
||||
|
||||
const onClose = useCallback(
|
||||
(tx: EthStoredTxState) => () => {
|
||||
dismissTx(tx.id);
|
||||
removeToast(`eth-${tx.id}`);
|
||||
updateTx(tx.id, { notify: false });
|
||||
// closes related "Funds released" toast after successful withdrawal
|
||||
if (
|
||||
isWithdrawTransaction(tx) &&
|
||||
@@ -183,7 +186,7 @@ export const useEthereumTransactionToasts = () => {
|
||||
closeToastBy({ withdrawalId: tx.withdrawal.id });
|
||||
}
|
||||
},
|
||||
[closeToastBy, dismissTx, removeToast]
|
||||
[closeToastBy, dismissTx, removeToast, updateTx]
|
||||
);
|
||||
|
||||
const fromEthTransaction = useCallback(
|
||||
@@ -213,17 +216,25 @@ export const useEthereumTransactionToasts = () => {
|
||||
loader: [EthTxStatus.Pending, EthTxStatus.Complete].includes(tx.status),
|
||||
content,
|
||||
closeAfter,
|
||||
hidden: !tx.notify,
|
||||
};
|
||||
},
|
||||
[onClose]
|
||||
);
|
||||
|
||||
useEthTransactionStore.subscribe(
|
||||
(state) => compact(state.transactions.filter((tx) => tx?.dialogOpen)),
|
||||
(txs) => {
|
||||
txs.forEach((tx) => {
|
||||
setToast(fromEthTransaction(tx));
|
||||
});
|
||||
}
|
||||
);
|
||||
// Only register a subscription once
|
||||
useEffect(() => {
|
||||
const unsubscribe = useEthTransactionStore.subscribe(
|
||||
(state) => compact(state.transactions.filter((tx) => tx?.dialogOpen)),
|
||||
(txs) => {
|
||||
txs.forEach((tx) => {
|
||||
setToast(fromEthTransaction(tx));
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
return () => {
|
||||
unsubscribe();
|
||||
};
|
||||
}, [fromEthTransaction, setToast]);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user