Compare commits

...
Author SHA1 Message Date
Matthew Russell 529a724f6b chore: add wait for dialog to display 2024-03-01 09:59:15 +00:00
Matthew Russell 851f721934 chore: remove test for view as pubkey using query string 2024-03-01 09:30:20 +00:00
Matthew Russell 96821f8f04 fix: add wallet to i18n default namespaces 2024-03-01 08:51:03 +00:00
Matthew Russell 8d39981eb7 chore: fixes for cypress 2024-02-29 16:21:29 +00:00
Matthew Russell fe67a83a96 chore: add wallet-react to i18n namespace so its immediately loaded 2024-02-29 16:21:29 +00:00
Matthew Russell e4756c5d68 chore: adjust wallet store config for cypress testsw 2024-02-29 16:21:29 +00:00
Matthew Russell eeedc19e8b fix: tests 2024-02-29 16:21:29 +00:00
Matthew Russell d50dc4dbdd chore: remove pointless return type for disconnect connector method 2024-02-29 16:21:29 +00:00
Matthew Russell f96e423e15 chore: fix incorrect testnet prop for mainnet 2024-02-29 16:21:29 +00:00
bwallacee 45a74680c9 chore(trading): fix e2e tests 2024-02-29 16:21:29 +00:00
Matthew Russell 766012e389 chore: switch to use eventemitter3 as its already bundled 2024-02-29 16:21:29 +00:00
Matthew Russell d16deb4c19 chore: simplify window.ethereum check 2024-02-29 16:21:29 +00:00
Matthew Russell 7d5addad2e chore: make methods only needed for snap/json-rpc private 2024-02-29 16:21:29 +00:00
Matthew Russell b698bd2e40 fix: add more context to errors, fix stack, and proposal error dialog 2024-02-29 16:21:29 +00:00
Matthew Russell 996a29690f fix: ensure propose tx dialog can be closed 2024-02-29 16:21:29 +00:00
bwallacee 5ee54e7cc2 chore(trading): fix default pub key for python tests 2024-02-29 16:21:29 +00:00
Matthew Russell 6d7a63e0e6 chore: fix lint 2024-02-29 16:21:29 +00:00
Matthew Russell 5c03450463 chore: fix lint 2024-02-29 16:21:29 +00:00
bwallacee 64c8af8cb0 chore(trading): fix wallet store for e2e test 2024-02-29 16:21:28 +00:00
Matthew Russell a06b861724 chore: change view party to view as public key 2024-02-29 16:21:28 +00:00
Matthew Russell e2cde1efb6 fix: explore button not dismissing dialog 2024-02-29 16:21:28 +00:00
Matthew Russell 7b9645a603 fix: risk ack layout 2024-02-29 16:21:28 +00:00
Matthew Russell 0352096e78 feat: make browser wallet icon bg always black 2024-02-29 16:21:28 +00:00
Matthew Russell f7a423205c fix: tooltips 2024-02-29 16:21:28 +00:00
Matthew Russell 866afe0a82 fix: throw correct error for send transaction 2024-02-29 16:21:28 +00:00
Matthew Russell 6443a7ea35 chore: move errors to own file 2024-02-29 16:21:28 +00:00
Matthew Russell 538927fe19 fix: propsal spec 2024-02-29 16:21:28 +00:00
Matthew Russell 4c28bfa60c chore: use connector error for use-vega-transaction hook 2024-02-29 16:21:28 +00:00
Matthew Russell 01e2902239 fix: layout and functionality on mobile 2024-02-29 16:21:28 +00:00
Matthew Russell 7c84e62532 chore: add comment for extension detection 2024-02-29 16:21:28 +00:00
Matthew Russell c5e33d01f2 chore: delete no longer required snap status hook 2024-02-29 16:21:28 +00:00
Matthew Russell a2b5f54fb7 feat: dry up connection option ui 2024-02-29 16:21:28 +00:00
Matthew Russell db2eb4d0dd fix: hit box for dont have wallet link 2024-02-29 16:21:28 +00:00
Matthew Russell 64d327c3f2 fix: snap not working in firefox 2024-02-29 16:21:28 +00:00
Matthew Russell 66bff41e0b fix: snap version 2024-02-29 16:21:28 +00:00
Matthew Russell ec8e4e2b58 fix: remove translations 2024-02-29 16:21:28 +00:00
Matthew Russell f6c0031403 fix: swap wallet link in for welcome dialog 2024-02-29 16:21:28 +00:00
Matthew Russell 09e678e151 fix: re add reconnect toast if wallet becomes disconnected 2024-02-29 16:21:28 +00:00
Matthew Russell 8fde527e05 feat: fix disconnected toast by adding polling for snap and json rpc connectors 2024-02-29 16:21:28 +00:00
Matthew Russell 6d484907f7 fix: polling in snap connector 2024-02-29 16:21:28 +00:00
Matthew Russell 4336e2f1f7 fix: remove unnecessary ts-ignore 2024-02-29 16:21:28 +00:00
Matthew Russell 2af090f2ba chore: handle custom connection option better 2024-02-29 16:21:28 +00:00
Matthew Russell 7ea69b3a85 fix: deal ticket stop order ts-ignores 2024-02-29 16:21:28 +00:00
Matthew Russell 38a33dddf3 feat: switch vega wallet button to link if not installed 2024-02-29 16:21:28 +00:00
Matthew Russell 4719703481 chore: remove hard coded translations 2024-02-29 16:21:28 +00:00
Matthew Russell 2bed3d5c26 fix: types in snap connector 2024-02-29 16:21:28 +00:00
Matthew Russell 0e55e50dc4 chore: rename read only connector to view-party 2024-02-29 16:21:28 +00:00
Matthew Russell 2b9a002248 feat: re add view as connection to sidebar 2024-02-29 16:21:28 +00:00
Matthew Russell 5ac0917764 fix: useVegaWallet sendTx func, remove unused code 2024-02-29 16:21:28 +00:00
Matthew Russell dbc535ddfc chore: split onboarding store from onboarding step hook 2024-02-29 16:21:28 +00:00
Matthew Russell f5ec7277bd chore: readonly connector typescript error 2024-02-29 16:21:27 +00:00
Matthew Russell cb59fb741a fix: use hooks for connectors which depend on VEGA_ENV 2024-02-29 16:21:27 +00:00
Matthew Russell 8bf9e17fdd chore: minor misc fixes 2024-02-29 16:21:27 +00:00
Matthew Russell 9f211bc5ba feat: use risk dialog in governance 2024-02-29 16:21:27 +00:00
Matthew Russell 6ddbe5486a chore: move risk act to wallet-react 2024-02-29 16:21:27 +00:00
Matthew Russell af42a78bcd chore: dont show risk ack if not mainnet 2024-02-29 16:21:27 +00:00
Matthew Russell 5ee813e65e feat: make titles consistent, fix interaction between dialogs 2024-02-29 16:21:27 +00:00
Matthew Russell 7ea8544473 feat: add dont have wallet link to welcome dialog 2024-02-29 16:21:27 +00:00
Matthew Russell 5f4c7388cd feat: wrap connect dialog so to show risk ack 2024-02-29 16:21:27 +00:00
Matthew Russell 1b478364d1 feat: add risk acknowledgement to onboarding 2024-02-29 16:21:27 +00:00
Matthew Russell 24c5afc1dc chore: re-enable telemetry 2024-02-29 16:21:27 +00:00
Matthew Russell d3079b5cfa feat: add link to wallet page 2024-02-29 16:21:27 +00:00
Matthew Russell 72236c35e9 feat: change injected icon color depending on network 2024-02-29 16:21:27 +00:00
Matthew Russell 78b6966e36 fix: broken tests due to mockKeys 2024-02-29 16:21:27 +00:00
Matthew Russell 28a4455f42 refactor: dialog store properties 2024-02-29 16:21:27 +00:00
Matthew Russell 08b32553a1 chore: remove view as sidebar button 2024-02-29 16:21:27 +00:00
Matthew Russell a76899f581 chore: fix components after rebase 2024-02-29 16:21:27 +00:00
Matthew Russell ce8d3adf13 test: add test for connector dialog 2024-02-29 16:21:27 +00:00
Matthew Russell 56005fa522 chore: move translations to wallet react lib 2024-02-29 16:21:27 +00:00
Matthew Russell 443732d0df chore: remove unused test setup 2024-02-29 16:21:27 +00:00
Matthew Russell f432386398 test: add tests for wallet config 2024-02-29 16:21:27 +00:00
Matthew Russell b84f62b73d chore: add some ts-ignore for readonly instances 2024-02-29 16:21:27 +00:00
Matthew Russell 0b75aefeb6 fix: additional entry point config 2024-02-29 16:21:27 +00:00
Matthew Russell 5073416e21 chore: fix types of mocked browser wallet 2024-02-29 16:21:27 +00:00
Matthew Russell 48f50ce92c fix: status check after connect 2024-02-29 16:21:27 +00:00
Matthew Russell 7e29b30312 chore: fix user rejected error test for transaction hook 2024-02-29 16:21:27 +00:00
Matthew Russell e6d0c406f2 fix: create separate entry point so mock config isnt bundled 2024-02-29 16:21:27 +00:00
Matthew Russell de6575659b fix: tx handling for use-transaction hook in proposals 2024-02-29 16:21:27 +00:00
Matthew Russell b9643afed5 chore: dont create mock config in module 2024-02-29 16:21:27 +00:00
Matthew Russell a332246da3 chore: remove @vegaprotocol/wallet-client 2024-02-29 16:21:27 +00:00
Matthew Russell 94937f3593 feat: improve error handling 2024-02-29 16:21:27 +00:00
Matthew Russell 7b82882fdc feat: make consistent errors for connectors 2024-02-29 16:21:26 +00:00
Matthew Russell d1ec5f5136 feat: dialog layout 2024-02-29 16:21:26 +00:00
Matthew Russell 0add85690b feat: hover states for dialogs 2024-02-29 16:21:26 +00:00
Matthew Russell 38962f397f chore: re add welcome dialog 2024-02-29 16:21:26 +00:00
Matthew Russell 3ef9b9f8af fix: tests relying on mocks for wallet 2024-02-29 16:21:26 +00:00
Matthew Russell 49a0cec9df refactor: mocked provider 2024-02-29 16:21:26 +00:00
Matthew Russell 6e0df4678d chore: convert tests to mock provider 2024-02-29 16:21:26 +00:00
Matthew Russell 50295dc040 chore: WIP amend me, changed to mocked provider component 2024-02-29 16:21:26 +00:00
Matthew Russell 871bfb0a40 fix: ensure on event not binded twice, remove unused method 2024-02-29 16:21:26 +00:00
Matthew Russell e49148b203 chore: add missing test setup for i18n funding payments 2024-02-29 16:21:26 +00:00
Matthew Russell 77453881e4 fix: gov tests after removing linked transaction dialog 2024-02-29 16:21:26 +00:00
Matthew Russell 642175d183 chore: dont render dialog from hook 2024-02-29 16:21:26 +00:00
Matthew Russell b45db36f7f fix: web3 test fixes 2024-02-29 16:21:26 +00:00
Matthew Russell 9846a30475 fix: orders tests 2024-02-29 16:21:26 +00:00
Matthew Russell 33612d22dc fix: deal ticket and deposit tests 2024-02-29 16:21:26 +00:00
Matthew Russell 07278f15e8 fix: governance tests 2024-02-29 16:21:26 +00:00
Matthew Russell 4df801f067 chore: fix imports 2024-02-29 16:21:25 +00:00
Matthew Russell fd919ebc21 fix: tests and welcome dialog 2024-02-29 16:20:15 +00:00
Matthew Russell c62f189982 chore: re add welcome dialog 2024-02-29 16:20:15 +00:00
Matthew Russell ed7d9678c0 fix: navbar test 2024-02-29 16:20:15 +00:00
Matthew Russell 5fb542daf5 fix: imports and add vega global 2024-02-29 16:20:15 +00:00
Matthew Russell bdbdf309b6 fix: connect button tests 2024-02-29 16:20:15 +00:00
Matthew Russell 5fde0d3b3e fix: imports 2024-02-29 16:20:15 +00:00
Matthew Russell 1b0780d6ba chore: conver apps/trading wallet imports 2024-02-29 16:20:15 +00:00
Matthew Russell 8fa808051a chore: add wallet react lib 2024-02-29 16:20:15 +00:00
Matthew Russell f43a59817f chore: remove hooks we dont need anymore 2024-02-29 16:20:14 +00:00
Matthew Russell ab5d3fe2b1 fix: wallet not running error and key refresh 2024-02-29 16:20:14 +00:00
Matthew Russell e245675a79 chore: rename v2 to default, move manage dialog 2024-02-29 16:20:14 +00:00
Matthew Russell 0ab83d6248 feat: update useVegaWallet usage where needed 2024-02-29 16:20:14 +00:00
Matthew Russell 2c505c7500 feat: try connector id type, adjust dialog layout 2024-02-29 16:20:14 +00:00
Matthew Russell b9d031c573 feat: bind listener for injected connector 2024-02-29 16:20:14 +00:00
Matthew Russell f8cd249fe1 feat: bind store to connectors to access local storage values 2024-02-29 16:20:14 +00:00
Matthew Russell a3380407b1 refactor: change to use slice for single key 2024-02-29 16:20:14 +00:00
Matthew Russell 7c5ac31b73 feat: add some ui for the connect dialog v2 2024-02-29 16:20:14 +00:00
Matthew Russell 30bc99a455 feat: eager connection 2024-02-29 16:20:14 +00:00
Matthew Russell c7560eff7e feat: connect dialog rewrite start, add wrapper hook for selected key 2024-02-29 16:20:14 +00:00
Matthew Russell c6e6021f01 chore: start moving code to lib 2024-02-29 16:20:14 +00:00
Matthew Russell bacea950fb chore: wire up sendTransaction 2024-02-29 16:20:14 +00:00
Matthew Russell 4e38be7763 chore: remove unused reconnecting 2024-02-29 16:20:14 +00:00
Matthew Russell 906fbbabc2 feat: refactor wallet store and connections 2024-02-29 16:20:14 +00:00
285 changed files with 4526 additions and 5917 deletions
@@ -34,12 +34,6 @@ context('View functionality with public key', { tags: '@smoke' }, function () {
cy.connectPublicKey(vegaWalletPubKey);
});
it('Able to connect public key using url', function () {
cy.getByTestId('exit-view').click();
cy.visit(`/?address=${vegaWalletPubKey}`);
verifyConnectedToPubKey();
});
it.skip('Able to connect public key via wallet and view assets in wallet', function () {
verifyConnectedToPubKey();
cy.getByTestId('currency-title', { timeout: 10000 })
+2 -16
View File
@@ -1,7 +1,7 @@
import * as Sentry from '@sentry/react';
import { toBigNum } from '@vegaprotocol/utils';
import { Splash } from '@vegaprotocol/ui-toolkit';
import { useVegaWallet, useEagerConnect } from '@vegaprotocol/wallet';
import { useVegaWallet, useEagerConnect } from '@vegaprotocol/wallet-react';
import { useFeatureFlags, useEnvironment } from '@vegaprotocol/environment';
import { useWeb3React } from '@web3-react/core';
import React, { Suspense } from 'react';
@@ -15,20 +15,6 @@ import {
} from './contexts/app-state/app-state-context';
import { useContracts } from './contexts/contracts/contracts-context';
import { useRefreshAssociatedBalances } from './hooks/use-refresh-associated-balances';
import { useConnectors } from './lib/vega-connectors';
import { useSearchParams } from 'react-router-dom';
const useVegaWalletEagerConnect = () => {
const connectors = useConnectors();
const vegaConnecting = useEagerConnect(connectors);
const { pubKey, connect } = useVegaWallet();
const [searchParams] = useSearchParams();
const [query] = React.useState(searchParams.get('address'));
if (query && !pubKey) {
connect(connectors.view);
}
return vegaConnecting;
};
export const AppLoader = ({ children }: { children: React.ReactElement }) => {
const featureFlags = useFeatureFlags((state) => state.flags);
@@ -40,7 +26,7 @@ export const AppLoader = ({ children }: { children: React.ReactElement }) => {
const { token, staking, vesting } = useContracts();
const setAssociatedBalances = useRefreshAssociatedBalances();
const [balancesLoaded, setBalancesLoaded] = React.useState(false);
const vegaConnecting = useVegaWalletEagerConnect();
const vegaConnecting = useEagerConnect();
const loaded = balancesLoaded && !vegaConnecting;
+31 -141
View File
@@ -1,7 +1,6 @@
import './i18n';
import React, { useEffect } from 'react';
import * as Sentry from '@sentry/react';
import { BrowserRouter as Router, useLocation } from 'react-router-dom';
import { AppLoader } from './app-loader';
import { NetworkInfo } from '@vegaprotocol/network-info';
@@ -26,7 +25,7 @@ import {
} from '@vegaprotocol/web3';
import { Web3Provider } from '@vegaprotocol/web3';
import { VegaWalletDialogs } from './components/vega-wallet-dialogs';
import { VegaWalletProvider, useChainId } from '@vegaprotocol/wallet';
import { WalletProvider } from '@vegaprotocol/wallet-react';
import {
useVegaTransactionManager,
useVegaTransactionUpdater,
@@ -36,26 +35,21 @@ import { useEthereumConfig } from '@vegaprotocol/web3';
import {
useEnvironment,
NetworkLoader,
useInitializeEnv,
NodeGuard,
NodeSwitcherDialog,
useNodeSwitcherStore,
DocsLinks,
NodeFailure,
AppLoader as Loader,
useInitializeEnv,
} from '@vegaprotocol/environment';
import { ENV } from './config';
import type { InMemoryCacheConfig } from '@apollo/client';
import { CreateWithdrawalDialog } from '@vegaprotocol/withdraws';
import { SplashLoader } from './components/splash-loader';
import { ToastsManager } from './toasts-manager';
import {
TelemetryDialog,
TELEMETRY_ON,
} from './components/telemetry-dialog/telemetry-dialog';
import { useLocalStorage } from '@vegaprotocol/react-helpers';
import { TelemetryDialog } from './components/telemetry-dialog/telemetry-dialog';
import { useTranslation } from 'react-i18next';
import { isPartyNotFoundError } from './lib/party';
import { useSentryInit } from './hooks/use-sentry-init';
import { useVegaWalletConfig } from './hooks/use-vega-wallet-config';
const cache: InMemoryCacheConfig = {
typePolicies: {
@@ -104,32 +98,12 @@ const Web3Container = ({
/** Ethereum provider url */
providerUrl: string;
}) => {
const InitializeHandlers = () => {
useVegaTransactionManager();
useVegaTransactionUpdater();
useEthTransactionManager();
useEthTransactionUpdater();
useEthWithdrawApprovalsManager();
return null;
};
const [connectors, initializeConnectors] = useWeb3ConnectStore((store) => [
store.connectors,
store.initialize,
]);
const {
ETHEREUM_PROVIDER_URL,
ETH_LOCAL_PROVIDER_URL,
ETH_WALLET_MNEMONIC,
VEGA_ENV,
VEGA_URL,
VEGA_EXPLORER_URL,
CHROME_EXTENSION_URL,
MOZILLA_EXTENSION_URL,
VEGA_WALLET_URL,
} = useEnvironment();
const vegaChainId = useChainId(VEGA_URL);
const { ETHEREUM_PROVIDER_URL, ETH_LOCAL_PROVIDER_URL, ETH_WALLET_MNEMONIC } =
useEnvironment();
useEffect(() => {
if (chainId) {
@@ -150,50 +124,31 @@ const Web3Container = ({
ETH_LOCAL_PROVIDER_URL,
ETH_WALLET_MNEMONIC,
]);
const sideBar = React.useMemo(() => {
return [<EthWallet />, <VegaWallet />];
}, []);
if (connectors.length === 0) {
const vegaWalletConfig = useVegaWalletConfig();
if (!vegaWalletConfig || connectors.length === 0) {
// Prevent loading when the connectors are not initialized
return <SplashLoader />;
}
if (
!VEGA_URL ||
!VEGA_WALLET_URL ||
!VEGA_EXPLORER_URL ||
!DocsLinks ||
!CHROME_EXTENSION_URL ||
!MOZILLA_EXTENSION_URL ||
!vegaChainId
) {
return null;
}
return (
<Web3Provider connectors={connectors}>
<Web3Connector connectors={connectors} chainId={Number(chainId)}>
<VegaWalletProvider
config={{
network: VEGA_ENV,
vegaUrl: VEGA_URL,
chainId: vegaChainId,
vegaWalletServiceUrl: VEGA_WALLET_URL,
links: {
explorer: VEGA_EXPLORER_URL,
concepts: DocsLinks?.VEGA_WALLET_CONCEPTS_URL,
chromeExtensionUrl: CHROME_EXTENSION_URL,
mozillaExtensionUrl: MOZILLA_EXTENSION_URL,
},
}}
>
<WalletProvider config={vegaWalletConfig}>
<ContractsProvider>
<AppLoader>
<BalanceManager>
<>
<AppLayout>
<TemplateSidebar sidebar={sideBar}>
<TemplateSidebar
sidebar={
<>
<EthWallet />
<VegaWallet />
</>
}
>
<AppRouter />
</TemplateSidebar>
<footer className="p-4 break-all border-t border-neutral-700">
@@ -211,7 +166,7 @@ const Web3Container = ({
</BalanceManager>
</AppLoader>
</ContractsProvider>
</VegaWalletProvider>
</WalletProvider>
</Web3Connector>
</Web3Provider>
);
@@ -231,20 +186,9 @@ const ScrollToTop = () => {
return null;
};
const removeQueryParams = (url: string) => {
return url.split('?')[0];
};
const AppContainer = () => {
const { config, loading, error } = useEthereumConfig();
const {
VEGA_ENV,
VEGA_URL,
GIT_COMMIT_HASH,
GIT_BRANCH,
ETHEREUM_PROVIDER_URL,
} = useEnvironment();
const [telemetryOn] = useLocalStorage(TELEMETRY_ON);
const { VEGA_URL, ETHEREUM_PROVIDER_URL } = useEnvironment();
const { t } = useTranslation();
const [nodeSwitcherOpen, setNodeSwitcher] = useNodeSwitcherStore((store) => [
store.dialogOpen,
@@ -254,70 +198,7 @@ const AppContainer = () => {
// Hacky skip all the loading & web3 init for geo restricted users
const isRestricted = document?.location?.pathname?.includes('/restricted');
useEffect(() => {
if (ENV.dsn && telemetryOn === 'true') {
Sentry.init({
dsn: ENV.dsn,
tracesSampleRate: 0.1,
enabled: true,
environment: VEGA_ENV,
release: GIT_COMMIT_HASH,
beforeSend(event, hint) {
const error = hint?.originalException;
const errorIsString = typeof error === 'string';
const errorIsObject = error instanceof Error;
const requestUrl = event.request?.url;
const transaction = event.transaction;
if (
(errorIsString && isPartyNotFoundError({ message: error })) ||
(errorIsObject && isPartyNotFoundError(error))
) {
// This error is caused by a pubkey making an API request before
// it has interacted with the chain. This isn't needed in Sentry.
return null;
}
const updatedRequest =
requestUrl && requestUrl.includes('/claim?')
? { ...event.request, url: removeQueryParams(requestUrl) }
: event.request;
const updatedTransaction =
transaction && transaction.includes('/claim?')
? removeQueryParams(transaction)
: transaction;
const updatedBreadcrumbs = event.breadcrumbs?.map((breadcrumb) => {
if (
breadcrumb.type === 'navigation' &&
breadcrumb.data?.to?.includes('/claim?')
) {
return {
...breadcrumb,
data: {
...breadcrumb.data,
to: removeQueryParams(breadcrumb.data.to),
},
};
}
return breadcrumb;
});
return {
...event,
request: updatedRequest,
transaction: updatedTransaction,
breadcrumbs: updatedBreadcrumbs ?? event.breadcrumbs,
};
},
});
Sentry.setTag('branch', GIT_BRANCH);
Sentry.setTag('commit', GIT_COMMIT_HASH);
} else {
Sentry.close();
}
}, [GIT_COMMIT_HASH, GIT_BRANCH, VEGA_ENV, telemetryOn]);
useSentryInit();
if (isRestricted) {
return (
@@ -359,6 +240,15 @@ const AppContainer = () => {
);
};
const InitializeHandlers = () => {
useVegaTransactionManager();
useVegaTransactionUpdater();
useEthTransactionManager();
useEthTransactionUpdater();
useEthWithdrawApprovalsManager();
return null;
};
function App() {
useInitializeEnv();
@@ -7,7 +7,7 @@ import { useGetAssociationBreakdown } from '../../hooks/use-get-association-brea
import { useGetUserBalances } from '../../hooks/use-get-user-balances';
import { useBalances } from '../../lib/balances/balances-store';
import type { ReactElement } from 'react';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { useListenForStakingEvents as useListenForAssociationEvents } from '../../hooks/use-listen-for-staking-events';
import { useTranches } from '../../lib/tranches/tranches-store';
import { useUserTrancheBalances } from '../../routes/redemption/hooks';
@@ -1,18 +1,13 @@
import { Button } from '@vegaprotocol/ui-toolkit';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { useVegaWalletDialogStore } from '@vegaprotocol/wallet';
import { useDialogStore } from '@vegaprotocol/wallet-react';
export const ConnectToVega = () => {
const { t } = useTranslation();
const { openVegaWalletDialog } = useVegaWalletDialogStore((store) => ({
openVegaWalletDialog: store.openVegaWalletDialog,
}));
const openVegaWalletDialog = useDialogStore((store) => store.open);
return (
<Button
onClick={() => {
openVegaWalletDialog();
}}
onClick={openVegaWalletDialog}
data-testid="connect-to-vega-wallet-btn"
variant="primary"
>
@@ -6,8 +6,8 @@ import {
Intent,
Icon,
} from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '../use-vega-wallet';
import { useT } from '../use-t';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { useTranslation } from 'react-i18next';
export interface VegaManageDialogProps {
dialogOpen: boolean;
@@ -18,7 +18,7 @@ export const VegaManageDialog = ({
dialogOpen,
setDialogOpen,
}: VegaManageDialogProps) => {
const t = useT();
const { t } = useTranslation();
const { pubKey, pubKeys, selectPubKey, disconnect } = useVegaWallet();
return (
<Dialog
@@ -1,5 +1,5 @@
import classNames from 'classnames';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import type { ReactNode } from 'react';
import { AnnouncementBanner } from '@vegaprotocol/announcements';
import { Nav } from '../nav';
@@ -1,8 +1,8 @@
import React from 'react';
import { Children, type ReactNode } from 'react';
export interface TemplateSidebarProps {
children: React.ReactNode;
sidebar: React.ReactNode[];
children: ReactNode;
sidebar: ReactNode;
}
export function TemplateSidebar({ children, sidebar }: TemplateSidebarProps) {
@@ -12,9 +12,9 @@ export function TemplateSidebar({ children, sidebar }: TemplateSidebarProps) {
{children}
</main>
<aside className="col-start-2 row-start-1 row-span-2 hidden lg:block p-4 bg-banner bg-contain border-l border-neutral-700">
{sidebar.map((Component, i) => (
{Children.map(sidebar, (child, i) => (
<section className="mb-4 last:mb-0" key={i}>
{Component}
{child}
</section>
))}
</aside>
@@ -1,5 +1,5 @@
import { Button } from '@vegaprotocol/ui-toolkit';
import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
import { useVegaWallet, useDialogStore } from '@vegaprotocol/wallet-react';
import React from 'react';
import { useTranslation } from 'react-i18next';
@@ -10,9 +10,7 @@ interface VegaWalletContainerProps {
export const VegaWalletContainer = ({ children }: VegaWalletContainerProps) => {
const { t } = useTranslation();
const { pubKey } = useVegaWallet();
const { openVegaWalletDialog } = useVegaWalletDialogStore((store) => ({
openVegaWalletDialog: store.openVegaWalletDialog,
}));
const openVegaWalletDialog = useDialogStore((store) => store.open);
if (!pubKey) {
return (
@@ -9,7 +9,7 @@ import Routes from '../../routes/routes';
export const RiskMessage = () => {
return (
<>
<div className="bg-vega-light-100 dark:bg-vega-dark-100 p-6 mb-6">
<div className="bg-vega-light-100 dark:bg-vega-dark-100 p-6">
<ul className="list-[square] ml-4">
<li>
{t(
@@ -23,7 +23,7 @@ export const RiskMessage = () => {
</li>
</ul>
</div>
<p className="mb-8">
<p>
{t(
'By using the Vega Governance App, you acknowledge that you have read and understood the'
)}{' '}
@@ -1,25 +1,39 @@
import {
VegaConnectDialog,
VegaManageDialog,
ViewAsDialog,
} from '@vegaprotocol/wallet';
ConnectDialogWithRiskAck,
useDialogStore,
} from '@vegaprotocol/wallet-react';
import {
AppStateActionType,
useAppState,
} from '../../contexts/app-state/app-state-context';
import { useConnectors } from '../../lib/vega-connectors';
import { RiskMessage } from './risk-message';
import { VegaManageDialog } from '../manage-dialog';
import { useLocalStorage } from '@vegaprotocol/react-helpers';
import { Networks, useEnvironment } from '@vegaprotocol/environment';
export const VegaWalletDialogs = () => {
const { VEGA_ENV } = useEnvironment();
const { appState, appDispatch } = useAppState();
const connectors = useConnectors();
const [riskAccepted, setRiskAccepted] = useLocalStorage(
'vega_wallet_risk_accepted'
);
const vegaWalletDialogOpen = useDialogStore((store) => store.isOpen);
const setVegaWalletDialog = useDialogStore((store) => store.set);
return (
<>
<VegaConnectDialog
connectors={connectors}
riskMessage={<RiskMessage />}
<ConnectDialogWithRiskAck
open={vegaWalletDialogOpen}
onChange={setVegaWalletDialog}
riskAccepted={
VEGA_ENV === Networks.TESTNET ? riskAccepted === 'true' : true
}
riskAckContent={<RiskMessage />}
onRiskAccepted={() => setRiskAccepted('true')}
onRiskRejected={() => {
setRiskAccepted('false');
setVegaWalletDialog(false);
}}
/>
<VegaManageDialog
dialogOpen={appState.vegaWalletManageOverlay}
setDialogOpen={(open) =>
@@ -29,8 +43,6 @@ export const VegaWalletDialogs = () => {
})
}
/>
<ViewAsDialog connector={connectors.view} />
</>
);
};
@@ -10,7 +10,7 @@ import vegaBlack from '../../images/vega_black.png';
import vegaVesting from '../../images/vega_vesting.png';
import { BigNumber } from '../../lib/bignumber';
import { type WalletCardAssetProps } from '../wallet-card';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { useContracts } from '../../contexts/contracts/contracts-context';
import * as Schema from '@vegaprotocol/types';
import {
@@ -1,11 +1,11 @@
import { ButtonLink, Link } from '@vegaprotocol/ui-toolkit';
import { useTranslation } from 'react-i18next';
import { ExternalLinks } from '@vegaprotocol/environment';
import { useViewAsDialog } from '@vegaprotocol/wallet';
import { useConnect } from '@vegaprotocol/wallet-react';
export const VegaWalletPrompt = () => {
const { t } = useTranslation();
const setViewAsDialog = useViewAsDialog((state) => state.setOpen);
const { connect } = useConnect();
return (
<>
<h3 className="mt-4 mb-2">{t('getWallet')}</h3>
@@ -16,7 +16,7 @@ export const VegaWalletPrompt = () => {
<ButtonLink
className="text-neutral-500"
data-testid="view-as-user"
onClick={() => setViewAsDialog(true)}
onClick={() => connect('viewParty')}
>
{t('viewAsParty')}
</ButtonLink>
@@ -25,7 +25,7 @@ import {
} from '../wallet-card';
import { VegaWalletPrompt } from './vega-wallet-prompt';
import { usePollForDelegations } from './hooks';
import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
import { useVegaWallet, useDialogStore } from '@vegaprotocol/wallet-react';
import { Button, ButtonLink } from '@vegaprotocol/ui-toolkit';
import { toBigNum } from '@vegaprotocol/utils';
import { usePendingBalancesStore } from '../../hooks/use-pending-balances-manager';
@@ -34,16 +34,17 @@ import omit from 'lodash/omit';
export const VegaWallet = () => {
const { t } = useTranslation();
const { pubKey, pubKeys } = useVegaWallet();
const { status, pubKey, pubKeys } = useVegaWallet();
const pubKeyObj = useMemo(() => {
return pubKeys?.find((pk) => pk.publicKey === pubKey);
}, [pubKey, pubKeys]);
const child = !pubKeys ? (
<VegaWalletNotConnected />
) : (
<VegaWalletConnected vegaKeys={pubKeys.map((pk) => pk.publicKey)} />
);
const child =
status === 'connected' ? (
<VegaWalletConnected vegaKeys={pubKeys.map((pk) => pk.publicKey)} />
) : (
<VegaWalletNotConnected />
);
return (
<section className="vega-wallet" data-testid="vega-wallet">
@@ -75,9 +76,7 @@ export const VegaWallet = () => {
const VegaWalletNotConnected = () => {
const { t } = useTranslation();
const { openVegaWalletDialog } = useVegaWalletDialogStore((store) => ({
openVegaWalletDialog: store.openVegaWalletDialog,
}));
const openVegaWalletDialog = useDialogStore((store) => store.open);
return (
<>
<Button
@@ -7,7 +7,7 @@ import { useWeb3React } from '@web3-react/core';
export const useListenForStakingEvents = (
contract: Contract | undefined,
vegaPublicKey: string | null,
vegaPublicKey: string | undefined,
numberOfConfirmations: number
) => {
const { account } = useWeb3React();
@@ -1,6 +1,6 @@
import * as Sentry from '@sentry/react';
import { toBigNum } from '@vegaprotocol/utils';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { useEthereumConfig } from '@vegaprotocol/web3';
import React from 'react';
@@ -0,0 +1,81 @@
import { useEffect } from 'react';
import * as Sentry from '@sentry/react';
import { useLocalStorage } from '@vegaprotocol/react-helpers';
import { TELEMETRY_ON } from '../components/telemetry-dialog/telemetry-dialog';
import { useEnvironment } from '@vegaprotocol/environment';
import { ENV } from '../config';
import { isPartyNotFoundError } from '../lib/party';
export const useSentryInit = () => {
const { VEGA_ENV, GIT_COMMIT_HASH, GIT_BRANCH } = useEnvironment();
const [telemetryOn] = useLocalStorage(TELEMETRY_ON);
useEffect(() => {
if (ENV.dsn && telemetryOn === 'true') {
Sentry.init({
dsn: ENV.dsn,
tracesSampleRate: 0.1,
enabled: true,
environment: VEGA_ENV,
release: GIT_COMMIT_HASH,
beforeSend(event, hint) {
const error = hint?.originalException;
const errorIsString = typeof error === 'string';
const errorIsObject = error instanceof Error;
const requestUrl = event.request?.url;
const transaction = event.transaction;
if (
(errorIsString && isPartyNotFoundError({ message: error })) ||
(errorIsObject && isPartyNotFoundError(error))
) {
// This error is caused by a pubkey making an API request before
// it has interacted with the chain. This isn't needed in Sentry.
return null;
}
const updatedRequest =
requestUrl && requestUrl.includes('/claim?')
? { ...event.request, url: removeQueryParams(requestUrl) }
: event.request;
const updatedTransaction =
transaction && transaction.includes('/claim?')
? removeQueryParams(transaction)
: transaction;
const updatedBreadcrumbs = event.breadcrumbs?.map((breadcrumb) => {
if (
breadcrumb.type === 'navigation' &&
breadcrumb.data?.to?.includes('/claim?')
) {
return {
...breadcrumb,
data: {
...breadcrumb.data,
to: removeQueryParams(breadcrumb.data.to),
},
};
}
return breadcrumb;
});
return {
...event,
request: updatedRequest,
transaction: updatedTransaction,
breadcrumbs: updatedBreadcrumbs ?? event.breadcrumbs,
};
},
});
Sentry.setTag('branch', GIT_BRANCH);
Sentry.setTag('commit', GIT_COMMIT_HASH);
} else {
Sentry.close();
}
}, [GIT_COMMIT_HASH, GIT_BRANCH, VEGA_ENV, telemetryOn]);
};
const removeQueryParams = (url: string) => {
return url.split('?')[0];
};
@@ -0,0 +1,41 @@
import { useMemo } from 'react';
import {
InjectedConnector,
JsonRpcConnector,
SnapConnector,
ViewPartyConnector,
createConfig,
fairground,
stagnet,
mainnet,
} from '@vegaprotocol/wallet';
import { useEnvironment } from '@vegaprotocol/environment';
export const useVegaWalletConfig = () => {
const { VEGA_ENV, VEGA_URL, VEGA_WALLET_URL } = useEnvironment();
return useMemo(() => {
if (!VEGA_ENV || !VEGA_URL || !VEGA_WALLET_URL) return;
const injected = new InjectedConnector();
const jsonRpc = new JsonRpcConnector({
url: VEGA_WALLET_URL,
});
const snap = new SnapConnector({
node: new URL(VEGA_URL).origin,
snapId: 'npm:@vegaprotocol/snap',
version: '1.0.1',
});
const viewParty = new ViewPartyConnector();
const config = createConfig({
chains: [mainnet, fairground, stagnet],
defaultChainId: fairground.id,
connectors: [injected, snap, jsonRpc, viewParty],
});
return config;
}, [VEGA_ENV, VEGA_URL, VEGA_WALLET_URL]);
};
+1 -1
View File
@@ -31,7 +31,7 @@ i18n
load: 'languageOnly',
debug: isInDev,
// have a common namespace used around the full app
ns: ['governance'],
ns: ['governance', 'wallet', 'wallet-react'],
defaultNS: 'governance',
keySeparator: false, // we use content as keys
nsSeparator: false,
@@ -1,30 +0,0 @@
import { useFeatureFlags } from '@vegaprotocol/environment';
import { useMemo } from 'react';
import {
JsonRpcConnector,
ViewConnector,
InjectedConnector,
SnapConnector,
DEFAULT_SNAP_ID,
} from '@vegaprotocol/wallet';
const urlParams = new URLSearchParams(window.location.search);
export const jsonRpc = new JsonRpcConnector();
export const injected = new InjectedConnector();
export const view = new ViewConnector(urlParams.get('address'));
export const snap = new SnapConnector(DEFAULT_SNAP_ID);
export const useConnectors = () => {
const featureFlags = useFeatureFlags((state) => state.flags);
return useMemo(
() => ({
injected,
jsonRpc,
view,
snap: featureFlags.METAMASK_SNAPS ? snap : undefined,
}),
[featureFlags.METAMASK_SNAPS]
);
};
@@ -5,7 +5,6 @@ import {
ProposalState,
VoteValue,
} from '@vegaprotocol/types';
import { VegaWalletContext } from '@vegaprotocol/wallet';
import { AppStateProvider } from '../../../../contexts/app-state/app-state-provider';
import {
generateNoVotes,
@@ -16,9 +15,7 @@ import { ProposalHeader, NewTransferSummary } from './proposal-header';
import {
lastWeek,
nextWeek,
mockWalletContext,
createUserVoteQueryMock,
networkParamsQueryMock,
} from '../../test-helpers/mocks';
import { BrowserRouter } from 'react-router-dom';
import { VoteState } from '../vote-details/use-user-vote';
@@ -45,14 +42,12 @@ const renderComponent = (
render(
<AppStateProvider>
<BrowserRouter>
<MockedProvider mocks={[networkParamsQueryMock, ...mocks]}>
<VegaWalletContext.Provider value={mockWalletContext}>
<ProposalHeader
proposal={proposal}
isListItem={isListItem}
voteState={voteState}
/>
</VegaWalletContext.Provider>
<MockedProvider mocks={mocks}>
<ProposalHeader
proposal={proposal}
isListItem={isListItem}
voteState={voteState}
/>
</MockedProvider>
</BrowserRouter>
</AppStateProvider>
@@ -160,7 +155,7 @@ describe('Proposal header', () => {
screen.queryByTestId('proposal-description')
).not.toBeInTheDocument();
expect(screen.getByTestId('proposal-details')).toHaveTextContent(
'Update to market: MarketId'
/Update to market: MarketId/
);
});
@@ -1,12 +1,12 @@
import { MemoryRouter } from 'react-router-dom';
import { MockedProvider } from '@apollo/client/testing';
import { VegaWalletProvider } from '@vegaprotocol/wallet';
import { type VegaWalletConfig } from '@vegaprotocol/wallet';
import { render, screen } from '@testing-library/react';
import { generateProposal } from '../../test-helpers/generate-proposals';
import { Proposal } from './proposal';
import { ProposalState } from '@vegaprotocol/types';
import { type Proposal as IProposal } from '../../types';
import { AppStateProvider } from '../../../../contexts/app-state/app-state-provider';
import { MockedWalletProvider } from '@vegaprotocol/wallet-react/testing';
jest.mock('@vegaprotocol/network-parameters', () => ({
...jest.requireActual('@vegaprotocol/network-parameters'),
@@ -24,45 +24,44 @@ jest.mock('@vegaprotocol/network-parameters', () => ({
error: null,
})),
}));
jest.mock('../proposal-detail-header/proposal-header', () => ({
ProposalHeader: () => <div data-testid="proposal-header"></div>,
}));
jest.mock('../proposal-change-table', () => ({
ProposalChangeTable: () => <div data-testid="proposal-change-table"></div>,
}));
jest.mock('../proposal-json', () => ({
ProposalJson: () => <div data-testid="proposal-json"></div>,
}));
jest.mock('../list-asset', () => ({
ListAsset: () => <div data-testid="proposal-list-asset"></div>,
}));
jest.mock('./proposal-change-details', () => ({
ProposalChangeDetails: () => (
<div data-testid="proposal-change-details"></div>
),
jest.mock('../list-asset', () => ({
ListAsset: () => <div data-testid="proposal-list-asset"></div>,
}));
const vegaWalletConfig: VegaWalletConfig = {
network: 'TESTNET',
vegaUrl: 'https://vega.xyz',
vegaWalletServiceUrl: 'https://wallet.vega.xyz',
links: {
explorer: 'explorer',
concepts: 'concepts',
chromeExtensionUrl: 'chrome',
mozillaExtensionUrl: 'mozilla',
},
chainId: 'VEGA_CHAIN_ID',
};
jest.mock('../vote-details', () => ({
UserVote: () => <div data-testid="user-vote"></div>,
}));
jest.mock('./proposal-change-details', () => ({
ProposalChangeDetails: () => <div data-testid="proposal-change-details" />,
}));
const renderComponent = (proposal: IProposal) => {
render(
return render(
<MemoryRouter>
<MockedProvider>
<VegaWalletProvider config={vegaWalletConfig}>
<Proposal restData={null} proposal={proposal} />
</VegaWalletProvider>
<MockedWalletProvider>
<AppStateProvider>
<Proposal restData={null} proposal={proposal} />
</AppStateProvider>
</MockedWalletProvider>
</MockedProvider>
</MemoryRouter>
);
@@ -23,7 +23,7 @@ export interface ProposalProps {
export const Proposal = ({ proposal, restData }: ProposalProps) => {
const { t } = useTranslation();
const { submit, Dialog, finalizedVote, transaction } = useVoteSubmit();
const { submit, finalizedVote, transaction } = useVoteSubmit();
const { voteState, voteDatetime } = useUserVote(proposal?.id, finalizedVote);
return (
@@ -88,7 +88,6 @@ export const Proposal = ({ proposal, restData }: ProposalProps) => {
<UserVote
proposal={proposal}
submit={submit}
dialog={Dialog}
transaction={transaction}
voteState={voteState}
voteDatetime={voteDatetime}
@@ -1,15 +1,14 @@
import { BrowserRouter as Router } from 'react-router-dom';
import { VegaWalletContext } from '@vegaprotocol/wallet';
import { render, screen } from '@testing-library/react';
import { AppStateProvider } from '../../../../contexts/app-state/app-state-provider';
import { ProposalsListItemDetails } from './proposals-list-item-details';
import { mockWalletContext } from '../../test-helpers/mocks';
const renderComponent = (id: string) =>
render(
<Router>
<VegaWalletContext.Provider value={mockWalletContext}>
<AppStateProvider>
<ProposalsListItemDetails id={id} />
</VegaWalletContext.Provider>
</AppStateProvider>
</Router>
);
@@ -1,25 +1,32 @@
import { render, screen } from '@testing-library/react';
import { VegaWalletContext } from '@vegaprotocol/wallet';
import { act, render, screen } from '@testing-library/react';
import {
MockedWalletProvider,
mockConfig,
} from '@vegaprotocol/wallet-react/testing';
import { AppStateProvider } from '../../../../contexts/app-state/app-state-provider';
import { ProposalFormSubmit } from './proposal-form-submit';
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
const renderComponent = (
context: VegaWalletContextShape,
isSubmitting: boolean
) => {
const renderComponent = (isSubmitting: boolean) => {
render(
<AppStateProvider>
<VegaWalletContext.Provider value={context}>
<MockedWalletProvider>
<AppStateProvider>
<ProposalFormSubmit isSubmitting={isSubmitting} />
</VegaWalletContext.Provider>
</AppStateProvider>
</AppStateProvider>
</MockedWalletProvider>
);
};
describe('Proposal Form Submit', () => {
const pubKey = { publicKey: '123456__123456', name: 'test' };
afterEach(() => {
act(() => {
mockConfig.reset();
});
});
it('should display connection message and button if wallet not connected', () => {
renderComponent({ pubKey: null } as VegaWalletContextShape, false);
renderComponent(false);
expect(
screen.getByText('Connect your wallet to submit a proposal')
@@ -30,28 +37,22 @@ describe('Proposal Form Submit', () => {
});
it('should display submit button if wallet is connected', () => {
const pubKey = { publicKey: '123456__123456', name: 'test' };
renderComponent(
{
pubKey: pubKey.publicKey,
pubKeys: [pubKey],
} as VegaWalletContextShape,
false
);
mockConfig.store.setState({
pubKey: pubKey.publicKey,
keys: [pubKey],
});
renderComponent(false);
expect(screen.getByTestId('proposal-submit')).toHaveTextContent(
'Submit proposal'
);
});
it('should display submitting button text if wallet is connected and submitting', () => {
const pubKey = { publicKey: '123456__123456', name: 'test' };
renderComponent(
{
pubKey: pubKey.publicKey,
pubKeys: [pubKey],
} as VegaWalletContextShape,
true
);
mockConfig.store.setState({
pubKey: pubKey.publicKey,
keys: [pubKey],
});
renderComponent(true);
expect(screen.getByTestId('proposal-submit')).toHaveTextContent(
'Submitting proposal'
);
@@ -1,6 +1,6 @@
import { useTranslation } from 'react-i18next';
import { Button } from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { VegaWalletContainer } from '../../../../components/vega-wallet-container';
interface ProposalFormSubmitProps {
@@ -1,19 +1,24 @@
import {
VegaTransactionDialog,
getProposalDialogIcon,
getProposalDialogIntent,
useGetProposalDialogTitle,
} from '@vegaprotocol/proposals';
import type { ProposalEventFieldsFragment } from '@vegaprotocol/proposals';
import type { DialogProps } from '@vegaprotocol/proposals';
import type {
ProposalEventFieldsFragment,
VegaTxState,
} from '@vegaprotocol/proposals';
interface ProposalFormTransactionDialogProps {
finalizedProposal: ProposalEventFieldsFragment | null;
TransactionDialog: (props: DialogProps) => JSX.Element;
transaction: VegaTxState;
onChange: (open: boolean) => void;
}
export const ProposalFormTransactionDialog = ({
finalizedProposal,
TransactionDialog,
transaction,
onChange,
}: ProposalFormTransactionDialogProps) => {
const title = useGetProposalDialogTitle(finalizedProposal?.state);
// Render a custom complete UI if the proposal was rejected otherwise
@@ -24,13 +29,16 @@ export const ProposalFormTransactionDialog = ({
return (
<div data-testid="proposal-transaction-dialog">
<TransactionDialog
<VegaTransactionDialog
title={title}
intent={getProposalDialogIntent(finalizedProposal?.state)}
icon={getProposalDialogIcon(finalizedProposal?.state)}
content={{
Complete: completeContent,
}}
transaction={transaction}
isOpen={transaction.dialogOpen}
onChange={onChange}
/>
</div>
);
@@ -1,10 +1,8 @@
import { render, screen } from '@testing-library/react';
import { BrowserRouter as Router } from 'react-router-dom';
import { MockedProvider } from '@apollo/client/testing';
import { VegaWalletContext } from '@vegaprotocol/wallet';
import {
lastWeek,
mockWalletContext,
networkParamsQueryMock,
nextWeek,
} from '../../test-helpers/mocks';
@@ -48,9 +46,7 @@ const renderComponent = (
render(
<Router>
<MockedProvider mocks={mocks}>
<VegaWalletContext.Provider value={mockWalletContext}>
<VoteBreakdown proposal={proposal} />
</VegaWalletContext.Provider>
<VoteBreakdown proposal={proposal} />
</MockedProvider>
</Router>
);
@@ -60,6 +56,7 @@ describe('VoteBreakdown', () => {
jest.useFakeTimers();
jest.setSystemTime(0);
});
afterAll(() => {
jest.useRealTimers();
});
@@ -1,5 +1,5 @@
import { captureMessage } from '@sentry/minimal';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { VoteValue } from '@vegaprotocol/types';
import { useEffect, useState } from 'react';
import { useUserVoteQuery } from './__generated__/Vote';
@@ -1,20 +1,19 @@
import { useTranslation } from 'react-i18next';
import { Icon, ExternalLink } from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { ProposalState } from '@vegaprotocol/types';
import { ConnectToVega } from '../../../../components/connect-to-vega';
import { VoteButtonsContainer } from './vote-buttons';
import { SubHeading } from '../../../../components/heading';
import { type VoteValue } from '@vegaprotocol/types';
import { type DialogProps, type VegaTxState } from '@vegaprotocol/proposals';
import { type VegaTxState } from '@vegaprotocol/proposals';
import { type VoteState } from './use-user-vote';
import { type Proposal, type BatchProposal } from '../../types';
interface UserVoteProps {
proposal: Proposal | BatchProposal;
transaction: VegaTxState | null;
transaction: VegaTxState;
submit: (voteValue: VoteValue, proposalId: string | null) => Promise<void>;
dialog: (props: DialogProps) => JSX.Element;
voteState: VoteState | null;
voteDatetime: Date | null;
}
@@ -23,7 +22,6 @@ export const UserVote = ({
proposal,
submit,
transaction,
dialog,
voteState,
voteDatetime,
}: UserVoteProps) => {
@@ -56,7 +54,6 @@ export const UserVote = ({
className="flex"
submit={submit}
transaction={transaction}
dialog={dialog}
/>
)
) : (
@@ -2,33 +2,20 @@ import { render, screen } from '@testing-library/react';
import { VoteTransactionDialog } from './vote-transaction-dialog';
import { VoteState } from './use-user-vote';
import { VegaTxStatus } from '@vegaprotocol/proposals';
import { ConnectorErrors, unknownError } from '@vegaprotocol/wallet';
describe('VoteTransactionDialog', () => {
const mockTransactionDialog = jest.fn(({ title, content }) => (
<div>
<div>{title}</div>
<div>{content?.Complete}</div>
</div>
));
it('renders without crashing', () => {
render(
<VoteTransactionDialog
voteState={VoteState.Yes}
transaction={null}
TransactionDialog={mockTransactionDialog}
/>
);
expect(screen.getByTestId('vote-transaction-dialog')).toBeInTheDocument();
});
it('renders with txRequested title when voteState is Requested', () => {
render(
<VoteTransactionDialog
voteState={VoteState.Requested}
transaction={null}
TransactionDialog={mockTransactionDialog}
transaction={{
error: null,
txHash: null,
signature: null,
status: VegaTxStatus.Requested,
dialogOpen: true,
}}
/>
);
@@ -39,8 +26,13 @@ describe('VoteTransactionDialog', () => {
render(
<VoteTransactionDialog
voteState={VoteState.Pending}
transaction={null}
TransactionDialog={mockTransactionDialog}
transaction={{
error: null,
txHash: null,
signature: null,
status: VegaTxStatus.Pending,
dialogOpen: true,
}}
/>
);
@@ -51,8 +43,13 @@ describe('VoteTransactionDialog', () => {
render(
<VoteTransactionDialog
voteState={VoteState.Yes} // or any other state other than Requested or Pending
transaction={null}
TransactionDialog={mockTransactionDialog}
transaction={{
error: null,
txHash: null,
signature: null,
status: VegaTxStatus.Complete,
dialogOpen: true,
}}
/>
);
@@ -65,17 +62,18 @@ describe('VoteTransactionDialog', () => {
<VoteTransactionDialog
voteState={VoteState.Failed}
transaction={{
error: { message: 'Custom error test message', name: 'blah' },
error: unknownError(),
txHash: null,
signature: null,
status: VegaTxStatus.Error,
dialogOpen: false,
dialogOpen: true,
}}
TransactionDialog={mockTransactionDialog}
/>
);
expect(screen.getByText('Custom error test message')).toBeInTheDocument();
expect(
screen.getByText(ConnectorErrors.unknown.message)
).toBeInTheDocument();
});
it('renders default error message when voteState is failed and no error message exists on the tx', () => {
@@ -86,10 +84,9 @@ describe('VoteTransactionDialog', () => {
error: null,
txHash: null,
signature: null,
status: VegaTxStatus.Error,
dialogOpen: false,
status: VegaTxStatus.Complete,
dialogOpen: true,
}}
TransactionDialog={mockTransactionDialog}
/>
);
@@ -100,8 +97,13 @@ describe('VoteTransactionDialog', () => {
render(
<VoteTransactionDialog
voteState={VoteState.Yes}
transaction={null}
TransactionDialog={mockTransactionDialog}
transaction={{
error: null,
txHash: null,
signature: null,
status: VegaTxStatus.Default,
dialogOpen: true,
}}
/>
);
@@ -1,120 +1,77 @@
import { fireEvent, render, screen } from '@testing-library/react';
import { act, fireEvent, render, screen } from '@testing-library/react';
import BigNumber from 'bignumber.js';
import { VoteButtons } from './vote-buttons';
import { VoteButtons, type VoteButtonsProps } from './vote-buttons';
import { VoteState } from './use-user-vote';
import { ProposalState } from '@vegaprotocol/types';
import { VegaWalletContext } from '@vegaprotocol/wallet';
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
import { mockWalletContext } from '../../test-helpers/mocks';
import { AppStateProvider } from '../../../../contexts/app-state/app-state-provider';
import { MockedProvider } from '@apollo/react-testing';
import { VegaTxStatus } from '@vegaprotocol/proposals';
import {
MockedWalletProvider,
mockConfig,
} from '@vegaprotocol/wallet-react/testing';
describe('Vote buttons', () => {
it('should render successfully', () => {
const { baseElement } = render(
const key = { publicKey: '0x123', name: 'key 1' };
const transaction = {
status: VegaTxStatus.Default,
error: null,
txHash: null,
signature: null,
dialogOpen: false,
};
const props = {
voteState: VoteState.NotCast,
voteDatetime: null,
proposalState: ProposalState.STATE_OPEN,
proposalId: null,
minVoterBalance: null,
spamProtectionMinTokens: null,
currentStakeAvailable: new BigNumber(1),
submit: () => Promise.resolve(),
transaction,
};
const renderComponent = (testProps?: Partial<VoteButtonsProps>) => {
return render(
<AppStateProvider>
<MockedProvider>
<VegaWalletContext.Provider value={mockWalletContext}>
<VoteButtons
voteState={VoteState.NotCast}
voteDatetime={null}
proposalState={ProposalState.STATE_OPEN}
proposalId={null}
minVoterBalance={null}
spamProtectionMinTokens={null}
currentStakeAvailable={new BigNumber(1)}
dialog={() => <div>Blah</div>}
submit={() => Promise.resolve()}
transaction={null}
/>
</VegaWalletContext.Provider>
<MockedWalletProvider>
<VoteButtons {...props} {...testProps} />
</MockedWalletProvider>
</MockedProvider>
</AppStateProvider>
);
};
beforeEach(() => {
mockConfig.store.setState({ pubKey: key.publicKey, keys: [key] });
});
afterEach(() => {
act(() => {
mockConfig.reset();
});
});
it('should render successfully', () => {
const { baseElement } = renderComponent();
expect(baseElement).toBeTruthy();
});
it('should explain that voting is closed if the proposal is not open', () => {
render(
<AppStateProvider>
<MockedProvider>
<VegaWalletContext.Provider value={mockWalletContext}>
<VoteButtons
voteState={VoteState.NotCast}
voteDatetime={null}
proposalState={ProposalState.STATE_PASSED}
proposalId={null}
minVoterBalance={null}
spamProtectionMinTokens={null}
currentStakeAvailable={new BigNumber(1)}
dialog={() => <div>Blah</div>}
submit={() => Promise.resolve()}
transaction={null}
/>
</VegaWalletContext.Provider>
</MockedProvider>
</AppStateProvider>
);
renderComponent({ proposalState: ProposalState.STATE_PASSED });
expect(screen.getByText('Voting has ended.')).toBeTruthy();
});
it('should provide a connect wallet prompt if no pubkey', () => {
const mockWalletNoPubKeyContext = {
pubKey: null,
pubKeys: [],
isReadOnly: false,
sendTx: jest.fn().mockReturnValue(Promise.resolve(null)),
connect: jest.fn(),
disconnect: jest.fn(),
selectPubKey: jest.fn(),
connector: null,
} as unknown as VegaWalletContextShape;
render(
<AppStateProvider>
<MockedProvider>
<VegaWalletContext.Provider value={mockWalletNoPubKeyContext}>
<VoteButtons
voteState={VoteState.NotCast}
voteDatetime={null}
proposalState={ProposalState.STATE_OPEN}
proposalId={null}
minVoterBalance={null}
spamProtectionMinTokens={null}
currentStakeAvailable={new BigNumber(1)}
dialog={() => <div>Blah</div>}
submit={() => Promise.resolve()}
transaction={null}
/>
</VegaWalletContext.Provider>
</MockedProvider>
</AppStateProvider>
);
mockConfig.reset();
renderComponent();
expect(screen.getByTestId('connect-wallet')).toBeTruthy();
});
it('should tell the user they need tokens if their current stake is 0', () => {
render(
<AppStateProvider>
<MockedProvider>
<VegaWalletContext.Provider value={mockWalletContext}>
<VoteButtons
voteState={VoteState.NotCast}
voteDatetime={null}
proposalState={ProposalState.STATE_OPEN}
proposalId={null}
minVoterBalance={null}
spamProtectionMinTokens={null}
currentStakeAvailable={new BigNumber(0)}
dialog={() => <div>Blah</div>}
submit={() => Promise.resolve()}
transaction={null}
/>
</VegaWalletContext.Provider>
</MockedProvider>
</AppStateProvider>
);
renderComponent({ currentStakeAvailable: new BigNumber(0) });
expect(
screen.getByText(
'You need some VEGA tokens to participate in governance.'
@@ -123,26 +80,10 @@ describe('Vote buttons', () => {
});
it('should tell the user of the minimum requirements if they have some, but not enough tokens', () => {
render(
<AppStateProvider>
<MockedProvider>
<VegaWalletContext.Provider value={mockWalletContext}>
<VoteButtons
voteState={VoteState.NotCast}
voteDatetime={null}
proposalState={ProposalState.STATE_OPEN}
proposalId={null}
minVoterBalance="2000000000000000000"
spamProtectionMinTokens="1000000000000000000"
currentStakeAvailable={new BigNumber(1)}
dialog={() => <div>Blah</div>}
submit={() => Promise.resolve()}
transaction={null}
/>
</VegaWalletContext.Provider>
</MockedProvider>
</AppStateProvider>
);
renderComponent({
minVoterBalance: '2000000000000000000',
spamProtectionMinTokens: '1000000000000000000',
});
expect(
screen.getByText(
'You must have at least 2 VEGA associated to vote on this proposal'
@@ -151,51 +92,23 @@ describe('Vote buttons', () => {
});
it('should show you voted if vote state is correct, and if the proposal is still open, it will display a change vote button', () => {
render(
<AppStateProvider>
<MockedProvider>
<VegaWalletContext.Provider value={mockWalletContext}>
<VoteButtons
voteState={VoteState.Yes}
voteDatetime={null}
proposalState={ProposalState.STATE_OPEN}
proposalId={null}
minVoterBalance="2000000000000000000"
spamProtectionMinTokens="1000000000000000000"
currentStakeAvailable={new BigNumber(10)}
dialog={() => <div>Blah</div>}
submit={() => Promise.resolve()}
transaction={null}
/>
</VegaWalletContext.Provider>
</MockedProvider>
</AppStateProvider>
);
renderComponent({
voteState: VoteState.Yes,
minVoterBalance: '2000000000000000000',
spamProtectionMinTokens: '1000000000000000000',
currentStakeAvailable: new BigNumber(10),
});
expect(screen.getByTestId('you-voted')).toBeInTheDocument();
expect(screen.getByTestId('change-vote-button')).toBeInTheDocument();
});
it('should allow you to change your vote', () => {
render(
<AppStateProvider>
<MockedProvider>
<VegaWalletContext.Provider value={mockWalletContext}>
<VoteButtons
voteState={VoteState.No}
voteDatetime={null}
proposalState={ProposalState.STATE_OPEN}
proposalId={null}
minVoterBalance="2000000000000000000"
spamProtectionMinTokens="1000000000000000000"
currentStakeAvailable={new BigNumber(10)}
dialog={() => <div>Blah</div>}
submit={() => Promise.resolve()}
transaction={null}
/>
</VegaWalletContext.Provider>
</MockedProvider>
</AppStateProvider>
);
renderComponent({
voteState: VoteState.No,
minVoterBalance: '2000000000000000000',
spamProtectionMinTokens: '1000000000000000000',
currentStakeAvailable: new BigNumber(10),
});
fireEvent.click(screen.getByTestId('change-vote-button'));
expect(screen.getByTestId('vote-buttons')).toBeInTheDocument();
});
@@ -1,7 +1,7 @@
import { format } from 'date-fns';
import React, { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
import { useVegaWallet, useDialogStore } from '@vegaprotocol/wallet-react';
import {
AsyncRenderer,
Button,
@@ -17,7 +17,7 @@ import { VoteState } from './use-user-vote';
import { ProposalMinRequirements, ProposalUserAction } from '../shared';
import { VoteTransactionDialog } from './vote-transaction-dialog';
import { useVoteButtonsQuery } from './__generated__/Stake';
import type { DialogProps, VegaTxState } from '@vegaprotocol/proposals';
import type { VegaTxState } from '@vegaprotocol/proposals';
import { filterAcceptableGraphqlErrors } from '../../../../lib/party';
import {
NetworkParams,
@@ -32,8 +32,7 @@ interface VoteButtonsContainerProps {
proposalId: string | null;
proposalState: ProposalState;
submit: (voteValue: VoteValue, proposalId: string | null) => Promise<void>;
transaction: VegaTxState | null;
dialog: (props: DialogProps) => JSX.Element;
transaction: VegaTxState;
className?: string;
}
@@ -136,17 +135,16 @@ export const VoteButtonsContainer = (props: VoteButtonsContainerProps) => {
);
};
interface VoteButtonsProps {
export interface VoteButtonsProps {
voteState: VoteState | null;
voteDatetime: Date | null;
proposalId: string | null;
proposalState: ProposalState;
submit: (voteValue: VoteValue, proposalId: string | null) => Promise<void>;
transaction: VegaTxState | null;
dialog: (props: DialogProps) => JSX.Element;
proposalId: string | null;
currentStakeAvailable: BigNumber;
minVoterBalance: string | null;
spamProtectionMinTokens: string | null;
submit: (voteValue: VoteValue, proposalId: string | null) => Promise<void>;
transaction: VegaTxState;
}
export const VoteButtons = ({
@@ -159,13 +157,10 @@ export const VoteButtons = ({
spamProtectionMinTokens,
submit,
transaction,
dialog: Dialog,
}: VoteButtonsProps) => {
const { t } = useTranslation();
const { pubKey } = useVegaWallet();
const { openVegaWalletDialog } = useVegaWalletDialogStore((store) => ({
openVegaWalletDialog: store.openVegaWalletDialog,
}));
const openVegaWalletDialog = useDialogStore((store) => store.open);
const [changeVote, setChangeVote] = React.useState(false);
const proposalVotable = useMemo(
() =>
@@ -184,11 +179,7 @@ export const VoteButtons = ({
if (!pubKey) {
return (
<div data-testid="connect-wallet">
<ButtonLink
onClick={() => {
openVegaWalletDialog();
}}
>
<ButtonLink onClick={openVegaWalletDialog}>
{t('connectVegaWallet')}
</ButtonLink>{' '}
{t('toVote')}
@@ -301,11 +292,7 @@ export const VoteButtons = ({
</p>
)
)}
<VoteTransactionDialog
voteState={voteState}
transaction={transaction}
TransactionDialog={Dialog}
/>
<VoteTransactionDialog voteState={voteState} transaction={transaction} />
</>
);
};
@@ -1,11 +1,13 @@
import { t } from '@vegaprotocol/i18n';
import { VoteState } from './use-user-vote';
import type { DialogProps, VegaTxState } from '@vegaprotocol/proposals';
import {
VegaTransactionDialog,
type VegaTxState,
} from '@vegaprotocol/proposals';
interface VoteTransactionDialogProps {
voteState: VoteState;
transaction: VegaTxState | null;
TransactionDialog: (props: DialogProps) => JSX.Element;
transaction: VegaTxState;
}
const dialogTitle = (voteState: VoteState): string | undefined => {
@@ -22,22 +24,23 @@ const dialogTitle = (voteState: VoteState): string | undefined => {
export const VoteTransactionDialog = ({
voteState,
transaction,
TransactionDialog,
}: VoteTransactionDialogProps) => {
// Render a custom message if the voting fails otherwise
// pass undefined so that the default vega transaction dialog UI gets used
const customMessage =
voteState === VoteState.Failed ? (
<p>{transaction?.error?.message || t('voteError')}</p>
<p>{transaction.error?.message || t('voteError')}</p>
) : undefined;
return (
<div data-testid="vote-transaction-dialog">
<TransactionDialog
<VegaTransactionDialog
title={dialogTitle(voteState)}
transaction={transaction}
content={{
Complete: customMessage,
}}
isOpen={transaction.dialogOpen}
/>
</div>
);
@@ -1,13 +1,12 @@
import { render, screen } from '@testing-library/react';
import { ProposeFreeform } from './propose-freeform';
import { MockedProvider } from '@apollo/client/testing';
import { mockWalletContext } from '../../test-helpers/mocks';
import { AppStateProvider } from '../../../../contexts/app-state/app-state-provider';
import { VegaWalletContext } from '@vegaprotocol/wallet';
import { MemoryRouter as Router } from 'react-router-dom';
import type { NetworkParamsQuery } from '@vegaprotocol/network-parameters';
import type { MockedResponse } from '@apollo/client/testing';
import { NetworkParamsDocument } from '@vegaprotocol/network-parameters';
import { MockedWalletProvider } from '@vegaprotocol/wallet-react/testing';
jest.mock('@vegaprotocol/environment', () => ({
...jest.requireActual('@vegaprotocol/environment'),
@@ -72,18 +71,19 @@ const updateMarketNetworkParamsQueryMock: MockedResponse<NetworkParamsQuery> = {
},
};
const renderComponent = () =>
render(
const renderComponent = () => {
return render(
<Router>
<MockedProvider mocks={[updateMarketNetworkParamsQueryMock]}>
<AppStateProvider>
<VegaWalletContext.Provider value={mockWalletContext}>
<MockedWalletProvider>
<AppStateProvider>
<ProposeFreeform />
</VegaWalletContext.Provider>
</AppStateProvider>
</AppStateProvider>
</MockedWalletProvider>
</MockedProvider>
</Router>
);
};
// Note: form submission is tested in propose-raw.spec.tsx. Reusable form
// components are tested in their own directory.
@@ -51,7 +51,8 @@ export const ProposeFreeform = () => {
watch,
trigger,
} = useForm<FreeformProposalFormFields>();
const { finalizedProposal, submit, Dialog } = useProposalSubmit();
const { finalizedProposal, transaction, submit, setTransaction } =
useProposalSubmit();
const assembleProposal = (fields: FreeformProposalFormFields) => {
const isVoteDeadlineAtMinimum =
@@ -169,7 +170,8 @@ export const ProposeFreeform = () => {
<ProposalFormDownloadJson downloadJson={viewJson} />
<ProposalFormTransactionDialog
finalizedProposal={finalizedProposal}
TransactionDialog={Dialog}
transaction={transaction}
onChange={(open) => setTransaction({ dialogOpen: open })}
/>
</form>
</div>
@@ -1,13 +1,12 @@
import { fireEvent, render, screen } from '@testing-library/react';
import { ProposeNetworkParameter } from './propose-network-parameter';
import { MockedProvider } from '@apollo/client/testing';
import { mockWalletContext } from '../../test-helpers/mocks';
import { AppStateProvider } from '../../../../contexts/app-state/app-state-provider';
import { VegaWalletContext } from '@vegaprotocol/wallet';
import { MemoryRouter as Router } from 'react-router-dom';
import type { NetworkParamsQuery } from '@vegaprotocol/network-parameters';
import { NetworkParamsDocument } from '@vegaprotocol/network-parameters';
import type { MockedResponse } from '@apollo/client/testing';
import { MockedWalletProvider } from '@vegaprotocol/wallet-react/testing';
jest.mock('@vegaprotocol/environment', () => ({
...jest.requireActual('@vegaprotocol/environment'),
@@ -72,26 +71,27 @@ const updateMarketNetworkParamsQueryMock: MockedResponse<NetworkParamsQuery> = {
},
};
const renderComponent = () =>
render(
const renderComponent = () => {
return render(
<Router>
<MockedProvider mocks={[updateMarketNetworkParamsQueryMock]}>
<AppStateProvider>
<VegaWalletContext.Provider value={mockWalletContext}>
<MockedWalletProvider>
<AppStateProvider>
<ProposeNetworkParameter />
</VegaWalletContext.Provider>
</AppStateProvider>
</AppStateProvider>
</MockedWalletProvider>
</MockedProvider>
</Router>
);
};
// Note: form submission is tested in propose-raw.spec.tsx. Reusable form
// components are tested in their own directory.
describe('Propose Network Parameter', () => {
it('should render successfully', async () => {
it('should render successfully', () => {
const { baseElement } = renderComponent();
await expect(baseElement).toBeTruthy();
expect(baseElement).toBeTruthy();
});
it('should render the correct title', async () => {
@@ -91,7 +91,8 @@ export const ProposeNetworkParameter = () => {
watch,
trigger,
} = useForm<NetworkParameterProposalFormFields>();
const { finalizedProposal, submit, Dialog } = useProposalSubmit();
const { finalizedProposal, transaction, submit, setTransaction } =
useProposalSubmit();
const selectedParamEntry = params
? Object.entries(params).find(([key]) => key === selectedNetworkParam)
@@ -312,7 +313,8 @@ export const ProposeNetworkParameter = () => {
<ProposalFormDownloadJson downloadJson={viewJson} />
<ProposalFormTransactionDialog
finalizedProposal={finalizedProposal}
TransactionDialog={Dialog}
transaction={transaction}
onChange={(open) => setTransaction({ dialogOpen: open })}
/>
</form>
</div>
@@ -1,13 +1,12 @@
import { MockedProvider } from '@apollo/client/testing';
import { MemoryRouter as Router } from 'react-router-dom';
import { render, screen } from '@testing-library/react';
import { VegaWalletContext } from '@vegaprotocol/wallet';
import { AppStateProvider } from '../../../../contexts/app-state/app-state-provider';
import { mockWalletContext } from '../../test-helpers/mocks';
import { ProposeNewAsset } from './propose-new-asset';
import type { NetworkParamsQuery } from '@vegaprotocol/network-parameters';
import type { MockedResponse } from '@apollo/client/testing';
import { NetworkParamsDocument } from '@vegaprotocol/network-parameters';
import { MockedWalletProvider } from '@vegaprotocol/wallet-react/testing';
jest.mock('@vegaprotocol/environment', () => ({
...jest.requireActual('@vegaprotocol/environment'),
@@ -72,26 +71,27 @@ const newAssetNetworkParamsQueryMock: MockedResponse<NetworkParamsQuery> = {
},
};
const renderComponent = () =>
render(
const renderComponent = () => {
return render(
<Router>
<MockedProvider mocks={[newAssetNetworkParamsQueryMock]}>
<AppStateProvider>
<VegaWalletContext.Provider value={mockWalletContext}>
<MockedWalletProvider>
<AppStateProvider>
<ProposeNewAsset />
</VegaWalletContext.Provider>
</AppStateProvider>
</AppStateProvider>
</MockedWalletProvider>
</MockedProvider>
</Router>
);
};
// Note: form submission is tested in propose-raw.spec.tsx. Reusable form
// components are tested in their own directory.
describe('Propose New Asset', () => {
it('should render successfully', async () => {
it('should render successfully', () => {
const { baseElement } = renderComponent();
await expect(baseElement).toBeTruthy();
expect(baseElement).toBeTruthy();
});
it('should render the title', async () => {
@@ -64,7 +64,8 @@ export const ProposeNewAsset = () => {
watch,
trigger,
} = useForm<NewAssetProposalFormFields>();
const { finalizedProposal, submit, Dialog } = useProposalSubmit();
const { finalizedProposal, transaction, submit, setTransaction } =
useProposalSubmit();
const assembleProposal = (fields: NewAssetProposalFormFields) => {
const isVoteDeadlineAtMinimum = doesValueEquateToParam(
@@ -232,7 +233,8 @@ export const ProposeNewAsset = () => {
<ProposalFormDownloadJson downloadJson={viewJson} />
<ProposalFormTransactionDialog
finalizedProposal={finalizedProposal}
TransactionDialog={Dialog}
transaction={transaction}
onChange={(open) => setTransaction({ dialogOpen: open })}
/>
</form>
</div>
@@ -1,13 +1,12 @@
import { render, screen } from '@testing-library/react';
import { ProposeNewMarket } from './propose-new-market';
import { MockedProvider } from '@apollo/client/testing';
import { mockWalletContext } from '../../test-helpers/mocks';
import { AppStateProvider } from '../../../../contexts/app-state/app-state-provider';
import { VegaWalletContext } from '@vegaprotocol/wallet';
import { BrowserRouter as Router } from 'react-router-dom';
import type { MockedResponse } from '@apollo/client/testing';
import type { NetworkParamsQuery } from '@vegaprotocol/network-parameters';
import { NetworkParamsDocument } from '@vegaprotocol/network-parameters';
import { MockedWalletProvider } from '@vegaprotocol/wallet-react/testing';
jest.mock('@vegaprotocol/environment', () => ({
...jest.requireActual('@vegaprotocol/environment'),
@@ -72,26 +71,27 @@ const newMarketNetworkParamsQueryMock: MockedResponse<NetworkParamsQuery> = {
},
};
const renderComponent = () =>
render(
const renderComponent = () => {
return render(
<Router>
<MockedProvider mocks={[newMarketNetworkParamsQueryMock]}>
<AppStateProvider>
<VegaWalletContext.Provider value={mockWalletContext}>
<MockedWalletProvider>
<AppStateProvider>
<ProposeNewMarket />
</VegaWalletContext.Provider>
</AppStateProvider>
</AppStateProvider>
</MockedWalletProvider>
</MockedProvider>
</Router>
);
};
// Note: form submission is tested in propose-raw.spec.tsx. Reusable form
// components are tested in their own directory.
describe('Propose New Market', () => {
it('should render successfully', async () => {
it('should render successfully', () => {
const { baseElement } = renderComponent();
await expect(baseElement).toBeTruthy();
expect(baseElement).toBeTruthy();
});
it('should render the form components', async () => {
@@ -62,7 +62,8 @@ export const ProposeNewMarket = () => {
watch,
trigger,
} = useForm<NewMarketProposalFormFields>();
const { finalizedProposal, submit, Dialog } = useProposalSubmit();
const { finalizedProposal, transaction, submit, setTransaction } =
useProposalSubmit();
const assembleProposal = (fields: NewMarketProposalFormFields) => {
const isVoteDeadlineAtMinimum = doesValueEquateToParam(
@@ -214,7 +215,8 @@ export const ProposeNewMarket = () => {
<ProposalFormDownloadJson downloadJson={viewJson} />
<ProposalFormTransactionDialog
finalizedProposal={finalizedProposal}
TransactionDialog={Dialog}
transaction={transaction}
onChange={(open) => setTransaction({ dialogOpen: open })}
/>
</form>
</div>
@@ -3,8 +3,6 @@ import type { MockedResponse } from '@apollo/client/testing';
import { addHours, getTime } from 'date-fns';
import { AppStateProvider } from '../../../../contexts/app-state/app-state-provider';
import { MockedProvider } from '@apollo/client/testing';
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
import { VegaWalletContext } from '@vegaprotocol/wallet';
import * as Schema from '@vegaprotocol/types';
import { ProposeRaw } from './propose-raw';
import { ProposalEventDocument } from '@vegaprotocol/proposals';
@@ -12,6 +10,11 @@ import type { ProposalEventSubscription } from '@vegaprotocol/proposals';
import type { NetworkParamsQuery } from '@vegaprotocol/network-parameters';
import { NetworkParamsDocument } from '@vegaprotocol/network-parameters';
import {
MockedWalletProvider,
mockConfig,
} from '@vegaprotocol/wallet-react/testing';
import { userRejectedError } from '@vegaprotocol/wallet';
const paramsDelay = 20;
@@ -103,23 +106,15 @@ describe('Raw proposal form', () => {
},
delay: 300,
};
const setup = (mockSendTx = jest.fn()) => {
const setup = () => {
return render(
<AppStateProvider>
<MockedProvider
mocks={[rawProposalNetworkParamsQueryMock, mockProposalEvent]}
>
<VegaWalletContext.Provider
value={
{
pubKey,
sendTx: mockSendTx,
links: { explorer: 'explorer' },
} as unknown as VegaWalletContextShape
}
>
<MockedWalletProvider>
<ProposeRaw />
</VegaWalletContext.Provider>
</MockedWalletProvider>
</MockedProvider>
</AppStateProvider>
);
@@ -127,15 +122,22 @@ describe('Raw proposal form', () => {
beforeAll(() => {
jest.useFakeTimers();
mockConfig.store.setState({ status: 'connected', pubKey: '0x123' });
});
afterAll(() => {
jest.useRealTimers();
mockConfig.reset();
});
afterEach(() => {
jest.clearAllMocks();
});
it('handles validation', async () => {
const mockSendTx = jest.fn().mockReturnValue(Promise.resolve());
setup(mockSendTx);
const mockSendTx = jest.spyOn(mockConfig, 'sendTransaction');
setup();
expect(await screen.findByTestId('proposal-submit')).toBeTruthy();
await act(async () => {
@@ -162,20 +164,25 @@ describe('Raw proposal form', () => {
});
it('sends the transaction', async () => {
const mockSendTx = jest.fn().mockReturnValue(
new Promise((resolve) => {
setTimeout(
() =>
resolve({
transactionHash: 'tx-hash',
signature:
'cfe592d169f87d0671dd447751036d0dddc165b9c4b65e5a5060e2bbadd1aa726d4cbe9d3c3b327bcb0bff4f83999592619a2493f9bbd251fae99ce7ce766909',
}),
100
);
})
);
setup(mockSendTx);
const mockSendTx = jest
.spyOn(mockConfig, 'sendTransaction')
.mockReturnValue(
new Promise((resolve) => {
setTimeout(
() =>
resolve({
transactionHash: 'tx-hash',
signature:
'cfe592d169f87d0671dd447751036d0dddc165b9c4b65e5a5060e2bbadd1aa726d4cbe9d3c3b327bcb0bff4f83999592619a2493f9bbd251fae99ce7ce766909',
sentAt: new Date().toISOString(),
receivedAt: new Date().toISOString(),
}),
100
);
})
);
setup();
await act(async () => {
jest.advanceTimersByTime(paramsDelay);
@@ -206,8 +213,12 @@ describe('Raw proposal form', () => {
fireEvent.click(screen.getByTestId('proposal-submit'));
});
expect(mockSendTx).toHaveBeenCalledWith(pubKey, {
proposalSubmission: JSON.parse(inputJSON),
expect(mockSendTx).toHaveBeenCalledWith({
publicKey: pubKey,
sendingMode: 'TYPE_SYNC',
transaction: {
proposalSubmission: JSON.parse(inputJSON),
},
});
expect(screen.getByTestId('dialog-title')).toHaveTextContent(
@@ -232,12 +243,12 @@ describe('Raw proposal form', () => {
});
it('can be rejected by the user', async () => {
const mockSendTx = jest.fn().mockReturnValue(
new Promise((resolve) => {
setTimeout(() => resolve(null), 100);
jest.spyOn(mockConfig, 'sendTransaction').mockReturnValue(
new Promise((_, reject) => {
setTimeout(() => reject(userRejectedError()), 100);
})
);
setup(mockSendTx);
setup();
await act(async () => {
jest.advanceTimersByTime(paramsDelay);
@@ -52,7 +52,8 @@ export const ProposeRaw = () => {
handleSubmit,
formState: { isSubmitting, errors },
} = useForm<RawProposalFormFields>();
const { finalizedProposal, submit, Dialog } = useProposalSubmit();
const { finalizedProposal, transaction, submit, setTransaction } =
useProposalSubmit();
const hasError = Boolean(errors.rawProposalData?.message);
@@ -152,7 +153,8 @@ export const ProposeRaw = () => {
<ProposalFormSubmit isSubmitting={isSubmitting} />
<ProposalFormTransactionDialog
finalizedProposal={finalizedProposal}
TransactionDialog={Dialog}
transaction={transaction}
onChange={(open) => setTransaction({ dialogOpen: open })}
/>
</form>
</div>
@@ -1,13 +1,12 @@
import { MockedProvider } from '@apollo/client/testing';
import { MemoryRouter as Router } from 'react-router-dom';
import { render, screen } from '@testing-library/react';
import { VegaWalletContext } from '@vegaprotocol/wallet';
import { AppStateProvider } from '../../../../contexts/app-state/app-state-provider';
import { mockWalletContext } from '../../test-helpers/mocks';
import { ProposeUpdateAsset } from './propose-update-asset';
import type { NetworkParamsQuery } from '@vegaprotocol/network-parameters';
import type { MockedResponse } from '@apollo/client/testing';
import { NetworkParamsDocument } from '@vegaprotocol/network-parameters';
import { MockedWalletProvider } from '@vegaprotocol/wallet-react/testing';
jest.mock('@vegaprotocol/environment', () => ({
...jest.requireActual('@vegaprotocol/environment'),
@@ -72,26 +71,27 @@ const updateAssetNetworkParamsQueryMock: MockedResponse<NetworkParamsQuery> = {
},
};
const renderComponent = () =>
render(
const renderComponent = () => {
return render(
<Router>
<MockedProvider mocks={[updateAssetNetworkParamsQueryMock]}>
<AppStateProvider>
<VegaWalletContext.Provider value={mockWalletContext}>
<MockedWalletProvider>
<AppStateProvider>
<ProposeUpdateAsset />
</VegaWalletContext.Provider>
</AppStateProvider>
</AppStateProvider>
</MockedWalletProvider>
</MockedProvider>
</Router>
);
};
// Note: form submission is tested in propose-raw.spec.tsx. Reusable form
// components are tested in their own directory.
describe('Propose Update Asset', () => {
it('should render successfully', async () => {
it('should render successfully', () => {
const { baseElement } = renderComponent();
await expect(baseElement).toBeTruthy();
expect(baseElement).toBeTruthy();
});
it('should render the title', async () => {
@@ -62,7 +62,8 @@ export const ProposeUpdateAsset = () => {
watch,
trigger,
} = useForm<UpdateAssetProposalFormFields>();
const { finalizedProposal, submit, Dialog } = useProposalSubmit();
const { finalizedProposal, transaction, submit, setTransaction } =
useProposalSubmit();
const assembleProposal = (fields: UpdateAssetProposalFormFields) => {
const isVoteDeadlineAtMinimum = doesValueEquateToParam(
@@ -218,7 +219,8 @@ export const ProposeUpdateAsset = () => {
<ProposalFormDownloadJson downloadJson={viewJson} />
<ProposalFormTransactionDialog
finalizedProposal={finalizedProposal}
TransactionDialog={Dialog}
transaction={transaction}
onChange={(open) => setTransaction({ dialogOpen: open })}
/>
</form>
</div>
@@ -2,15 +2,14 @@ import type { MockedResponse } from '@apollo/client/testing';
import { MockedProvider } from '@apollo/client/testing';
import { MemoryRouter as Router } from 'react-router-dom';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import { VegaWalletContext } from '@vegaprotocol/wallet';
import { AppStateProvider } from '../../../../contexts/app-state/app-state-provider';
import { mockWalletContext } from '../../test-helpers/mocks';
import { ProposeUpdateMarket } from './propose-update-market';
import type { NetworkParamsQuery } from '@vegaprotocol/network-parameters';
import { NetworkParamsDocument } from '@vegaprotocol/network-parameters';
import type { ProposalMarketsQueryQuery } from './__generated__/UpdateMarket';
import { ProposalMarketsQueryDocument } from './__generated__/UpdateMarket';
import { ProposalState } from '@vegaprotocol/types';
import { MockedWalletProvider } from '@vegaprotocol/wallet-react/testing';
const updateMarketNetworkParamsQueryMock: MockedResponse<NetworkParamsQuery> = {
request: {
@@ -217,29 +216,30 @@ const marketQueryMock: MockedResponse<ProposalMarketsQueryQuery> = {
},
};
const renderComponent = () =>
render(
const renderComponent = () => {
return render(
<MockedProvider
mocks={[updateMarketNetworkParamsQueryMock, marketQueryMock]}
addTypename={false}
>
<Router>
<AppStateProvider>
<VegaWalletContext.Provider value={mockWalletContext}>
<MockedWalletProvider>
<AppStateProvider>
<ProposeUpdateMarket />
</VegaWalletContext.Provider>
</AppStateProvider>
</AppStateProvider>
</MockedWalletProvider>
</Router>
</MockedProvider>
);
};
// Note: form submission is tested in propose-raw.spec.tsx. Reusable form
// components are tested in their own directory.
describe('Propose Update Market', () => {
it('should render successfully', async () => {
it('should render successfully', () => {
const { baseElement } = renderComponent();
await expect(baseElement).toBeTruthy();
expect(baseElement).toBeTruthy();
});
it('should render the title', async () => {
@@ -109,7 +109,8 @@ export const ProposeUpdateMarket = () => {
watch,
trigger,
} = useForm<UpdateMarketProposalFormFields>();
const { finalizedProposal, submit, Dialog } = useProposalSubmit();
const { finalizedProposal, transaction, submit, setTransaction } =
useProposalSubmit();
const assembleProposal = (fields: UpdateMarketProposalFormFields) => {
const isVoteDeadlineAtMinimum = doesValueEquateToParam(
@@ -323,7 +324,8 @@ export const ProposeUpdateMarket = () => {
<ProposalFormDownloadJson downloadJson={viewJson} />
<ProposalFormTransactionDialog
finalizedProposal={finalizedProposal}
TransactionDialog={Dialog}
transaction={transaction}
onChange={(open) => setTransaction({ dialogOpen: open })}
/>
</form>
</div>
@@ -1,28 +1,17 @@
import { NetworkParamsDocument } from '@vegaprotocol/network-parameters';
import type { MockedResponse } from '@apollo/client/testing';
import type { NetworkParamsQuery } from '@vegaprotocol/network-parameters';
import type { PubKey, VegaWalletContextShape } from '@vegaprotocol/wallet';
import type { VoteValue } from '@vegaprotocol/types';
import type { UserVoteQuery } from '../components/vote-details/__generated__/Vote';
import { UserVoteDocument } from '../components/vote-details/__generated__/Vote';
import faker from 'faker';
import { type Key } from '@vegaprotocol/wallet';
export const mockPubkey: PubKey = {
export const mockPubkey: Key = {
publicKey: '0x123',
name: 'test key 1',
};
export const mockWalletContext = {
pubKey: mockPubkey.publicKey,
pubKeys: [mockPubkey],
isReadOnly: false,
sendTx: jest.fn().mockReturnValue(Promise.resolve(null)),
connect: jest.fn(),
disconnect: jest.fn(),
selectPubKey: jest.fn(),
connector: null,
} as unknown as VegaWalletContextShape;
const mockEthereumConfig = {
network_id: '3',
chain_id: '3',
@@ -1,13 +1,11 @@
import classNames from 'classnames';
import { useTranslation } from 'react-i18next';
import { useVegaWalletDialogStore } from '@vegaprotocol/wallet';
import { useDialogStore } from '@vegaprotocol/wallet-react';
import { Button } from '@vegaprotocol/ui-toolkit';
import { SubHeading } from '../../components/heading';
export const ConnectToSeeRewards = () => {
const { openVegaWalletDialog } = useVegaWalletDialogStore((store) => ({
openVegaWalletDialog: store.openVegaWalletDialog,
}));
const openVegaWalletDialog = useDialogStore((store) => store.open);
const { t } = useTranslation();
const classes = classNames(
@@ -4,7 +4,7 @@ import { AsyncRenderer, Pagination } from '@vegaprotocol/ui-toolkit';
import { removePaginationWrapper } from '@vegaprotocol/utils';
import type { EpochFieldsFragment } from '../home/__generated__/Rewards';
import { useRewardsQuery } from '../home/__generated__/Rewards';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { EpochIndividualRewardsTable } from './epoch-individual-rewards-table';
import { generateEpochIndividualRewardsList } from './generate-epoch-individual-rewards-list';
import { calculateEpochOffset } from '../../../lib/epoch-pagination';
@@ -10,7 +10,7 @@ import {
Toggle,
ExternalLink,
} from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import {
useNetworkParams,
NetworkParams,
@@ -33,8 +33,8 @@ let mockVegaWalletHookValue: {
pubKey: null,
};
jest.mock('@vegaprotocol/wallet', () => ({
...jest.requireActual('@vegaprotocol/wallet'),
jest.mock('@vegaprotocol/wallet-react', () => ({
...jest.requireActual('@vegaprotocol/wallet-react'),
useVegaWallet: jest.fn(() => mockVegaWalletHookValue),
}));
@@ -2,7 +2,7 @@ import { useWeb3React } from '@web3-react/core';
import { useTranslation } from 'react-i18next';
import { EthConnectPrompt } from '../../../../../components/eth-connect-prompt';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { ConnectToVega } from '../../../../../components/connect-to-vega';
export const StakingWalletsContainer = ({
@@ -33,8 +33,8 @@ let mockVegaWalletHookValue: {
pubKey: null,
};
jest.mock('@vegaprotocol/wallet', () => ({
...jest.requireActual('@vegaprotocol/wallet'),
jest.mock('@vegaprotocol/wallet-react', () => ({
...jest.requireActual('@vegaprotocol/wallet-react'),
useVegaWallet: jest.fn(() => mockVegaWalletHookValue),
}));
@@ -1,4 +1,4 @@
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { useWeb3React } from '@web3-react/core';
import { EthConnectPrompt } from '../../../components/eth-connect-prompt';
import { DisassociatePage } from './components/disassociate-page';
@@ -5,7 +5,7 @@ import { useStakingQuery } from '../__generated__/Staking';
import { usePreviousEpochQuery } from '../__generated__/PreviousEpoch';
import { ValidatorTables } from './validator-tables';
import { useRefreshAfterEpoch } from '../../../hooks/use-refresh-after-epoch';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { getMultisigStatusInfo } from '../../../lib/get-multisig-status-info';
import { MultisigIncorrectNotice } from '../../../components/multisig-incorrect-notice';
@@ -2,7 +2,7 @@ import React from 'react';
import { useTranslation } from 'react-i18next';
import { useParams } from 'react-router-dom';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import {
addDecimal,
removePaginationWrapper,
@@ -1,5 +1,5 @@
import { Callout, Intent, Splash } from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { useTranslation } from 'react-i18next';
import { useRefreshAfterEpoch } from '../../../hooks/use-refresh-after-epoch';
import { SplashLoader } from '../../../components/splash-loader';
@@ -1,78 +0,0 @@
import React from 'react';
import * as Sentry from '@sentry/react';
import { Button, Callout, Intent, Loader } from '@vegaprotocol/ui-toolkit';
import { useTranslation } from 'react-i18next';
import { useAppState } from '../../../contexts/app-state/app-state-context';
import type { BigNumber } from '../../../lib/bignumber';
import type { UndelegateSubmissionBody } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { removeDecimal } from '@vegaprotocol/utils';
interface PendingStakeProps {
pendingAmount: BigNumber;
nodeId: string;
pubKey: string;
}
enum FormState {
Default,
Pending,
Success,
Failure,
}
export const PendingStake = ({
pendingAmount,
nodeId,
pubKey,
}: PendingStakeProps) => {
const { t } = useTranslation();
const { sendTx } = useVegaWallet();
const { appState } = useAppState();
const [formState, setFormState] = React.useState(FormState.Default);
const removeStakeNow = async () => {
setFormState(FormState.Pending);
try {
const command: UndelegateSubmissionBody = {
undelegateSubmission: {
nodeId,
amount: removeDecimal(pendingAmount.toString(), appState.decimals),
method: 'METHOD_NOW',
},
};
await sendTx(pubKey, command);
} catch (err) {
setFormState(FormState.Failure);
Sentry.captureException(err);
}
};
if (formState === FormState.Failure) {
return (
<Callout
intent={Intent.Danger}
title={t('failedToRemovePendingStake', { pendingAmount })}
>
<p>{t('pleaseTryAgain')}</p>
</Callout>
);
} else if (formState === FormState.Pending) {
return (
<Callout
icon={<Loader size="small" />}
title={t('removingPendingStake', { pendingAmount })}
/>
);
}
return (
<div className="py-4">
<h2>{t('pendingNomination')}</h2>
<p>{t('pendingNominationNextEpoch', { pendingAmount })}</p>
<Button onClick={() => removeStakeNow()}>
{t('cancelPendingEpochNomination')}
</Button>
</div>
);
};
@@ -27,11 +27,11 @@ import {
NetworkParams,
} from '@vegaprotocol/network-parameters';
import { useBalances } from '../../../lib/balances/balances-store';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { SubHeading } from '../../../components/heading';
import type {
DelegateSubmissionBody,
UndelegateSubmissionBody,
import {
type DelegateSubmissionBody,
type UndelegateSubmissionBody,
} from '@vegaprotocol/wallet';
import Routes from '../../routes';
@@ -9,7 +9,7 @@ import {
useWithdrawalDialog,
WithdrawalsTable,
} from '@vegaprotocol/withdraws';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { useDataProvider } from '@vegaprotocol/data-provider';
import { useDocumentTitle } from '../../hooks/use-document-title';
import type { RouteChildProps } from '../index';
+2 -4
View File
@@ -6,7 +6,7 @@ import {
VegaIconNames,
useToasts,
} from '@vegaprotocol/ui-toolkit';
import { useVegaWalletDialogStore } from '@vegaprotocol/wallet';
import { useDialogStore } from '@vegaprotocol/wallet-react';
import {
useEthereumTransactionToasts,
useEthereumWithdrawApprovalsToasts,
@@ -19,9 +19,7 @@ import { useTranslation } from 'react-i18next';
const WalletDisconnectAdditionalContent = () => {
const { t } = useTranslation();
const { hideToast } = useWalletDisconnectToastActions();
const openVegaWalletDialog = useVegaWalletDialogStore(
(store) => store.openVegaWalletDialog
);
const openVegaWalletDialog = useDialogStore((store) => store.open);
return (
<p className="mt-2">
<TradingButton
@@ -5,7 +5,7 @@ import {
VegaIcon,
VegaIconNames,
} from '@vegaprotocol/ui-toolkit';
import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
import { useVegaWallet, useDialogStore } from '@vegaprotocol/wallet-react';
import { addDecimalsFormatNumber } from '@vegaprotocol/utils';
import { useT } from '../../lib/use-t';
import { useReferralSetTransaction } from '../../lib/hooks/use-referral-set-transaction';
@@ -26,9 +26,7 @@ export const CompetitionsCreateTeam = () => {
usePageTitle(t('Create a team'));
const { isReadOnly, pubKey } = useVegaWallet();
const openWalletDialog = useVegaWalletDialogStore(
(store) => store.openVegaWalletDialog
);
const openWalletDialog = useDialogStore((store) => store.open);
return (
<ErrorBoundary feature="create-team">
@@ -31,7 +31,7 @@ import { TeamStats } from '../../components/competitions/team-stats';
import { usePageTitle } from '../../lib/hooks/use-page-title';
import { ErrorBoundary } from '../../components/error-boundary';
import { LayoutWithGradient } from '../../components/layouts-inner';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { JoinTeam } from './join-team';
import { UpdateTeamButton } from './update-team-button';
import {
@@ -2,7 +2,7 @@ import { ErrorBoundary } from '../../components/error-boundary';
import { usePageTitle } from '../../lib/hooks/use-page-title';
import { Box } from '../../components/competitions/box';
import { useT } from '../../lib/use-t';
import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
import { useVegaWallet, useDialogStore } from '@vegaprotocol/wallet-react';
import {
Intent,
Loader,
@@ -24,9 +24,7 @@ export const CompetitionsUpdateTeam = () => {
const t = useT();
usePageTitle([t('Competitions'), t('Update a team')]);
const { pubKey, isReadOnly } = useVegaWallet();
const openWalletDialog = useVegaWalletDialogStore(
(store) => store.openVegaWalletDialog
);
const openWalletDialog = useDialogStore((store) => store.open);
const { teamId } = useParams<{ teamId: string }>();
if (!teamId) {
return <Navigate to={Links.COMPETITIONS()} />;
@@ -29,7 +29,7 @@ describe('JoinButton', () => {
});
it('disables button if not connected', async () => {
render(<JoinButton {...props} pubKey={null} />);
render(<JoinButton {...props} pubKey={undefined} />);
const button = screen.getByRole('button');
expect(button).toBeDisabled();
await userEvent.hover(button);
@@ -6,7 +6,10 @@ import {
VegaIcon,
VegaIconNames,
} from '@vegaprotocol/ui-toolkit';
import { useSimpleTransaction, useVegaWallet } from '@vegaprotocol/wallet';
import {
useSimpleTransaction,
useVegaWallet,
} from '@vegaprotocol/wallet-react';
import { useT } from '../../lib/use-t';
import { type Team } from '../../lib/hooks/use-team';
import { useState } from 'react';
@@ -59,7 +62,7 @@ export const JoinButton = ({
partyTeam,
onJoin,
}: {
pubKey: string | null;
pubKey: string | undefined;
isReadOnly: boolean;
team: Team;
partyTeam?: Team;
@@ -14,11 +14,11 @@ import { URL_REGEX, isValidVegaPublicKey } from '@vegaprotocol/utils';
import { type useReferralSetTransaction } from '../../lib/hooks/use-referral-set-transaction';
import { useT } from '../../lib/use-t';
import { useForm, Controller } from 'react-hook-form';
import type {
CreateReferralSet,
UpdateReferralSet,
Status,
import {
type CreateReferralSet,
type UpdateReferralSet,
} from '@vegaprotocol/wallet';
import { type Status } from '@vegaprotocol/wallet-react';
import classNames from 'classnames';
import { useLayoutEffect, useState } from 'react';
@@ -1,6 +1,6 @@
import { type Team } from '../../lib/hooks/use-team';
import { type ComponentProps } from 'react';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { Intent, TradingAnchorButton } from '@vegaprotocol/ui-toolkit';
import { Links } from '../../lib/links';
import { useT } from '../../lib/use-t';
@@ -1,12 +1,12 @@
import classNames from 'classnames';
import { Intent, TradingAnchorButton } from '@vegaprotocol/ui-toolkit';
import { GetStartedCheckList } from '../../components/welcome-dialog';
import { useOnboardingStore } from '../../stores/onboarding';
import {
useGetOnboardingStep,
useOnboardingStore,
OnboardingStep,
} from '../../components/welcome-dialog/use-get-onboarding-step';
} from '../../lib/hooks/use-get-onboarding-step';
import { Links } from '../../lib/links';
import classNames from 'classnames';
import { useT } from '../../lib/use-t';
export const DepositGetStarted = () => {
@@ -1,7 +1,7 @@
import { matchFilter, lpAggregatedDataProvider } from '@vegaprotocol/liquidity';
import { useDataProvider } from '@vegaprotocol/data-provider';
import { Tab, Tabs } from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import { LiquidityContainer } from '../../components/liquidity-container';
@@ -1,5 +1,4 @@
import { act, render, screen, waitFor, within } from '@testing-library/react';
// import userEvent from '@testing-library/user-event';
import { MemoryRouter } from 'react-router-dom';
import { Closed } from './closed';
import { MarketStateMapping, PropertyKeyType } from '@vegaprotocol/types';
@@ -18,8 +17,6 @@ import {
MarketsDocument,
getAsset,
} from '@vegaprotocol/markets';
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
import { VegaWalletContext } from '@vegaprotocol/wallet';
import { addDecimalsFormatNumber } from '@vegaprotocol/utils';
import {
createMarketFragment,
@@ -37,7 +34,6 @@ describe('Closed', () => {
3
).toISOString();
const settlementDateTag = `settlement-expiry-date:${settlementDateMetaDate}`;
const pubKey = 'pubKey';
const marketId = 'market-0';
const settlementDataProperty = 'spec-binding';
const settlementDataId = 'settlement-data-oracle-id';
@@ -175,11 +171,7 @@ describe('Closed', () => {
render(
<MemoryRouter>
<MockedProvider mocks={mocks}>
<VegaWalletContext.Provider
value={{ pubKey } as VegaWalletContextShape}
>
<Closed />
</VegaWalletContext.Provider>
<Closed />
</MockedProvider>
</MemoryRouter>
);
@@ -14,7 +14,7 @@ import { useT } from '../../lib/use-t';
import { useScreenDimensions } from '@vegaprotocol/react-helpers';
import { useEffect } from 'react';
import classNames from 'classnames';
import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
import { useVegaWallet, useDialogStore } from '@vegaprotocol/wallet-react';
const ViewInitializer = () => {
const currentRouteId = useGetCurrentRouteId();
@@ -34,9 +34,7 @@ export const MarketsMobileSidebar = () => {
const t = useT();
const currentRouteId = useGetCurrentRouteId();
const { pubKeys, isReadOnly } = useVegaWallet();
const openVegaWalletDialog = useVegaWalletDialogStore(
(store) => store.openVegaWalletDialog
);
const openVegaWalletDialog = useDialogStore((store) => store.open);
return (
<Routes>
@@ -15,8 +15,6 @@ import {
MarketsDocument,
MarketsCandlesDocument,
} from '@vegaprotocol/markets';
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
import { VegaWalletContext } from '@vegaprotocol/wallet';
import {
marketsQuery,
marketsDataQuery,
@@ -27,7 +25,6 @@ import userEvent from '@testing-library/user-event';
describe('Open', () => {
let originalNow: typeof Date.now;
const mockNowTimestamp = 1672531200000;
const pubKey = 'pubKey';
const marketsQueryData = marketsQuery();
const marketsMock: MockedResponse<MarketsQuery> = {
@@ -80,11 +77,7 @@ describe('Open', () => {
<MockedProvider
mocks={[marketsMock, marketsCandlesMock, marketsDataMock]}
>
<VegaWalletContext.Provider
value={{ pubKey } as VegaWalletContextShape}
>
<OpenMarkets />
</VegaWalletContext.Provider>
<OpenMarkets />
</MockedProvider>
</MemoryRouter>
);
@@ -14,8 +14,8 @@ import { RainbowButton } from '../../components/rainbow-button';
import {
useSimpleTransaction,
useVegaWallet,
useVegaWalletDialogStore,
} from '@vegaprotocol/wallet';
useDialogStore,
} from '@vegaprotocol/wallet-react';
import { useIsInReferralSet, useReferral } from './hooks/use-referral';
import { Routes } from '../../lib/links';
import { Statistics, useStats } from './referral-statistics';
@@ -83,9 +83,7 @@ export const ApplyCodeForm = ({ onSuccess }: { onSuccess?: () => void }) => {
const t = useT();
const program = useReferralProgram();
const navigate = useNavigate();
const openWalletDialog = useVegaWalletDialogStore(
(store) => store.openVegaWalletDialog
);
const openWalletDialog = useDialogStore((store) => store.open);
const { isReadOnly, pubKey } = useVegaWallet();
const { isEligible, requiredFunds } = useFundsAvailable();
@@ -1,4 +1,4 @@
import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
import { useVegaWallet, useDialogStore } from '@vegaprotocol/wallet-react';
import { RainbowButton } from '../../components/rainbow-button';
import { useState } from 'react';
import {
@@ -28,9 +28,7 @@ export const CreateCodeContainer = () => {
const t = useT();
const { pubKey, isReadOnly } = useVegaWallet();
const isInReferralSet = useIsInReferralSet(pubKey);
const openWalletDialog = useVegaWalletDialogStore(
(store) => store.openVegaWalletDialog
);
const openWalletDialog = useDialogStore((store) => store.open);
// Navigate to the index page when already in the referral set.
if (isInReferralSet) {
@@ -1,4 +1,4 @@
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { useFundsAvailableQuery } from './__generated__/FundsAvailable';
import compact from 'lodash/compact';
import BigNumber from 'bignumber.js';
@@ -6,7 +6,7 @@ import {
Button,
} from '@vegaprotocol/ui-toolkit';
import { useReferral } from './use-referral';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { useEffect } from 'react';
import { useT } from '../../../lib/use-t';
import { matchPath, useLocation, useNavigate } from 'react-router-dom';
@@ -15,7 +15,7 @@ export const DEFAULT_AGGREGATION_DAYS = 30;
export type Role = 'referrer' | 'referee';
type UseReferralArgs = (
| { code: string | undefined }
| { pubKey: string | null; role: Role }
| { pubKey: string | undefined; role: Role }
) & {
aggregationEpochs?: number;
};
@@ -188,7 +188,7 @@ const retrieveReferralSetData = (data: ReferralSetsQuery | undefined) =>
? data.referralSets.edges[0]?.node
: undefined;
export const useIsInReferralSet = (pubKey: string | null) => {
export const useIsInReferralSet = (pubKey: string | undefined) => {
const [asRefereeVariables, asRefereeSkip] = prepareVariables({
pubKey,
role: 'referee',
@@ -1,9 +1,5 @@
import { MockedProvider, type MockedResponse } from '@apollo/react-testing';
import { render, screen, waitFor } from '@testing-library/react';
import {
VegaWalletContext,
type VegaWalletContextShape,
} from '@vegaprotocol/wallet';
import { ReferralStatistics } from './referral-statistics';
import {
ReferralProgramDocument,
@@ -25,9 +21,22 @@ import {
type RefereesQuery,
} from './hooks/__generated__/Referees';
import { MemoryRouter } from 'react-router-dom';
import {
mockConfig,
MockedWalletProvider,
} from '@vegaprotocol/wallet-react/testing';
const MOCK_PUBKEY =
'1234567890123456789012345678901234567890123456789012345678901234';
const mockKeys = [
{
name: 'Key 1',
publicKey: '1'.repeat(64),
},
{
name: 'Key 2',
publicKey: '2'.repeat(64),
},
];
const MOCK_PUBKEY = mockKeys[0].publicKey;
const MOCK_STAKE_AVAILABLE: StakeAvailableQuery = {
networkParameter: {
@@ -301,23 +310,29 @@ const refereesMock30: MockedResponse<RefereesQuery, RefereesQueryVariables> = {
describe('ReferralStatistics', () => {
const renderComponent = (mocks: MockedResponse[]) => {
const walletContext = {
pubKey: MOCK_PUBKEY,
isReadOnly: false,
sendTx: jest.fn(),
} as unknown as VegaWalletContextShape;
return render(
<MemoryRouter>
<VegaWalletContext.Provider value={walletContext}>
<MockedProvider mocks={mocks} showWarnings={false}>
<MockedProvider mocks={mocks} showWarnings={false}>
<MockedWalletProvider>
<ReferralStatistics />
</MockedProvider>
</VegaWalletContext.Provider>
</MockedWalletProvider>
</MockedProvider>
</MemoryRouter>
);
};
beforeAll(() => {
mockConfig.store.setState({
status: 'connected',
keys: mockKeys,
pubKey: mockKeys[0].publicKey,
});
});
afterAll(() => {
mockConfig.reset();
});
it('displays apply code when no data has been found for given pubkey', () => {
renderComponent([]);
expect(
@@ -11,7 +11,7 @@ import {
truncateMiddle,
TextChildrenTooltip as Tooltip,
} from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import {
addDecimalsFormatNumber,
formatNumber,
@@ -9,7 +9,7 @@ import { TiersContainer } from './tiers';
import { TabLink } from './buttons';
import { Outlet, useMatch } from 'react-router-dom';
import { Routes } from '../../lib/links';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { useReferral } from './hooks/use-referral';
import { REFERRAL_DOCS_LINK } from './constants';
import classNames from 'classnames';
@@ -1,7 +1,7 @@
import { useCallback } from 'react';
import { Splash } from '@vegaprotocol/ui-toolkit';
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import type { PinnedAsset } from '@vegaprotocol/accounts';
import { AccountManager } from '@vegaprotocol/accounts';
import { create } from 'zustand';
@@ -2,42 +2,24 @@ import type { InMemoryCacheConfig } from '@apollo/client';
import {
AppFailure,
AppLoader,
DocsLinks,
NetworkLoader,
NodeFailure,
NodeGuard,
useEnvironment,
} from '@vegaprotocol/environment';
import { VegaWalletProvider } from '@vegaprotocol/wallet';
import type { ReactNode } from 'react';
import { type ReactNode } from 'react';
import { Web3Provider } from './web3-provider';
import { useT } from '../../lib/use-t';
import { DataLoader } from './data-loader';
import { useChainId } from '@vegaprotocol/wallet';
import { WalletProvider } from '@vegaprotocol/wallet-react';
import { useVegaWalletConfig } from '../../lib/hooks/use-vega-wallet-config';
export const Bootstrapper = ({ children }: { children: ReactNode }) => {
const t = useT();
const {
error,
VEGA_URL,
VEGA_ENV,
VEGA_WALLET_URL,
VEGA_EXPLORER_URL,
MOZILLA_EXTENSION_URL,
CHROME_EXTENSION_URL,
} = useEnvironment();
const { error, VEGA_URL } = useEnvironment();
const config = useVegaWalletConfig();
const chainId = useChainId(VEGA_URL);
if (
!VEGA_URL ||
!VEGA_WALLET_URL ||
!VEGA_EXPLORER_URL ||
!CHROME_EXTENSION_URL ||
!MOZILLA_EXTENSION_URL ||
!DocsLinks ||
!chainId
) {
if (!config) {
return <AppLoader />;
}
@@ -72,22 +54,7 @@ export const Bootstrapper = ({ children }: { children: ReactNode }) => {
<AppFailure title={t('Could not configure web3 provider')} />
}
>
<VegaWalletProvider
config={{
network: VEGA_ENV,
vegaUrl: VEGA_URL,
chainId,
vegaWalletServiceUrl: VEGA_WALLET_URL,
links: {
explorer: VEGA_EXPLORER_URL,
concepts: DocsLinks.VEGA_WALLET_CONCEPTS_URL,
chromeExtensionUrl: CHROME_EXTENSION_URL,
mozillaExtensionUrl: MOZILLA_EXTENSION_URL,
},
}}
>
{children}
</VegaWalletProvider>
<WalletProvider config={config}>{children}</WalletProvider>
</Web3Provider>
</DataLoader>
</NodeGuard>
@@ -2,7 +2,7 @@ import { Splash } from '@vegaprotocol/ui-toolkit';
import { DepositsTable } from '@vegaprotocol/deposits';
import { depositsProvider } from '@vegaprotocol/deposits';
import { useDataProvider } from '@vegaprotocol/data-provider';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { useT } from '../../lib/use-t';
export const DepositsContainer = () => {
@@ -1,6 +1,6 @@
import maxBy from 'lodash/maxBy';
import minBy from 'lodash/minBy';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import {
useNetworkParams,
NetworkParams,
@@ -1,4 +1,4 @@
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { FillsManager } from '@vegaprotocol/fills';
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
@@ -1,4 +1,4 @@
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { FundingPaymentsManager } from '@vegaprotocol/funding-payments';
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
@@ -1,6 +1,6 @@
import { LedgerExportForm } from '@vegaprotocol/ledger';
import { Loader, Splash } from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { useEnvironment } from '@vegaprotocol/environment';
import type { PartyAssetFieldsFragment } from '@vegaprotocol/assets';
import { usePartyAssetsQuery } from '@vegaprotocol/assets';
+46 -32
View File
@@ -1,47 +1,38 @@
import { render, screen, within } from '@testing-library/react';
import { act, render, screen, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { MemoryRouter } from 'react-router-dom';
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
import { VegaWalletContext } from '@vegaprotocol/wallet';
import { Navbar } from './navbar';
import { useGlobalStore } from '../../stores';
import { ENV, useFeatureFlags } from '@vegaprotocol/environment';
import {
mockConfig,
MockedWalletProvider,
} from '@vegaprotocol/wallet-react/testing';
jest.mock('@vegaprotocol/proposals', () => ({
ProtocolUpgradeCountdown: () => null,
}));
describe('Navbar', () => {
const pubKey = '000';
const pubKeys = [
const mockKeys = [
{
publicKey: pubKey,
name: 'Pub key 0',
name: 'Key 1',
publicKey: '1'.repeat(64),
},
{
publicKey: '111',
name: 'Pub key 1',
name: 'Key 2',
publicKey: '2'.repeat(64),
},
];
const marketId = 'abc';
const navbarContent = 'navbar-menu-content';
const renderComponent = (
initialEntries?: string[],
walletContext?: Partial<VegaWalletContextShape>
) => {
const context = {
pubKey,
pubKeys,
selectPubKey: jest.fn(),
disconnect: jest.fn(),
...walletContext,
} as VegaWalletContextShape;
const renderComponent = (initialEntries?: string[]) => {
return render(
<MemoryRouter initialEntries={initialEntries}>
<VegaWalletContext.Provider value={context}>
<MockedWalletProvider>
<Navbar />
</VegaWalletContext.Provider>
</MockedWalletProvider>
</MemoryRouter>
);
};
@@ -57,6 +48,12 @@ describe('Navbar', () => {
jest.clearAllMocks();
});
afterEach(() => {
act(() => {
mockConfig.reset();
});
});
it('should be properly rendered', () => {
renderComponent();
@@ -125,26 +122,38 @@ describe('Navbar', () => {
});
it('can open wallet menu on small screens and change pubkey', async () => {
const mockSelectPubKey = jest.fn();
renderComponent(undefined, { selectPubKey: mockSelectPubKey });
mockConfig.store.setState({
status: 'connected',
keys: mockKeys,
pubKey: mockKeys[0].publicKey,
});
const mockSelectPubKey = jest.spyOn(mockConfig.store, 'setState');
renderComponent(undefined);
await userEvent.click(screen.getByRole('button', { name: 'Wallet' }));
const menuEl = screen.getByTestId(navbarContent);
expect(menuEl).toBeInTheDocument();
const menu = within(menuEl);
expect(menu.getAllByTestId(/key-\d+-mobile/)).toHaveLength(pubKeys.length);
expect(menu.getAllByTestId(/key-\d+-mobile/)).toHaveLength(mockKeys.length);
const activeKey = within(menu.getByTestId('key-000-mobile'));
expect(activeKey.getByText(pubKeys[0].name)).toBeInTheDocument();
const activeKey = within(menu.getByTestId(/key-1+-mobile/));
expect(activeKey.getByText(mockKeys[0].name)).toBeInTheDocument();
expect(activeKey.getByTestId('icon-tick')).toBeInTheDocument();
const inactiveKey = within(menu.getByTestId('key-111-mobile'));
await userEvent.click(inactiveKey.getByText(pubKeys[1].name));
expect(mockSelectPubKey).toHaveBeenCalledWith(pubKeys[1].publicKey);
const inactiveKey = within(menu.getByTestId(/key-2+-mobile/));
await userEvent.click(inactiveKey.getByText(mockKeys[1].name));
expect(mockSelectPubKey).toHaveBeenCalledWith({
pubKey: mockKeys[1].publicKey,
});
});
it('can transfer and close menu', async () => {
mockConfig.store.setState({
status: 'connected',
keys: mockKeys,
pubKey: mockKeys[0].publicKey,
});
renderComponent();
await userEvent.click(screen.getByRole('button', { name: 'Wallet' }));
@@ -158,8 +167,13 @@ describe('Navbar', () => {
});
it('can disconnect and close menu', async () => {
const mockDisconnect = jest.fn();
renderComponent(undefined, { disconnect: mockDisconnect });
mockConfig.store.setState({
status: 'connected',
keys: mockKeys,
pubKey: mockKeys[0].publicKey,
});
const mockDisconnect = jest.spyOn(mockConfig, 'disconnect');
renderComponent(undefined);
await userEvent.click(screen.getByRole('button', { name: 'Wallet' }));
const menuEl = screen.getByTestId(navbarContent);
+4 -8
View File
@@ -25,7 +25,7 @@ import { NavLink } from 'react-router-dom';
import { Links } from '../../lib/links';
import classNames from 'classnames';
import { VegaWalletMenu } from '../vega-wallet';
import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
import { useDialogStore, useWallet } from '@vegaprotocol/wallet-react';
import { WalletIcon } from '../icons/wallet';
import { ProtocolUpgradeCountdown } from '@vegaprotocol/proposals';
import { useT, useI18n } from '../../lib/use-t';
@@ -40,13 +40,9 @@ export const Navbar = ({ theme = 'system' }: { theme?: Theme }) => {
// menu state for small screens
const [menu, setMenu] = useState<MenuState>(null);
const { pubKey } = useVegaWallet();
const status = useWallet((store) => store.status);
const openVegaWalletDialog = useVegaWalletDialogStore(
(store) => store.openVegaWalletDialog
);
const isConnected = pubKey !== null;
const openVegaWalletDialog = useDialogStore((store) => store.open);
const navTextClasses = 'text-vega-clight-200 dark:text-vega-cdark-200';
const rootClasses = classNames(
@@ -88,7 +84,7 @@ export const Navbar = ({ theme = 'system' }: { theme?: Theme }) => {
</div>
<NavbarMobileButton
onClick={() => {
if (isConnected) {
if (status === 'connected') {
setMenu((x) => (x === 'wallet' ? null : 'wallet'));
} else {
openVegaWalletDialog();
@@ -1,7 +1,7 @@
import { useDataGridEvents } from '@vegaprotocol/datagrid';
import { Filter, OrderListManager } from '@vegaprotocol/orders';
import { Splash } from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import { useNavigateWithMeta } from '../../lib/hooks/use-market-click-handler';
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
@@ -1,7 +1,7 @@
import { useDataGridEvents } from '@vegaprotocol/datagrid';
import { PositionsManager } from '@vegaprotocol/positions';
import { Splash } from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import type { DataGridSlice } from '../../stores/datagrid-store-slice';
import { createDataGridSlice } from '../../stores/datagrid-store-slice';
import type { StateCreator } from 'zustand';
@@ -172,7 +172,9 @@ describe('Vesting', () => {
});
it('doesnt use multiplier if not connected', () => {
render(<Vesting baseRate={'0.25'} pubKey={null} multiplier={undefined} />);
render(
<Vesting baseRate={'0.25'} pubKey={undefined} multiplier={undefined} />
);
expect(screen.getByTestId('vesting-rate')).toHaveTextContent('25%');
@@ -199,7 +201,11 @@ describe('Multipliers', () => {
it('shows not connected state', () => {
render(
<Multipliers pubKey={null} streakMultiplier="3" hoarderMultiplier="2" />
<Multipliers
pubKey={undefined}
streakMultiplier="3"
hoarderMultiplier="2"
/>
);
expect(
@@ -7,7 +7,7 @@ import {
useNetworkParams,
} from '@vegaprotocol/network-parameters';
import { AccountType } from '@vegaprotocol/types';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet-react';
import BigNumber from 'bignumber.js';
import {
Card,
@@ -309,7 +309,7 @@ type VestingBalances = NonNullable<
>['vestingBalancesSummary'];
export type RewardPotProps = {
pubKey: string | null;
pubKey: string | undefined;
accounts: Account[] | null;
assetId: string; // VEGA
vestingBalancesSummary: VestingBalances | undefined;
@@ -469,7 +469,7 @@ export const Vesting = ({
baseRate,
multiplier,
}: {
pubKey: string | null;
pubKey: string | undefined;
baseRate: string;
multiplier?: string;
}) => {
@@ -506,7 +506,7 @@ export const Multipliers = ({
streakMultiplier,
hoarderMultiplier,
}: {
pubKey: string | null;
pubKey: string | undefined;
streakMultiplier?: string;
hoarderMultiplier?: string;
}) => {
@@ -25,7 +25,7 @@ export const RewardsHistoryContainer = ({
pubKey,
assets,
}: {
pubKey: string | null;
pubKey: string | undefined;
epoch: number;
assets: Record<string, AssetFieldsFragment>;
}) => {
@@ -129,7 +129,7 @@ export const RewardHistoryTable = ({
epochRewardSummaries: RewardsHistoryQuery['epochRewardSummaries'];
partyRewards: PartyRewardsConnection;
assets: Record<string, AssetFieldsFragment> | null;
pubKey: string | null;
pubKey: string | undefined;
epoch: number;
epochVariables: {
from: number;
@@ -145,7 +145,7 @@ export const RewardHistoryTable = ({
epochRewardSummaries,
partyRewards,
assets,
partyId: isParty ? pubKey : null,
partyId: isParty ? pubKey : undefined,
});
const columnDefs = useMemo<ColDef<RewardRow>[]>(() => {
@@ -97,7 +97,7 @@ export const useRewardsRowData = ({
partyRewards: PartyRewardsConnection;
epochRewardSummaries: RewardsHistoryQuery['epochRewardSummaries'];
assets: Record<string, Asset> | null;
partyId: string | null;
partyId: string | undefined;
}) => {
if (partyId) {
const rewards = removePaginationWrapper(partyRewards?.edges).map((r) => ({
@@ -0,0 +1 @@
export { RiskAckContent } from './risk-ack-content';

Some files were not shown because too many files have changed in this diff Show More