diff --git a/apps/token/src/routes/router-config.tsx b/apps/token/src/routes/router-config.tsx index 5285a3ad9..253b69d58 100644 --- a/apps/token/src/routes/router-config.tsx +++ b/apps/token/src/routes/router-config.tsx @@ -70,7 +70,7 @@ const LazyStakingAssociate = React.lazy( const LazyStakingDisassociate = React.lazy( () => import( - /* webpackChunkName: "route-staking-disassociate", webpackPrefetch: true */ './staking/disassociate/disassociate-page-container' + /* webpackChunkName: "route-staking-disassociate", webpackPrefetch: true */ './staking/disassociate' ) ); diff --git a/apps/token/src/routes/staking/associate/associate-page-container.tsx b/apps/token/src/routes/staking/associate/associate-page-container.tsx index e629f4194..d8b610504 100644 --- a/apps/token/src/routes/staking/associate/associate-page-container.tsx +++ b/apps/token/src/routes/staking/associate/associate-page-container.tsx @@ -1,5 +1,5 @@ import { useEthereumConfig } from '@vegaprotocol/web3'; -import { StakingWalletsContainer } from '../staking-wallets-container'; +import { StakingWalletsContainer } from '../components/staking-wallets-container/staking-wallets-container'; import { AssociatePage } from './associate-page'; import { AssociatePageNoVega } from './associate-page-no-vega'; diff --git a/apps/token/src/routes/staking/components/staking-wallets-container/index.ts b/apps/token/src/routes/staking/components/staking-wallets-container/index.ts new file mode 100644 index 000000000..91bb920d0 --- /dev/null +++ b/apps/token/src/routes/staking/components/staking-wallets-container/index.ts @@ -0,0 +1 @@ +export { StakingWalletsContainer } from './staking-wallets-container'; diff --git a/apps/token/src/routes/staking/components/staking-wallets-container/staking-wallets-container.spec.tsx b/apps/token/src/routes/staking/components/staking-wallets-container/staking-wallets-container.spec.tsx new file mode 100644 index 000000000..1d8545164 --- /dev/null +++ b/apps/token/src/routes/staking/components/staking-wallets-container/staking-wallets-container.spec.tsx @@ -0,0 +1,82 @@ +import { render, screen } from '@testing-library/react'; +import type { useWeb3React } from '@web3-react/core'; +import { StakingWalletsContainer } from './staking-wallets-container'; + +jest.mock('../../connect-to-vega', () => ({ + ConnectToVega: () =>
, +})); + +jest.mock('../../../../components/eth-connect-prompt', () => ({ + EthConnectPrompt: () =>
, +})); + +const defaultHookValue = { + isActive: false, + error: undefined, + connector: null, + chainId: 3, + account: null, +} as unknown as ReturnType; +let mockHookValue: ReturnType; + +jest.mock('@web3-react/core', () => { + const original = jest.requireActual('@web3-react/core'); + return { + ...original, + useWeb3React: jest.fn(() => mockHookValue), + }; +}); + +let mockVegaWalletHookValue: { + pubKey: string | null; +} = { + pubKey: null, +}; + +jest.mock('@vegaprotocol/wallet', () => ({ + ...jest.requireActual('@vegaprotocol/wallet'), + useVegaWallet: jest.fn(() => mockVegaWalletHookValue), +})); + +const renderComponent = () => { + return render( + + {({ address, pubKey }) => ( +
+
{address}
+
{pubKey}
+
+ )} +
+ ); +}; + +describe('Staking wallets container', () => { + it('should render connect to eth button if not connected', () => { + mockHookValue = defaultHookValue; + renderComponent(); + expect(screen.getByTestId('eth-connect-prompt')).toBeInTheDocument(); + }); + + it('should render connect to vega button if there is no pubkey', () => { + mockHookValue = { + ...defaultHookValue, + account: '0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f', + }; + renderComponent(); + expect(screen.getByTestId('connect-to-vega')).toBeInTheDocument(); + }); + + it('should render children if both are connected', () => { + mockVegaWalletHookValue = { pubKey: 'foo' }; + mockHookValue = { + ...defaultHookValue, + account: '0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f', + }; + renderComponent(); + expect(screen.getByTestId('eth-address')).toHaveTextContent( + '0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f' + ); + expect(screen.getByTestId('vega-pubkey')).toHaveTextContent('foo'); + }); +}); diff --git a/apps/token/src/routes/staking/staking-wallets-container.tsx b/apps/token/src/routes/staking/components/staking-wallets-container/staking-wallets-container.tsx similarity index 57% rename from apps/token/src/routes/staking/staking-wallets-container.tsx rename to apps/token/src/routes/staking/components/staking-wallets-container/staking-wallets-container.tsx index e623634d7..66b5fc197 100644 --- a/apps/token/src/routes/staking/staking-wallets-container.tsx +++ b/apps/token/src/routes/staking/components/staking-wallets-container/staking-wallets-container.tsx @@ -1,24 +1,20 @@ import { useWeb3React } from '@web3-react/core'; import { useTranslation } from 'react-i18next'; -import { EthConnectPrompt } from '../../components/eth-connect-prompt'; +import { EthConnectPrompt } from '../../../../components/eth-connect-prompt'; import { useVegaWallet } from '@vegaprotocol/wallet'; -import { ConnectToVega } from './connect-to-vega'; +import { ConnectToVega } from '../../connect-to-vega'; export const StakingWalletsContainer = ({ - needsEthereum, - needsVega, children, }: { - needsEthereum?: boolean; - needsVega?: boolean; children: (data: { address: string; pubKey: string }) => React.ReactElement; }) => { const { t } = useTranslation(); const { account } = useWeb3React(); const { pubKey } = useVegaWallet(); - if (!account && needsEthereum) { + if (!account) { return (

{t('associateInfo1')}

@@ -27,16 +23,8 @@ export const StakingWalletsContainer = ({ ); } - if (!pubKey || needsVega) { - return ( - <> - -

{t('associateInfo1')}

-

{t('associateInfo2')}

-
- - - ); + if (!pubKey) { + return ; } return children({ address: account || '', pubKey }); diff --git a/apps/token/src/routes/staking/disassociate/disassociate-page.tsx b/apps/token/src/routes/staking/disassociate/components/disassociate-page/disassociate-page.tsx similarity index 85% rename from apps/token/src/routes/staking/disassociate/disassociate-page.tsx rename to apps/token/src/routes/staking/disassociate/components/disassociate-page/disassociate-page.tsx index 84e8bd34d..2e90eb5e4 100644 --- a/apps/token/src/routes/staking/disassociate/disassociate-page.tsx +++ b/apps/token/src/routes/staking/disassociate/components/disassociate-page/disassociate-page.tsx @@ -1,19 +1,19 @@ -import { DisassociateTransaction } from './disassociate-transaction'; -import { formatNumber } from '../../../lib/format-number'; +import { DisassociateTransaction } from '../disassociate-transaction'; +import { formatNumber } from '../../../../../lib/format-number'; import { remove0x, toBigNum } from '@vegaprotocol/react-helpers'; import { Select } from '@vegaprotocol/ui-toolkit'; -import { StakingMethod } from '../../../components/staking-method-radio'; -import { TokenInput } from '../../../components/token-input'; -import { TxState } from '../../../hooks/transaction-reducer'; -import { useAppState } from '../../../contexts/app-state/app-state-context'; -import { useRefreshAssociatedBalances } from '../../../hooks/use-refresh-associated-balances'; -import { useRemoveStake } from './hooks'; -import type { RemoveStakePayload } from './hooks'; +import { StakingMethod } from '../../../../../components/staking-method-radio'; +import { TokenInput } from '../../../../../components/token-input'; +import { TxState } from '../../../../../hooks/transaction-reducer'; +import { useAppState } from '../../../../../contexts/app-state/app-state-context'; +import { useRefreshAssociatedBalances } from '../../../../../hooks/use-refresh-associated-balances'; +import { useRemoveStake } from '../../hooks'; +import type { RemoveStakePayload } from '../../hooks'; import { useState, useEffect, useMemo, useCallback } from 'react'; import type { ChangeEvent } from 'react'; import { useTranslation } from 'react-i18next'; -import type { BigNumber } from '../../../lib/bignumber'; -import { truncateMiddle } from '../../../lib/truncate-middle'; +import type { BigNumber } from '../../../../../lib/bignumber'; +import { truncateMiddle } from '../../../../../lib/truncate-middle'; type Association = { /** @@ -68,7 +68,7 @@ export const DisassociatePage = ({ ...toListOfAssociations(vestingAssociations, StakingMethod.Contract), ].map((a) => ({ ...a, - label: `${truncateMiddle(a.key)} ${t(`via${a.stakingMethod}`)} + label: `${truncateMiddle(a.key)} ${t(`via${a.stakingMethod}`)} (${formatNumber(a.amount, 18)} ${t('tokens')})`, })), [stakingAssociations, vestingAssociations, t] diff --git a/apps/token/src/routes/staking/disassociate/components/disassociate-page/index.ts b/apps/token/src/routes/staking/disassociate/components/disassociate-page/index.ts new file mode 100644 index 000000000..3e89dc133 --- /dev/null +++ b/apps/token/src/routes/staking/disassociate/components/disassociate-page/index.ts @@ -0,0 +1 @@ +export { DisassociatePage } from './disassociate-page'; diff --git a/apps/token/src/routes/staking/disassociate/disassociate-transaction.tsx b/apps/token/src/routes/staking/disassociate/components/disassociate-transaction/disassociate-transaction.tsx similarity index 79% rename from apps/token/src/routes/staking/disassociate/disassociate-transaction.tsx rename to apps/token/src/routes/staking/disassociate/components/disassociate-transaction/disassociate-transaction.tsx index 1049884f1..97939943d 100644 --- a/apps/token/src/routes/staking/disassociate/disassociate-transaction.tsx +++ b/apps/token/src/routes/staking/disassociate/components/disassociate-transaction/disassociate-transaction.tsx @@ -3,14 +3,14 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { Link } from 'react-router-dom'; -import { StakingMethod } from '../../../components/staking-method-radio'; -import { TransactionCallout } from '../../../components/transaction-callout'; +import { StakingMethod } from '../../../../../components/staking-method-radio'; +import { TransactionCallout } from '../../../../../components/transaction-callout'; import type { TransactionAction, TransactionState, -} from '../../../hooks/transaction-reducer'; -import { TransactionActionType } from '../../../hooks/transaction-reducer'; -import Routes from '../../routes'; +} from '../../../../../hooks/transaction-reducer'; +import { TransactionActionType } from '../../../../../hooks/transaction-reducer'; +import Routes from '../../../../routes'; export const DisassociateTransaction = ({ amount, diff --git a/apps/token/src/routes/staking/disassociate/components/disassociate-transaction/index.tsx b/apps/token/src/routes/staking/disassociate/components/disassociate-transaction/index.tsx new file mode 100644 index 000000000..63a9d6092 --- /dev/null +++ b/apps/token/src/routes/staking/disassociate/components/disassociate-transaction/index.tsx @@ -0,0 +1 @@ +export { DisassociateTransaction } from './disassociate-transaction'; diff --git a/apps/token/src/routes/staking/disassociate/disassociate-page-container.tsx b/apps/token/src/routes/staking/disassociate/disassociate-page-container.tsx deleted file mode 100644 index 4469ab146..000000000 --- a/apps/token/src/routes/staking/disassociate/disassociate-page-container.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { StakingWalletsContainer } from '../staking-wallets-container'; -import { DisassociatePage } from './disassociate-page'; - -export const DisassociateContainer = () => { - return ( - - {({ address, pubKey }) => ( - - )} - - ); -}; - -export default DisassociateContainer; diff --git a/apps/token/src/routes/staking/disassociate/index.spec.tsx b/apps/token/src/routes/staking/disassociate/index.spec.tsx new file mode 100644 index 000000000..1d64391e6 --- /dev/null +++ b/apps/token/src/routes/staking/disassociate/index.spec.tsx @@ -0,0 +1,71 @@ +import { render, screen } from '@testing-library/react'; +import type { useWeb3React } from '@web3-react/core'; +import Disassociate from './index'; + +jest.mock('../../../components/eth-connect-prompt', () => ({ + EthConnectPrompt: () =>
, +})); + +jest.mock('./components/disassociate-page', () => ({ + DisassociatePage: () =>
, +})); + +const defaultHookValue = { + isActive: false, + error: undefined, + connector: null, + chainId: 3, + account: null, +} as unknown as ReturnType; +let mockHookValue: ReturnType; + +jest.mock('@web3-react/core', () => { + const original = jest.requireActual('@web3-react/core'); + return { + ...original, + useWeb3React: jest.fn(() => mockHookValue), + }; +}); + +let mockVegaWalletHookValue: { + pubKey: string | null; +} = { + pubKey: null, +}; + +jest.mock('@vegaprotocol/wallet', () => ({ + ...jest.requireActual('@vegaprotocol/wallet'), + useVegaWallet: jest.fn(() => mockVegaWalletHookValue), +})); + +const renderComponent = () => { + return render(); +}; + +describe('Disassociate', () => { + it('should render connect to eth button if not connected', () => { + mockHookValue = defaultHookValue; + renderComponent(); + expect(screen.getByTestId('eth-connect-prompt')).toBeInTheDocument(); + }); + + it('should render disassociate page if eth wallet is connected and vega wallet is not', () => { + mockHookValue = { + ...defaultHookValue, + account: 'foo', + }; + renderComponent(); + expect(screen.queryByTestId('eth-connect-prompt')).toBeFalsy(); + expect(screen.getByTestId('disassociate-page')).toBeInTheDocument(); + }); + + it('should render disassociate page if both wallets connected', () => { + mockHookValue = { + ...defaultHookValue, + account: 'foo', + }; + mockVegaWalletHookValue = { pubKey: 'foo' }; + renderComponent(); + expect(screen.getByTestId('disassociate-page')).toBeInTheDocument(); + }); +}); diff --git a/apps/token/src/routes/staking/disassociate/index.tsx b/apps/token/src/routes/staking/disassociate/index.tsx new file mode 100644 index 000000000..436d0370e --- /dev/null +++ b/apps/token/src/routes/staking/disassociate/index.tsx @@ -0,0 +1,17 @@ +import { useVegaWallet } from '@vegaprotocol/wallet'; +import { useWeb3React } from '@web3-react/core'; +import { EthConnectPrompt } from '../../../components/eth-connect-prompt'; +import { DisassociatePage } from './components/disassociate-page'; + +export const DisassociateContainer = () => { + const { account } = useWeb3React(); + const { pubKey } = useVegaWallet(); + + if (!account) { + return ; + } + + return ; +}; + +export default DisassociateContainer; diff --git a/apps/token/src/routes/staking/staking-node.tsx b/apps/token/src/routes/staking/staking-node.tsx index a2d57be75..9e0bae849 100644 --- a/apps/token/src/routes/staking/staking-node.tsx +++ b/apps/token/src/routes/staking/staking-node.tsx @@ -7,29 +7,25 @@ import { BigNumber } from '../../lib/bignumber'; import type { Staking as StakingQueryResult } from './__generated__/Staking'; import { ConnectToVega } from './connect-to-vega'; import { StakingForm } from './staking-form'; -import { StakingNodesContainer } from './staking-nodes-container'; -import { StakingWalletsContainer } from './staking-wallets-container'; import { ValidatorTable } from './validator-table'; import { YourStake } from './your-stake'; +import StakingNodesContainer from './staking-nodes-container'; +import { useVegaWallet } from '@vegaprotocol/wallet'; export const StakingNodeContainer = () => { return ( - - {({ pubKey }) => ( - - {({ data }) => } - - )} - + + {({ data }) => } + ); }; interface StakingNodeProps { - pubKey: string; data?: StakingQueryResult; } -export const StakingNode = ({ pubKey: vegaKey, data }: StakingNodeProps) => { +export const StakingNode = ({ data }: StakingNodeProps) => { + const { pubKey: vegaKey } = useVegaWallet(); const { node } = useParams<{ node: string }>(); const { t } = useTranslation(); diff --git a/apps/token/src/routes/staking/staking-nodes-container.tsx b/apps/token/src/routes/staking/staking-nodes-container.tsx index a2a8cc988..6f40c2efa 100644 --- a/apps/token/src/routes/staking/staking-nodes-container.tsx +++ b/apps/token/src/routes/staking/staking-nodes-container.tsx @@ -85,7 +85,6 @@ export const StakingNodesContainer = ({ STAKING_QUERY, { variables: { partyId: pubKey || '' }, - skip: !pubKey, } );