chore(web3): wallet connect v2 (#3324)
This commit is contained in:
parent
9e054c7c85
commit
360624282d
@ -15,6 +15,7 @@ NX_VEGA_DOCS_URL=https://docs.vega.xyz/mainnet
|
||||
NX_TRANCHES_SERVICE_URL=https://tranches-stagnet3-k8s.ops.vega.xyz
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/test/announcements.json
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
||||
|
||||
#Test configuration variables
|
||||
CYPRESS_FAIRGROUND=false
|
||||
|
@ -68,8 +68,10 @@ context(
|
||||
it('should have connector list visible', function () {
|
||||
const connectList = [
|
||||
'Unknown',
|
||||
'MetaMask, Brave or other injected web wallet',
|
||||
'MetaMask',
|
||||
'Coinbase',
|
||||
'WalletConnect',
|
||||
'WalletConnect Legacy',
|
||||
];
|
||||
cy.get(connectorList).within(() => {
|
||||
cy.get('button').each(($btn, i) => {
|
||||
|
@ -14,6 +14,7 @@ NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
NX_DELEGATIONS_PAGINATION=50
|
||||
NX_TRANCHES_SERVICE_URL=https://tranches-stagnet3-k8s.ops.vega.xyz
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/main/announcements.json
|
||||
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
||||
|
||||
#Test configuration variables
|
||||
CYPRESS_FAIRGROUND=false
|
||||
|
@ -26,6 +26,7 @@ import {
|
||||
import { Loader } from '@vegaprotocol/ui-toolkit';
|
||||
import colors from 'tailwindcss/colors';
|
||||
import { useBalances } from '../../lib/balances/balances-store';
|
||||
import { useWeb3Disconnect } from '@vegaprotocol/web3';
|
||||
|
||||
const removeLeadingAddressSymbol = (key: string) => {
|
||||
if (key && key.length > 2 && key.slice(0, 2) === '0x') {
|
||||
@ -184,6 +185,7 @@ export const EthWallet = () => {
|
||||
const { appDispatch } = useAppState();
|
||||
const { account, connector } = useWeb3React();
|
||||
const pendingTxs = usePendingTransactions();
|
||||
const disconnect = useWeb3Disconnect(connector);
|
||||
|
||||
return (
|
||||
<WalletCard>
|
||||
@ -239,7 +241,7 @@ export const EthWallet = () => {
|
||||
<div className="flex justify-end">
|
||||
<button
|
||||
className="underline"
|
||||
onClick={() => connector.deactivate()}
|
||||
onClick={() => disconnect()}
|
||||
data-testid="disconnect-from-eth-wallet-button"
|
||||
>
|
||||
{t('disconnect')}
|
||||
|
@ -1,5 +1,10 @@
|
||||
import { Button, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { getChainName, Web3ConnectDialog } from '@vegaprotocol/web3';
|
||||
import {
|
||||
getChainName,
|
||||
useWeb3ConnectStore,
|
||||
useWeb3Disconnect,
|
||||
Web3ConnectDialog,
|
||||
} from '@vegaprotocol/web3';
|
||||
import { useWeb3React } from '@web3-react/core';
|
||||
import type { ReactElement } from 'react';
|
||||
import { useCallback, useEffect } from 'react';
|
||||
@ -51,7 +56,9 @@ interface Web3ContentProps {
|
||||
}
|
||||
|
||||
export const Web3Content = ({ children, appChainId }: Web3ContentProps) => {
|
||||
const { error, connector, chainId } = useWeb3React();
|
||||
const { connector, chainId } = useWeb3React();
|
||||
const error = useWeb3ConnectStore((store) => store.error);
|
||||
const disconnect = useWeb3Disconnect(connector);
|
||||
|
||||
useEffect(() => {
|
||||
if (connector?.connectEagerly) {
|
||||
@ -67,7 +74,7 @@ export const Web3Content = ({ children, appChainId }: Web3ContentProps) => {
|
||||
<Splash>
|
||||
<div className="flex flex-col items-center gap-12">
|
||||
<p className="text-white">Something went wrong: {error.message}</p>
|
||||
<Button onClick={() => connector.deactivate()}>Disconnect</Button>
|
||||
<Button onClick={() => disconnect()}>Disconnect</Button>
|
||||
</div>
|
||||
</Splash>
|
||||
);
|
||||
@ -80,7 +87,7 @@ export const Web3Content = ({ children, appChainId }: Web3ContentProps) => {
|
||||
<p className="text-white">
|
||||
This app only works on {getChainName(appChainId)}
|
||||
</p>
|
||||
<Button onClick={() => connector.deactivate()}>Disconnect</Button>
|
||||
<Button onClick={() => disconnect()}>Disconnect</Button>
|
||||
</div>
|
||||
</Splash>
|
||||
);
|
||||
|
@ -1,20 +1,17 @@
|
||||
import { ethers } from 'ethers';
|
||||
import type { Web3ReactHooks } from '@web3-react/core';
|
||||
import { initializeConnector } from '@web3-react/core';
|
||||
import { MetaMask } from '@web3-react/metamask';
|
||||
import { WalletConnect } from '@web3-react/walletconnect';
|
||||
import type { Connector } from '@web3-react/types';
|
||||
import { ENV } from '../config/env';
|
||||
import { UrlConnector } from '@vegaprotocol/web3';
|
||||
import {
|
||||
initializeMetaMaskConnector,
|
||||
initializeWalletConnector,
|
||||
initializeWalletConnectLegacyConnector,
|
||||
initializeCoinbaseConnector,
|
||||
WALLETCONNECT_PROJECT_ID,
|
||||
initializeUrlConnector,
|
||||
} from '@vegaprotocol/web3';
|
||||
|
||||
const [metamask, metamaskHooks] = initializeConnector<MetaMask>(
|
||||
(actions) => new MetaMask(actions)
|
||||
);
|
||||
|
||||
const [urlConnector, urlHooks] = initializeConnector<UrlConnector>(
|
||||
(actions) =>
|
||||
new UrlConnector(actions, ENV.localProviderUrl, ENV.ethWalletMnemonic)
|
||||
);
|
||||
initializeUrlConnector(ENV.localProviderUrl, ENV.ethWalletMnemonic);
|
||||
|
||||
export const createDefaultProvider = (providerUrl: string, chainId: number) => {
|
||||
return new ethers.providers.JsonRpcProvider(providerUrl, chainId);
|
||||
@ -24,19 +21,14 @@ export const createConnectors = (providerUrl: string, chainId: number) => {
|
||||
if (isNaN(chainId)) {
|
||||
throw new Error('Invalid Ethereum chain ID for environment');
|
||||
}
|
||||
const [walletconnect, walletconnectHooks] =
|
||||
initializeConnector<WalletConnect>(
|
||||
(actions) =>
|
||||
new WalletConnect(actions, {
|
||||
rpc: {
|
||||
[chainId]: providerUrl,
|
||||
},
|
||||
}),
|
||||
[chainId]
|
||||
);
|
||||
|
||||
return [
|
||||
ENV.urlConnect ? [urlConnector, urlHooks] : null,
|
||||
[metamask, metamaskHooks],
|
||||
[walletconnect, walletconnectHooks],
|
||||
].filter(Boolean) as [Connector, Web3ReactHooks][];
|
||||
ENV.urlConnect
|
||||
? initializeUrlConnector(ENV.localProviderUrl, ENV.ethWalletMnemonic)
|
||||
: null,
|
||||
initializeMetaMaskConnector(),
|
||||
initializeCoinbaseConnector(providerUrl),
|
||||
initializeWalletConnector(WALLETCONNECT_PROJECT_ID, chainId, providerUrl),
|
||||
initializeWalletConnectLegacyConnector(chainId, providerUrl),
|
||||
].filter(Boolean) as unknown as [Connector, Web3ReactHooks][];
|
||||
};
|
||||
|
@ -2,4 +2,4 @@ NX_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet3/vegawallet-stagnet3.toml
|
||||
NX_VEGA_NETWORKS='{"TESTNET":"https://multisig-signer.fairground.wtf","MAINNET":"https://multisig-signer.vega.xyz"}'
|
||||
NX_VEGA_ENV=STAGNET3
|
||||
|
||||
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
||||
|
@ -9,6 +9,7 @@ import {
|
||||
} from '@vegaprotocol/environment';
|
||||
import { AsyncRenderer, Button, Lozenge } from '@vegaprotocol/ui-toolkit';
|
||||
import type { EthereumConfig } from '@vegaprotocol/web3';
|
||||
import { useWeb3Disconnect } from '@vegaprotocol/web3';
|
||||
import { useEthereumConfig, Web3Provider } from '@vegaprotocol/web3';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { ENV } from './config/env';
|
||||
@ -34,6 +35,7 @@ const pageWrapperClasses = classnames(
|
||||
|
||||
const ConnectedApp = ({ config }: { config: EthereumConfig | null }) => {
|
||||
const { account, connector } = useWeb3React();
|
||||
const disconnect = useWeb3Disconnect(connector);
|
||||
return (
|
||||
<main className="w-full max-w-3xl px-5 justify-self-center">
|
||||
<h1>{t('Multisig signer')}</h1>
|
||||
@ -41,7 +43,7 @@ const ConnectedApp = ({ config }: { config: EthereumConfig | null }) => {
|
||||
<p>
|
||||
Connected to Eth wallet: <Lozenge>{account}</Lozenge>
|
||||
</p>
|
||||
<Button onClick={() => connector.deactivate()}>Disconnect</Button>
|
||||
<Button onClick={() => disconnect()}>Disconnect</Button>
|
||||
</div>
|
||||
<ContractDetails config={config} />
|
||||
<h2>{t('Add or remove signer')}</h2>
|
||||
|
@ -1,5 +1,10 @@
|
||||
import { useEnvironment } from '@vegaprotocol/environment';
|
||||
import { getChainName, useEthereumConfig } from '@vegaprotocol/web3';
|
||||
import {
|
||||
getChainName,
|
||||
useEthereumConfig,
|
||||
useWeb3ConnectStore,
|
||||
useWeb3Disconnect,
|
||||
} from '@vegaprotocol/web3';
|
||||
import { Button, Splash, AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||
import { Web3ConnectDialog } from '@vegaprotocol/web3';
|
||||
import { useWeb3React } from '@web3-react/core';
|
||||
@ -55,7 +60,9 @@ export const Web3Content = ({
|
||||
appChainId,
|
||||
setDialogOpen,
|
||||
}: Web3ContentProps) => {
|
||||
const { error, connector, chainId } = useWeb3React();
|
||||
const { connector, chainId } = useWeb3React();
|
||||
const error = useWeb3ConnectStore((store) => store.error);
|
||||
const disconnect = useWeb3Disconnect(connector);
|
||||
|
||||
useEffect(() => {
|
||||
if (connector?.connectEagerly) {
|
||||
@ -71,7 +78,7 @@ export const Web3Content = ({
|
||||
<Splash>
|
||||
<div className="flex flex-col items-center gap-12">
|
||||
<p className="text-white">Something went wrong: {error.message}</p>
|
||||
<Button onClick={() => connector.deactivate()}>Disconnect</Button>
|
||||
<Button onClick={() => disconnect()}>Disconnect</Button>
|
||||
</div>
|
||||
</Splash>
|
||||
);
|
||||
@ -84,7 +91,7 @@ export const Web3Content = ({
|
||||
<p className="text-white">
|
||||
This app only works on {getChainName(appChainId)}
|
||||
</p>
|
||||
<Button onClick={() => connector.deactivate()}>Disconnect</Button>
|
||||
<Button onClick={() => disconnect()}>Disconnect</Button>
|
||||
</div>
|
||||
</Splash>
|
||||
);
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { ethers } from 'ethers';
|
||||
import type { Web3ReactHooks } from '@web3-react/core';
|
||||
import { initializeConnector } from '@web3-react/core';
|
||||
import { MetaMask } from '@web3-react/metamask';
|
||||
import { WalletConnect } from '@web3-react/walletconnect';
|
||||
import type { Connector } from '@web3-react/types';
|
||||
|
||||
const [metamask, metamaskHooks] = initializeConnector<MetaMask>(
|
||||
(actions) => new MetaMask(actions)
|
||||
);
|
||||
import {
|
||||
WALLETCONNECT_PROJECT_ID,
|
||||
initializeCoinbaseConnector,
|
||||
initializeMetaMaskConnector,
|
||||
initializeWalletConnectLegacyConnector,
|
||||
initializeWalletConnector,
|
||||
} from '@vegaprotocol/web3';
|
||||
|
||||
export const createDefaultProvider = (providerUrl: string, chainId: number) => {
|
||||
return new ethers.providers.JsonRpcProvider(providerUrl, chainId);
|
||||
@ -17,18 +17,11 @@ export const createConnectors = (providerUrl: string, chainId: number) => {
|
||||
if (isNaN(chainId)) {
|
||||
throw new Error('Invalid Ethereum chain ID for environment');
|
||||
}
|
||||
const [walletconnect, walletconnectHooks] =
|
||||
initializeConnector<WalletConnect>(
|
||||
(actions) =>
|
||||
new WalletConnect(actions, {
|
||||
rpc: {
|
||||
[chainId]: providerUrl,
|
||||
},
|
||||
}),
|
||||
[chainId]
|
||||
);
|
||||
|
||||
return [
|
||||
[metamask, metamaskHooks],
|
||||
[walletconnect, walletconnectHooks],
|
||||
] as [Connector, Web3ReactHooks][];
|
||||
initializeMetaMaskConnector(),
|
||||
initializeCoinbaseConnector(providerUrl),
|
||||
initializeWalletConnector(WALLETCONNECT_PROJECT_ID, chainId, providerUrl),
|
||||
initializeWalletConnectLegacyConnector(chainId, providerUrl),
|
||||
].filter(Boolean) as unknown as [Connector, Web3ReactHooks][];
|
||||
};
|
||||
|
@ -12,6 +12,7 @@ NX_VEGA_URL=http://localhost:3028/query
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_ETH_LOCAL_PROVIDER_URL=http://localhost:8545/
|
||||
NX_ETH_WALLET_MNEMONIC="ozone access unlock valid olympic save include omit supply green clown session"
|
||||
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
||||
|
||||
# Expose some env vars to cypress environment for market setup
|
||||
CYPRESS_ETH_WALLET_MNEMONIC=ozone access unlock valid olympic save include omit supply green clown session
|
||||
|
@ -27,7 +27,7 @@ describe('ethereum wallet', { tags: '@smoke', testIsolation: true }, () => {
|
||||
cy.getByTestId('tab-deposits').should('not.be.empty');
|
||||
});
|
||||
|
||||
it('should see an option to cancel the attempted connection', () => {
|
||||
it('should see QR code modal for WalletConnect', () => {
|
||||
// 0004-EWAL-003
|
||||
|
||||
cy.wait('@NetworkParams');
|
||||
@ -36,8 +36,8 @@ describe('ethereum wallet', { tags: '@smoke', testIsolation: true }, () => {
|
||||
cy.getByTestId('connect-eth-wallet-btn').click();
|
||||
cy.getByTestId('web3-connector-list').should('exist');
|
||||
cy.getByTestId('web3-connector-WalletConnect').click();
|
||||
cy.get('#walletconnect-qrcode-text').should('exist');
|
||||
cy.get('#walletconnect-qrcode-close').click();
|
||||
// testing if exists rather than visible because of the long loading time
|
||||
cy.get('w3m-modal').should('exist');
|
||||
});
|
||||
|
||||
it('able to disconnect eth wallet', () => {
|
||||
|
@ -11,4 +11,5 @@ NX_VEGA_TOKEN_URL=https://token.fairground.wtf
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/main/announcements.json
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/main/announcements.json
|
||||
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
@ -14,10 +14,9 @@ export const Web3Provider = ({ children }: { children: ReactNode }) => {
|
||||
const { config, loading, error } = useEthereumConfig();
|
||||
const { ETHEREUM_PROVIDER_URL, ETH_LOCAL_PROVIDER_URL, ETH_WALLET_MNEMONIC } =
|
||||
useEnvironment();
|
||||
const [connectors, initializeConnectors] = useWeb3ConnectStore((store) => [
|
||||
store.connectors,
|
||||
store.initialize,
|
||||
]);
|
||||
|
||||
const connectors = useWeb3ConnectStore((store) => store.connectors);
|
||||
const initializeConnectors = useWeb3ConnectStore((store) => store.initialize);
|
||||
|
||||
useEffect(() => {
|
||||
if (config?.chain_id) {
|
||||
|
@ -33,6 +33,7 @@ import { ViewingBanner } from '../components/viewing-banner';
|
||||
import { Banner } from '../components/banner';
|
||||
import { AppLoader, DynamicLoader } from '../components/app-loader';
|
||||
import { Navbar } from '../components/navbar';
|
||||
import { ENV } from '../lib/config';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import { activeOrdersProvider } from '@vegaprotocol/orders';
|
||||
|
||||
@ -144,7 +145,7 @@ const PartyData = () => {
|
||||
|
||||
const MaybeConnectEagerly = () => {
|
||||
useVegaEagerConnect(Connectors);
|
||||
useEthereumEagerConnect();
|
||||
useEthereumEagerConnect(ENV.dsn);
|
||||
|
||||
const { pubKey, connect } = useVegaWallet();
|
||||
const [searchParams] = useSearchParams();
|
||||
|
@ -19,6 +19,12 @@ const mockSocketServer = Cypress.env('VEGA_URL')
|
||||
? new Server(Cypress.env('VEGA_URL').replace('http', 'ws'))
|
||||
: null;
|
||||
|
||||
// DO NOT REMOVE: PASSTHROUGH for walletconnect
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const relayServer = new Server('wss://relay.walletconnect.com', {
|
||||
mock: false,
|
||||
});
|
||||
|
||||
export function addMockSubscription() {
|
||||
Cypress.Commands.add(
|
||||
'mockSubscription',
|
||||
|
@ -1,6 +1,7 @@
|
||||
import type { StateCreator } from 'zustand';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
const { create: actualCreate } = jest.requireActual('zustand'); // if using jest
|
||||
const { create: actualCreate, useStore: actualUseStore } =
|
||||
jest.requireActual('zustand'); // if using jest
|
||||
|
||||
// a variable to hold reset functions for all stores declared in the app
|
||||
const storeResetFns = new Set<() => void>();
|
||||
@ -15,7 +16,13 @@ export const create =
|
||||
return store;
|
||||
};
|
||||
|
||||
export const createStore = create;
|
||||
export const useStore = actualUseStore;
|
||||
|
||||
// Reset all stores after each test run
|
||||
beforeEach(() => {
|
||||
act(() => storeResetFns.forEach((resetFn) => resetFn()));
|
||||
});
|
||||
|
||||
// also export default as web3-react internals import and use zustand as the default import
|
||||
export default create;
|
||||
|
@ -35,6 +35,7 @@ import {
|
||||
ETHEREUM_EAGER_CONNECT,
|
||||
useWeb3ConnectStore,
|
||||
getChainName,
|
||||
useWeb3Disconnect,
|
||||
} from '@vegaprotocol/web3';
|
||||
import type { DepositBalances } from './use-deposit-balances';
|
||||
import { FaucetNotification } from './faucet-notification';
|
||||
@ -448,11 +449,12 @@ const DisconnectEthereumButton = ({
|
||||
}) => {
|
||||
const { connector } = useWeb3React();
|
||||
const [, , removeEagerConnector] = useLocalStorage(ETHEREUM_EAGER_CONNECT);
|
||||
const disconnect = useWeb3Disconnect(connector);
|
||||
|
||||
return (
|
||||
<ButtonLink
|
||||
onClick={() => {
|
||||
connector.deactivate();
|
||||
disconnect();
|
||||
removeEagerConnector();
|
||||
onDisconnect();
|
||||
}}
|
||||
|
@ -12,6 +12,7 @@ interface DialogProps {
|
||||
open: boolean;
|
||||
onChange?: (isOpen: boolean) => void;
|
||||
onCloseAutoFocus?: (e: Event) => void;
|
||||
onInteractOutside?: (e: Event) => void;
|
||||
title?: string;
|
||||
icon?: ReactNode;
|
||||
intent?: Intent;
|
||||
@ -24,6 +25,7 @@ export function Dialog({
|
||||
open,
|
||||
onChange,
|
||||
onCloseAutoFocus,
|
||||
onInteractOutside,
|
||||
title,
|
||||
icon,
|
||||
intent,
|
||||
@ -66,6 +68,7 @@ export function Dialog({
|
||||
<DialogPrimitives.Content
|
||||
className={contentClasses}
|
||||
onCloseAutoFocus={onCloseAutoFocus}
|
||||
onInteractOutside={onInteractOutside}
|
||||
data-testid={dataTestId}
|
||||
>
|
||||
<div className={wrapperClasses}>
|
||||
|
@ -1,6 +1,7 @@
|
||||
import type { StateCreator } from 'zustand';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
const { create: actualCreate } = jest.requireActual('zustand'); // if using jest
|
||||
const { create: actualCreate, useStore: actualUseStore } =
|
||||
jest.requireActual('zustand'); // if using jest
|
||||
|
||||
// a variable to hold reset functions for all stores declared in the app
|
||||
const storeResetFns = new Set<() => void>();
|
||||
@ -15,6 +16,9 @@ export const create =
|
||||
return store;
|
||||
};
|
||||
|
||||
export const createStore = create;
|
||||
export const useStore = actualUseStore;
|
||||
|
||||
// Reset all stores after each test run
|
||||
beforeEach(() => {
|
||||
act(() => storeResetFns.forEach((resetFn) => resetFn()));
|
||||
|
@ -1,23 +1,24 @@
|
||||
export * from './lib/constants';
|
||||
export * from './lib/eip-1193-custom-bridge';
|
||||
export * from './lib/ethereum-error';
|
||||
export * from './lib/ethereum-transaction-dialog';
|
||||
export * from './lib/url-connector';
|
||||
export * from './lib/use-bridge-contract';
|
||||
export * from './lib/use-eager-connect';
|
||||
export * from './lib/use-token-contract';
|
||||
export * from './lib/use-token-decimals';
|
||||
export * from './lib/use-ethereum-config';
|
||||
export * from './lib/use-ethereum-read-contract';
|
||||
export * from './lib/use-ethereum-transaction';
|
||||
export * from './lib/use-ethereum-transaction-updater';
|
||||
export * from './lib/use-ethereum-transaction-store';
|
||||
export * from './lib/use-ethereum-transaction-manager';
|
||||
export * from './lib/use-ethereum-transaction-store';
|
||||
export * from './lib/use-ethereum-transaction-updater';
|
||||
export * from './lib/use-ethereum-transaction';
|
||||
export * from './lib/use-ethereum-withdraw-approvals-manager';
|
||||
export * from './lib/use-ethereum-withdraw-approvals-store';
|
||||
export * from './lib/use-get-withdraw-delay';
|
||||
export * from './lib/use-get-withdraw-threshold';
|
||||
export * from './lib/ethereum-transaction-dialog';
|
||||
export * from './lib/web3-provider';
|
||||
export * from './lib/web3-connectors';
|
||||
export * from './lib/use-token-contract';
|
||||
export * from './lib/use-token-decimals';
|
||||
export * from './lib/use-web3-disconnect';
|
||||
export * from './lib/web3-connect-dialog';
|
||||
export * from './lib/web3-connect-store';
|
||||
export * from './lib/url-connector';
|
||||
export * from './lib/eip-1193-custom-bridge';
|
||||
export * from './lib/web3-connectors';
|
||||
export * from './lib/web3-provider';
|
||||
|
@ -9,3 +9,10 @@ export const getChainName = (chainId: number | null | undefined) => {
|
||||
const name = chainId ? ChainIdMap[chainId] : undefined;
|
||||
return name || 'Unknown';
|
||||
};
|
||||
|
||||
/**
|
||||
* WalletConnect project id
|
||||
* https://cloud.walletconnect.com/sign-in
|
||||
*/
|
||||
export const WALLETCONNECT_PROJECT_ID =
|
||||
process.env['NX_WALLETCONNECT_PROJECT_ID'] || '';
|
||||
|
@ -69,7 +69,7 @@ export class UrlConnector extends Connector {
|
||||
const chainId = await this.provider!.request({ method: 'eth_chainId' });
|
||||
this.actions.update({ chainId: Number(chainId) });
|
||||
} catch (error) {
|
||||
this.actions.reportError(error as Error);
|
||||
this.onError?.(error as Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,30 +1,40 @@
|
||||
import { useLocalStorage } from '@vegaprotocol/react-helpers';
|
||||
import { useLocalStorage, useLogger } from '@vegaprotocol/react-helpers';
|
||||
import type { Web3ReactHooks } from '@web3-react/core';
|
||||
import { MetaMask } from '@web3-react/metamask';
|
||||
import type { Connector } from '@web3-react/types';
|
||||
import { WalletConnect } from '@web3-react/walletconnect';
|
||||
import { WalletConnect } from '@web3-react/walletconnect-v2';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { useWeb3ConnectStore } from './web3-connect-store';
|
||||
|
||||
export const ETHEREUM_EAGER_CONNECT = 'ethereum-eager-connect';
|
||||
|
||||
export const useEagerConnect = () => {
|
||||
export const useEagerConnect = (sentryDsn?: string) => {
|
||||
const connectors = useWeb3ConnectStore((store) => store.connectors);
|
||||
const [eagerConnector] = useLocalStorage(ETHEREUM_EAGER_CONNECT);
|
||||
const attemptedRef = useRef(false);
|
||||
|
||||
const logger = useLogger({ dsn: sentryDsn });
|
||||
|
||||
useEffect(() => {
|
||||
if (attemptedRef.current || 'Cypress' in window) return;
|
||||
|
||||
const stored = getConnector(connectors, eagerConnector);
|
||||
|
||||
// found a valid connection option
|
||||
if (stored && stored[0].connectEagerly) {
|
||||
stored[0].connectEagerly();
|
||||
}
|
||||
const tryConnectEagerly = async () => {
|
||||
// found a valid connection option
|
||||
if (stored && stored[0].connectEagerly) {
|
||||
try {
|
||||
await stored[0].connectEagerly();
|
||||
} catch (err) {
|
||||
// NOOP - no active session
|
||||
logger.error('ERR_WEB3_EAGER_CONNECT', (err as Error).message);
|
||||
}
|
||||
}
|
||||
};
|
||||
tryConnectEagerly();
|
||||
|
||||
attemptedRef.current = true;
|
||||
}, [eagerConnector, connectors]);
|
||||
}, [eagerConnector, connectors, logger]);
|
||||
};
|
||||
|
||||
const getConnector = (
|
||||
|
13
libs/web3/src/lib/use-web3-disconnect.ts
Normal file
13
libs/web3/src/lib/use-web3-disconnect.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { useWeb3ConnectStore } from './web3-connect-store';
|
||||
import type { Connector } from '@web3-react/types';
|
||||
|
||||
export const useWeb3Disconnect = (connector: Connector) => {
|
||||
const clearError = useWeb3ConnectStore((store) => store.clearError);
|
||||
return () => {
|
||||
if (connector.deactivate) {
|
||||
connector.deactivate();
|
||||
}
|
||||
connector.resetState();
|
||||
clearError();
|
||||
};
|
||||
};
|
@ -6,7 +6,7 @@ import { MetaMask } from '@web3-react/metamask';
|
||||
import type { Connector } from '@web3-react/types';
|
||||
|
||||
const [foo, fooHooks] = initializeConnector((actions) => {
|
||||
return new MetaMask(actions);
|
||||
return new MetaMask({ actions });
|
||||
});
|
||||
|
||||
const connectors: [Connector, Web3ReactHooks][] = [[foo, fooHooks]];
|
||||
|
@ -2,11 +2,15 @@ import { t } from '@vegaprotocol/i18n';
|
||||
import { useLocalStorage } from '@vegaprotocol/react-helpers';
|
||||
import { Dialog, Intent } from '@vegaprotocol/ui-toolkit';
|
||||
import { MetaMask } from '@web3-react/metamask';
|
||||
import { WalletConnect } from '@web3-react/walletconnect';
|
||||
import { WalletConnect } from '@web3-react/walletconnect-v2';
|
||||
import { WalletConnect as WalletConnectLegacy } from '@web3-react/walletconnect';
|
||||
import { CoinbaseWallet } from '@web3-react/coinbase-wallet';
|
||||
import type { Connector } from '@web3-react/types';
|
||||
import { ETHEREUM_EAGER_CONNECT } from './use-eager-connect';
|
||||
import type { Web3ReactHooks } from '@web3-react/core';
|
||||
import { useWeb3ConnectStore } from './web3-connect-store';
|
||||
import { theme } from '@vegaprotocol/tailwindcss-config';
|
||||
import classNames from 'classnames';
|
||||
|
||||
interface Web3ConnectDialogProps {
|
||||
dialogOpen: boolean;
|
||||
@ -20,37 +24,79 @@ export const Web3ConnectDialog = ({
|
||||
setDialogOpen,
|
||||
connectors,
|
||||
desiredChainId,
|
||||
}: Web3ConnectDialogProps) => {
|
||||
const [, setEagerConnector] = useLocalStorage(ETHEREUM_EAGER_CONNECT);
|
||||
}: Web3ConnectDialogProps) => (
|
||||
<Dialog
|
||||
open={dialogOpen}
|
||||
onChange={setDialogOpen}
|
||||
onInteractOutside={(e) => {
|
||||
// do not close dialog when clicked outside (wallet connect modal)
|
||||
e.preventDefault();
|
||||
}}
|
||||
intent={Intent.None}
|
||||
title={t('Connect to your Ethereum wallet')}
|
||||
size="small"
|
||||
>
|
||||
<ul className="grid grid-cols-2 gap-2" data-testid="web3-connector-list">
|
||||
{connectors.map((connector, i) => (
|
||||
<li key={i} className="mb-2 last:mb-0">
|
||||
<ConnectButton
|
||||
connector={connector}
|
||||
desiredChainId={desiredChainId}
|
||||
onClick={() => {
|
||||
setDialogOpen(false);
|
||||
}}
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</Dialog>
|
||||
);
|
||||
|
||||
const ConnectButton = ({
|
||||
connector,
|
||||
desiredChainId,
|
||||
onClick,
|
||||
}: {
|
||||
connector: [Connector, Web3ReactHooks];
|
||||
desiredChainId?: number;
|
||||
onClick?: () => void;
|
||||
}) => {
|
||||
const [connectorInstance, { useIsActivating }] = connector;
|
||||
const isActivating = useIsActivating();
|
||||
const info = getConnectorInfo(connectorInstance);
|
||||
const [, setEagerConnector] = useLocalStorage(ETHEREUM_EAGER_CONNECT);
|
||||
return (
|
||||
<Dialog
|
||||
open={dialogOpen}
|
||||
onChange={setDialogOpen}
|
||||
intent={Intent.None}
|
||||
title={t('Connect to your Ethereum wallet')}
|
||||
<button
|
||||
className={classNames(
|
||||
'flex items-center gap-2 p-2 rounded ',
|
||||
'hover:bg-vega-light-100 hover:dark:bg-vega-dark-100',
|
||||
{
|
||||
'!bg-vega-yellow text-black hover:active:!bg-vega-yellow':
|
||||
isActivating,
|
||||
}
|
||||
)}
|
||||
data-testid={`web3-connector-${info.name}`}
|
||||
title={info.alt}
|
||||
onClick={async () => {
|
||||
// remove orphaned wallet connect modals
|
||||
const modals = document.querySelectorAll('w3m-modal');
|
||||
if (modals.length > 0) {
|
||||
modals.forEach((m) => m.remove());
|
||||
}
|
||||
|
||||
try {
|
||||
await connectorInstance.activate(desiredChainId);
|
||||
setEagerConnector(info.name);
|
||||
onClick?.();
|
||||
} catch (err) {
|
||||
console.log('could not connect to the wallet', info.name, err);
|
||||
// NOOP - cancelled wallet connector
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ul data-testid="web3-connector-list">
|
||||
{connectors.map(([connector], i) => {
|
||||
const info = getConnectorInfo(connector);
|
||||
return (
|
||||
<li key={i} className="mb-2 last:mb-0">
|
||||
<button
|
||||
className="hover:text-vega-pink dark:hover:text-vega-yellow underline"
|
||||
data-testid={`web3-connector-${info.name}`}
|
||||
onClick={async () => {
|
||||
await connector.activate(desiredChainId);
|
||||
setEagerConnector(info.name);
|
||||
setDialogOpen(false);
|
||||
}}
|
||||
>
|
||||
{info.text}
|
||||
</button>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</Dialog>
|
||||
{info.icon}
|
||||
<span>{info.text}</span>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
@ -72,15 +118,193 @@ export const Web3ConnectUncontrolledDialog = () => {
|
||||
function getConnectorInfo(connector: Connector) {
|
||||
if (connector instanceof MetaMask) {
|
||||
return {
|
||||
icon: <MetaMaskIcon width={40} />,
|
||||
name: 'MetaMask',
|
||||
text: t('MetaMask, Brave or other injected web wallet'),
|
||||
text: t('MetaMask'),
|
||||
alt: t('MetaMask, Brave or other injected web wallet'),
|
||||
};
|
||||
}
|
||||
if (connector instanceof CoinbaseWallet) {
|
||||
return {
|
||||
icon: <CoinbaseWalletIcon width={40} />,
|
||||
name: 'CoinbaseWallet',
|
||||
text: t('Coinbase'),
|
||||
};
|
||||
}
|
||||
if (connector instanceof WalletConnect) {
|
||||
return {
|
||||
icon: <WalletConnectIcon width={40} />,
|
||||
name: 'WalletConnect',
|
||||
text: t('WalletConnect'),
|
||||
alt: t('WalletConnect v2'),
|
||||
};
|
||||
}
|
||||
if (connector instanceof WalletConnectLegacy) {
|
||||
return {
|
||||
icon: (
|
||||
<WalletConnectIcon
|
||||
width={40}
|
||||
fillColor={theme.colors.vega.light[200]}
|
||||
/>
|
||||
),
|
||||
name: 'WalletConnectLegacy',
|
||||
text: t('WalletConnect Legacy'),
|
||||
alt: t('WalletConnect v1'),
|
||||
};
|
||||
}
|
||||
return { name: 'Unknown', text: t('Unknown') };
|
||||
}
|
||||
|
||||
type IconProps = {
|
||||
width?: number;
|
||||
height?: number;
|
||||
};
|
||||
|
||||
const MetaMaskIcon = ({ width, height }: IconProps) => (
|
||||
<svg
|
||||
viewBox="0 0 47 47"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={width}
|
||||
height={height}
|
||||
>
|
||||
<g>
|
||||
<path
|
||||
d="m40.632 6.969-14.136 10.62 2.628-6.259L40.632 6.97Z"
|
||||
fill="#E17726"
|
||||
stroke="#E17726"
|
||||
strokeWidth="0.223"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
></path>
|
||||
<path
|
||||
d="m8.024 6.969 14.01 10.72-2.502-6.359L8.024 6.97ZM35.542 31.594l-3.761 5.834 8.054 2.251 2.307-7.958-6.6-.127ZM6.528 31.721 8.82 39.68l8.04-2.251-3.747-5.834-6.586.127Z"
|
||||
fill="#E27625"
|
||||
stroke="#E27625"
|
||||
strokeWidth="0.223"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
></path>
|
||||
<path
|
||||
d="m16.428 21.738-2.237 3.427 7.97.368-.266-8.709-5.467 4.914ZM32.229 21.738l-5.552-5.012-.181 8.807 7.97-.368-2.237-3.427ZM16.861 37.428l4.824-2.365-4.152-3.285-.672 5.65ZM26.971 35.063l4.81 2.365-.657-5.65-4.153 3.285Z"
|
||||
fill="#E27625"
|
||||
stroke="#E27625"
|
||||
strokeWidth="0.223"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
></path>
|
||||
<path
|
||||
d="m31.78 37.428-4.81-2.365.392 3.172-.042 1.345 4.46-2.152ZM16.861 37.428l4.475 2.152-.028-1.345.377-3.172-4.824 2.365Z"
|
||||
fill="#D5BFB2"
|
||||
stroke="#D5BFB2"
|
||||
strokeWidth="0.223"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
></path>
|
||||
<path
|
||||
d="m21.42 29.682-4-1.19 2.825-1.316 1.174 2.506ZM27.236 29.682l1.175-2.506 2.838 1.317-4.013 1.19Z"
|
||||
fill="#233447"
|
||||
stroke="#233447"
|
||||
strokeWidth="0.223"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
></path>
|
||||
<path
|
||||
d="m16.861 37.427.7-5.834-4.447.128 3.747 5.706ZM31.096 31.593l.685 5.834 3.761-5.706-4.446-.128ZM34.465 25.165l-7.97.368.741 4.15 1.175-2.507 2.838 1.317 3.216-3.328ZM17.42 28.493l2.825-1.317 1.175 2.506.74-4.149-7.97-.368 3.23 3.328Z"
|
||||
fill="#CC6228"
|
||||
stroke="#CC6228"
|
||||
strokeWidth="0.223"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
></path>
|
||||
<path
|
||||
d="m14.19 25.165 3.343 6.613-.112-3.285-3.23-3.328ZM31.25 28.493l-.126 3.285 3.342-6.613-3.216 3.328ZM22.161 25.533l-.741 4.149.937 4.9.21-6.458-.406-2.591ZM26.495 25.533l-.391 2.577.196 6.471.937-4.9-.741-4.148Z"
|
||||
fill="#E27525"
|
||||
stroke="#E27525"
|
||||
strokeWidth="0.223"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
></path>
|
||||
<path
|
||||
d="m27.237 29.682-.937 4.9.671.481 4.153-3.285.126-3.285-4.013 1.19ZM17.42 28.493l.112 3.285 4.153 3.285.671-.481-.937-4.9-3.999-1.19Z"
|
||||
fill="#F5841F"
|
||||
stroke="#F5841F"
|
||||
strokeWidth="0.223"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
></path>
|
||||
<path
|
||||
d="m27.32 39.58.042-1.345-.363-.312h-5.342l-.35.312.029 1.345-4.475-2.152 1.566 1.303 3.175 2.223h5.439l3.188-2.224 1.552-1.302-4.46 2.152Z"
|
||||
fill="#C0AC9D"
|
||||
stroke="#C0AC9D"
|
||||
strokeWidth="0.223"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
></path>
|
||||
<path
|
||||
d="m26.97 35.063-.67-.482h-3.944l-.67.482-.378 3.172.35-.312h5.34l.364.312-.391-3.172Z"
|
||||
fill="#161616"
|
||||
stroke="#161616"
|
||||
strokeWidth="0.223"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
></path>
|
||||
<path
|
||||
d="m41.234 18.283 1.188-5.863-1.79-5.451-13.66 10.266 5.257 4.503 7.425 2.195 1.636-1.94-.713-.524 1.132-1.048-.867-.68 1.133-.878-.741-.58ZM6.234 12.42l1.203 5.863-.77.58 1.147.878-.867.68L8.08 21.47l-.713.524 1.636 1.94 7.425-2.195 5.257-4.503L8.025 6.97l-1.79 5.452Z"
|
||||
fill="#763E1A"
|
||||
stroke="#763E1A"
|
||||
strokeWidth="0.223"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
></path>
|
||||
<path
|
||||
d="m39.654 23.933-7.425-2.195 2.237 3.427-3.342 6.613 4.419-.057h6.6l-2.49-7.788ZM16.428 21.738l-7.425 2.195-2.475 7.788h6.586l4.418.056-3.342-6.612 2.238-3.427ZM26.495 25.533l.476-8.298 2.153-5.905h-9.592l2.153 5.905.476 8.298.181 2.605.014 6.443H26.3l.014-6.443.182-2.605Z"
|
||||
fill="#F5841F"
|
||||
stroke="#F5841F"
|
||||
strokeWidth="0.223"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
const CoinbaseWalletIcon = ({ width, height }: IconProps) => (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
viewBox="0 0 1024 1024"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<rect width="1024" height="1024" fill="#0052FF" />
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M152 512C152 710.823 313.177 872 512 872C710.823 872 872 710.823 872 512C872 313.177 710.823 152 512 152C313.177 152 152 313.177 152 512ZM420 396C406.745 396 396 406.745 396 420V604C396 617.255 406.745 628 420 628H604C617.255 628 628 617.255 628 604V420C628 406.745 617.255 396 604 396H420Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
const WalletConnectIcon = ({
|
||||
width,
|
||||
height,
|
||||
fillColor = '#3396ff',
|
||||
}: IconProps & { fillColor?: string }) => (
|
||||
<svg
|
||||
fill="none"
|
||||
width={width}
|
||||
height={height}
|
||||
viewBox="0 0 400 400"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g>
|
||||
<circle cx="200" cy="200" fill={fillColor} r="199.5" stroke="none" />
|
||||
<path
|
||||
d="m122.519 148.965c42.791-41.729 112.171-41.729 154.962 0l5.15 5.022c2.14 2.086 2.14 5.469 0 7.555l-17.617 17.18c-1.07 1.043-2.804 1.043-3.874 0l-7.087-6.911c-29.853-29.111-78.253-29.111-108.106 0l-7.59 7.401c-1.07 1.043-2.804 1.043-3.874 0l-17.617-17.18c-2.14-2.086-2.14-5.469 0-7.555zm191.397 35.529 15.679 15.29c2.14 2.086 2.14 5.469 0 7.555l-70.7 68.944c-2.139 2.087-5.608 2.087-7.748 0l-50.178-48.931c-.535-.522-1.402-.522-1.937 0l-50.178 48.931c-2.139 2.087-5.608 2.087-7.748 0l-70.7015-68.945c-2.1396-2.086-2.1396-5.469 0-7.555l15.6795-15.29c2.1396-2.086 5.6085-2.086 7.7481 0l50.1789 48.932c.535.522 1.402.522 1.937 0l50.177-48.932c2.139-2.087 5.608-2.087 7.748 0l50.179 48.932c.535.522 1.402.522 1.937 0l50.179-48.931c2.139-2.087 5.608-2.087 7.748 0z"
|
||||
fill="#fff"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
@ -6,11 +6,13 @@ interface State {
|
||||
isOpen: boolean;
|
||||
connectors: [Connector, Web3ReactHooks][];
|
||||
desiredChainId?: number;
|
||||
error?: Error;
|
||||
}
|
||||
interface Actions {
|
||||
initialize: (connectors: State['connectors'], desiredChainId: number) => void;
|
||||
open: () => void;
|
||||
close: () => void;
|
||||
clearError: () => void;
|
||||
}
|
||||
|
||||
export const useWeb3ConnectStore = create<State & Actions>()((set) => ({
|
||||
@ -21,4 +23,5 @@ export const useWeb3ConnectStore = create<State & Actions>()((set) => ({
|
||||
},
|
||||
open: () => set(() => ({ isOpen: true })),
|
||||
close: () => set(() => ({ isOpen: false })),
|
||||
clearError: () => set(() => ({ error: undefined })),
|
||||
}));
|
||||
|
@ -2,8 +2,102 @@ import type { Web3ReactHooks } from '@web3-react/core';
|
||||
import { initializeConnector } from '@web3-react/core';
|
||||
import type { Connector } from '@web3-react/types';
|
||||
import { MetaMask } from '@web3-react/metamask';
|
||||
import { WalletConnect } from '@web3-react/walletconnect';
|
||||
import { WalletConnect } from '@web3-react/walletconnect-v2';
|
||||
import { WalletConnect as WalletConnectLegacy } from '@web3-react/walletconnect';
|
||||
import { CoinbaseWallet } from '@web3-react/coinbase-wallet';
|
||||
import { initializeUrlConnector } from './url-connector';
|
||||
import { WALLETCONNECT_PROJECT_ID } from './constants';
|
||||
import { useWeb3ConnectStore } from './web3-connect-store';
|
||||
import { theme } from '@vegaprotocol/tailwindcss-config';
|
||||
|
||||
export const initializeCoinbaseConnector = (providerUrl: string) =>
|
||||
initializeConnector<CoinbaseWallet>(
|
||||
(actions) =>
|
||||
new CoinbaseWallet({
|
||||
actions,
|
||||
options: {
|
||||
appName: 'Vega',
|
||||
darkMode: true,
|
||||
url: providerUrl,
|
||||
},
|
||||
onError: (error) => {
|
||||
console.log('ERR_COINBASE_WALLET', error);
|
||||
useWeb3ConnectStore.setState({ error });
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
export const initializeWalletConnectLegacyConnector = (
|
||||
chainId: number,
|
||||
providerUrl: string
|
||||
) =>
|
||||
initializeConnector<WalletConnectLegacy>(
|
||||
(actions) =>
|
||||
new WalletConnectLegacy({
|
||||
actions,
|
||||
options: {
|
||||
rpc: {
|
||||
[chainId]: providerUrl,
|
||||
},
|
||||
qrcode: true,
|
||||
},
|
||||
defaultChainId: chainId,
|
||||
})
|
||||
);
|
||||
|
||||
export const initializeWalletConnector = (
|
||||
projectId: string,
|
||||
chainId: number,
|
||||
providerUrl: string
|
||||
) =>
|
||||
projectId && projectId.length > 0
|
||||
? initializeConnector<WalletConnect>(
|
||||
(actions) =>
|
||||
new WalletConnect({
|
||||
actions,
|
||||
defaultChainId: chainId,
|
||||
options: {
|
||||
projectId: projectId,
|
||||
chains: [chainId],
|
||||
showQrModal: true,
|
||||
rpcMap: {
|
||||
[chainId]: providerUrl,
|
||||
},
|
||||
qrModalOptions: {
|
||||
themeMode: 'dark',
|
||||
themeVariables: {
|
||||
'--w3m-z-index': '40',
|
||||
'--w3m-accent-color': theme.colors.vega.yellow.DEFAULT,
|
||||
'--w3m-background-color': theme.colors.vega.dark[100],
|
||||
'--w3m-font-family': 'AlphaLyrae',
|
||||
'--w3m-container-border-radius': '0.25rem',
|
||||
'--w3m-background-border-radius': '0.25rem',
|
||||
'--w3m-accent-fill-color': theme.colors.vega.yellow.DEFAULT,
|
||||
},
|
||||
},
|
||||
},
|
||||
onError: (error) => {
|
||||
console.log('ERR_WALLET_CONNECT', error.message);
|
||||
useWeb3ConnectStore.setState({ error });
|
||||
},
|
||||
})
|
||||
)
|
||||
: null;
|
||||
|
||||
export const initializeMetaMaskConnector = () =>
|
||||
initializeConnector<MetaMask>(
|
||||
(actions) =>
|
||||
new MetaMask({
|
||||
actions,
|
||||
options: {
|
||||
mustBeMetaMask: false,
|
||||
},
|
||||
onError: (error) => {
|
||||
console.log('ERR_META_MASK', error.message);
|
||||
useWeb3ConnectStore.setState({ error });
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
export const createConnectors = (
|
||||
providerUrl: string,
|
||||
@ -15,23 +109,11 @@ export const createConnectors = (
|
||||
throw new Error('Invalid Ethereum chain ID for environment');
|
||||
}
|
||||
|
||||
const [metamask, metamaskHooks] = initializeConnector<MetaMask>(
|
||||
(actions) => new MetaMask(actions)
|
||||
);
|
||||
|
||||
const [walletconnect, walletconnectHooks] =
|
||||
initializeConnector<WalletConnect>(
|
||||
(actions) =>
|
||||
new WalletConnect(actions, {
|
||||
rpc: {
|
||||
[chainId]: providerUrl,
|
||||
},
|
||||
}),
|
||||
[chainId]
|
||||
);
|
||||
return [
|
||||
initializeUrlConnector(localProviderUrl, walletMnemonic),
|
||||
[metamask, metamaskHooks],
|
||||
[walletconnect, walletconnectHooks],
|
||||
].filter(Boolean) as [Connector, Web3ReactHooks][];
|
||||
initializeMetaMaskConnector(),
|
||||
initializeCoinbaseConnector(providerUrl),
|
||||
initializeWalletConnector(WALLETCONNECT_PROJECT_ID, chainId, providerUrl),
|
||||
initializeWalletConnectLegacyConnector(chainId, providerUrl),
|
||||
].filter(Boolean) as unknown as [Connector, Web3ReactHooks][];
|
||||
};
|
||||
|
@ -4,7 +4,9 @@ import { initializeConnector } from '@web3-react/core';
|
||||
import { MetaMask } from '@web3-react/metamask';
|
||||
import { Web3Provider } from './web3-provider';
|
||||
|
||||
const [foo, fooHooks] = initializeConnector((actions) => new MetaMask(actions));
|
||||
const [foo, fooHooks] = initializeConnector(
|
||||
(actions) => new MetaMask({ actions })
|
||||
);
|
||||
|
||||
const connectors: [MetaMask, Web3ReactHooks][] = [[foo, fooHooks]];
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import type { Web3ReactHooks } from '@web3-react/core';
|
||||
import { Web3ReactProvider } from '@web3-react/core';
|
||||
import type { Connector } from '@web3-react/types';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
interface Web3ProviderProps {
|
||||
children: JSX.Element | JSX.Element[];
|
||||
@ -8,7 +9,19 @@ interface Web3ProviderProps {
|
||||
}
|
||||
|
||||
export const Web3Provider = ({ children, connectors }: Web3ProviderProps) => {
|
||||
/**
|
||||
* The connectors prop passed to Web3ReactProvider must be referentially static.
|
||||
* https://github.com/Uniswap/web3-react/blob/31742897f9fddb38e00e36c2516029d3df9a9c54/packages/core/src/provider.tsx#L66
|
||||
*/
|
||||
const key = useMemo(
|
||||
() => `WEB3_PROVIDER_${Date.now().toString()}`,
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[connectors]
|
||||
);
|
||||
|
||||
return (
|
||||
<Web3ReactProvider connectors={connectors}>{children}</Web3ReactProvider>
|
||||
<Web3ReactProvider key={key} connectors={connectors}>
|
||||
{children}
|
||||
</Web3ReactProvider>
|
||||
);
|
||||
};
|
||||
|
@ -31,6 +31,7 @@ import { WithdrawLimits } from './withdraw-limits';
|
||||
import {
|
||||
ETHEREUM_EAGER_CONNECT,
|
||||
useWeb3ConnectStore,
|
||||
useWeb3Disconnect,
|
||||
} from '@vegaprotocol/web3';
|
||||
|
||||
interface FormFields {
|
||||
@ -298,6 +299,7 @@ const EthereumButton = ({ clearAddress }: { clearAddress: () => void }) => {
|
||||
const openDialog = useWeb3ConnectStore((state) => state.open);
|
||||
const { isActive, connector } = useWeb3React();
|
||||
const [, , removeEagerConnector] = useLocalStorage(ETHEREUM_EAGER_CONNECT);
|
||||
const disconnect = useWeb3Disconnect(connector);
|
||||
|
||||
if (!isActive) {
|
||||
return (
|
||||
@ -310,7 +312,7 @@ const EthereumButton = ({ clearAddress }: { clearAddress: () => void }) => {
|
||||
return (
|
||||
<UseButton
|
||||
onClick={() => {
|
||||
connector.deactivate();
|
||||
disconnect();
|
||||
clearAddress();
|
||||
removeEagerConnector();
|
||||
}}
|
||||
|
11
package.json
11
package.json
@ -21,6 +21,7 @@
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.5.8",
|
||||
"@blueprintjs/icons": "^3.32.0",
|
||||
"@coinbase/wallet-sdk": "^3.6.5",
|
||||
"@radix-ui/react-accordion": "^1.1.0",
|
||||
"@radix-ui/react-checkbox": "^1.0.1",
|
||||
"@radix-ui/react-dialog": "^1.0.2",
|
||||
@ -37,10 +38,12 @@
|
||||
"@sentry/react": "^6.19.2",
|
||||
"@sentry/tracing": "^6.19.2",
|
||||
"@vegaprotocol/wallet-client": "0.1.9",
|
||||
"@walletconnect/ethereum-provider": "^1.7.5",
|
||||
"@web3-react/core": "8.0.20-beta.0",
|
||||
"@web3-react/metamask": "8.0.16-beta.0",
|
||||
"@web3-react/walletconnect": "^8.0.23-beta.0",
|
||||
"@walletconnect/ethereum-provider": "^2.6.0",
|
||||
"@web3-react/coinbase-wallet": "8.1.2-beta.0",
|
||||
"@web3-react/core": "^8.1.2-beta.0",
|
||||
"@web3-react/metamask": "^8.1.2-beta.0",
|
||||
"@web3-react/walletconnect": "8.1.3-beta.0",
|
||||
"@web3-react/walletconnect-v2": "^8.1.3-beta.0",
|
||||
"ag-grid-community": "^27.0.1",
|
||||
"ag-grid-react": "^27.0.1",
|
||||
"allotment": "1.18.1",
|
||||
|
Loading…
Reference in New Issue
Block a user