Skip to content

Commit

Permalink
Merge pull request #265 from lidofinance/feature/si-1300-update-reef-…
Browse files Browse the repository at this point in the history
…knot-to-v2-on-eth-stake-widget-wagmi-autoconnect

Update reef-knot to v2
  • Loading branch information
jake4take authored Mar 13, 2024
2 parents 6f32f52 + 37e6904 commit f402657
Show file tree
Hide file tree
Showing 6 changed files with 231 additions and 189 deletions.
8 changes: 4 additions & 4 deletions config/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ export const useGetRpcUrlByChainId = () => {

return useCallback(
(chainId: CHAINS) => {
// Needs this condition 'cause in 'providers/web3.tsx' we add `wagmiChains.polygonMumbai` to supportedChains
// so, here chainId = 80001 is arriving which to raises an invariant
// chainId = 1 we need anytime!
// This condition is needed because in 'providers/web3.tsx' we add `wagmiChains.polygonMumbai` to supportedChains as a workaround.
// polygonMumbai (80001) may cause an invariant throwing.
// And we always need Mainnet RPC for some requests, e.g. ETH to USD price, ENS lookup.
if (
chainId !== CHAINS.Mainnet &&
!clientConfig.supportedChainIds.includes(chainId)
) {
// Has no effect on functionality. Just a fix.
// Return empty string as stub
// Return empty string as a stub
// (see: 'providers/web3.tsx' --> jsonRpcBatchProvider --> getStaticRpcBatchProvider)
return '';
}
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@ethersproject/bytes": "^5.7.0",
"@ethersproject/constants": "^5.7.0",
"@ethersproject/contracts": "^5.7.0",
"@ethersproject/providers": "^5.7.0",
"@ethersproject/units": "^5.7.0",
"@lido-sdk/constants": "^3.2.1",
"@lido-sdk/contracts": "^3.0.4",
Expand Down Expand Up @@ -66,7 +67,7 @@
"react-hook-form": "^7.45.2",
"react-is": "^18.2.0",
"react-transition-group": "^4.4.2",
"reef-knot": "^1.15.3",
"reef-knot": "^2.1.0",
"remark": "^13.0.0",
"remark-external-links": "^8.0.0",
"remark-html": "^13.0.1",
Expand Down
77 changes: 77 additions & 0 deletions providers/sdk-legacy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import React, { useEffect, useState } from 'react';
import { ProviderSDK } from '@lido-sdk/react';
import { getStaticRpcBatchProvider } from '@lido-sdk/providers';
import { Web3Provider } from '@ethersproject/providers';
import { Chain, useAccount } from 'wagmi';
import { mainnet } from 'wagmi/chains';
import { useWeb3 } from 'reef-knot/web3-react';

const POLLING_INTERVAL = 12_000;

export const SDKLegacyProvider = (props: {
children?: React.ReactNode;
defaultChainId: number;
supportedChains: Chain[];
rpc: Record<number, string>;
pollingInterval?: number;
}) => {
const {
children,
defaultChainId,
rpc,
supportedChains,
pollingInterval = POLLING_INTERVAL,
} = props;
const { chainId = defaultChainId, account } = useWeb3();
const { connector, isConnected } = useAccount();

const [providerWeb3, setProviderWeb3] = useState<Web3Provider>();

// Reset web3 provider if the provider was set previously,
// and currently no wallet is connected.
// Gets triggered on a wallet disconnection, for example.
if (!isConnected && providerWeb3) {
setProviderWeb3(undefined);
}

useEffect(() => {
void (async () => {
if (!providerWeb3 && connector && isConnected) {
const provider = await connector.getProvider();
const wrappedProvider = new Web3Provider(provider);
wrappedProvider.pollingInterval = pollingInterval;
setProviderWeb3(wrappedProvider);
}
})();
}, [connector, isConnected, pollingInterval, providerWeb3]);

const supportedChainIds = supportedChains.map((chain) => chain.id);

const providerRpc = getStaticRpcBatchProvider(
chainId,
rpc[chainId],
0,
pollingInterval,
);

const providerMainnetRpc = getStaticRpcBatchProvider(
mainnet.id,
rpc[mainnet.id],
0,
pollingInterval,
);

return (
// @ts-expect-error Property children does not exist on type
<ProviderSDK
chainId={chainId}
supportedChainIds={supportedChainIds}
providerWeb3={providerWeb3}
providerRpc={providerRpc}
providerMainnetRpc={providerMainnetRpc}
account={account ?? undefined}
>
{children}
</ProviderSDK>
);
};
78 changes: 48 additions & 30 deletions providers/web3.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,27 @@
import { FC, PropsWithChildren, useMemo } from 'react';
import { ProviderWeb3 } from 'reef-knot/web3-react';
import { getConnectors, holesky } from 'reef-knot/core-react';
import { ReefKnot, getConnectors, holesky } from 'reef-knot/core-react';
import { WagmiConfig, createClient, configureChains, Chain } from 'wagmi';
import * as wagmiChains from 'wagmi/chains';

import { CHAINS } from 'utils/chains';
import { getStaticRpcBatchProvider } from '@lido-sdk/providers';

import { useClientConfig } from 'providers/client-config';
import { dynamics, useGetRpcUrlByChainId } from 'config';
import { useGetRpcUrlByChainId } from 'config';
import { SDKLegacyProvider } from './sdk-legacy';

const Web3Provider: FC<PropsWithChildren> = ({ children }) => {
const { defaultChain, supportedChainIds, walletconnectProjectId } =
useClientConfig();

const getRpcUrlByChainId = useGetRpcUrlByChainId();
const wagmiChainsArray = Object.values({ ...wagmiChains, holesky });

const backendRPC = useMemo(
() =>
supportedChainIds.reduce<Record<number, string>>(
(res, curr) => ({ ...res, [curr]: getRpcUrlByChainId(curr) }),
{
// Required by reef-knot
[CHAINS.Mainnet]: getRpcUrlByChainId(CHAINS.Mainnet),
},
),
[supportedChainIds, getRpcUrlByChainId],
);
const Web3Provider: FC<PropsWithChildren> = ({ children }) => {
const {
defaultChain: defaultChainId,
supportedChainIds,
walletconnectProjectId,
} = useClientConfig();

const client = useMemo(() => {
const wagmiChainsArray = Object.values({ ...wagmiChains, holesky });
const { supportedChains, defaultChain } = useMemo(() => {
const supportedChains = wagmiChainsArray.filter((chain) =>
dynamics.supportedChains.includes(chain.id),
supportedChainIds.includes(chain.id),
);

// Adding Mumbai as a temporary workaround
Expand All @@ -42,9 +32,26 @@ const Web3Provider: FC<PropsWithChildren> = ({ children }) => {
supportedChains.push(wagmiChains.polygonMumbai);

const defaultChain =
wagmiChainsArray.find((chain) => chain.id === dynamics.defaultChain) ||
supportedChains.find((chain) => chain.id === defaultChainId) ||
supportedChains[0]; // first supported chain as fallback
return { supportedChains, defaultChain };
}, [defaultChainId, supportedChainIds]);

const getRpcUrlByChainId = useGetRpcUrlByChainId();

const backendRPC = useMemo(
() =>
supportedChainIds.reduce(
(res, curr) => ({ ...res, [curr]: getRpcUrlByChainId(curr) }),
{
// Mainnet RPC is always required for some requests, e.g. ETH to USD price, ENS lookup
[CHAINS.Mainnet]: getRpcUrlByChainId(CHAINS.Mainnet),
},
),
[supportedChainIds, getRpcUrlByChainId],
);

const client = useMemo(() => {
const jsonRpcBatchProvider = (chain: Chain) => ({
provider: () =>
getStaticRpcBatchProvider(
Expand Down Expand Up @@ -81,19 +88,30 @@ const Web3Provider: FC<PropsWithChildren> = ({ children }) => {
provider,
webSocketProvider,
});
}, [backendRPC, getRpcUrlByChainId, walletconnectProjectId]);
}, [
supportedChains,
defaultChain,
backendRPC,
walletconnectProjectId,
getRpcUrlByChainId,
]);

return (
<WagmiConfig client={client}>
<ProviderWeb3
pollingInterval={1200}
defaultChainId={defaultChain}
supportedChainIds={supportedChainIds}
<ReefKnot
defaultChain={defaultChain}
chains={supportedChains}
rpc={backendRPC}
walletconnectProjectId={walletconnectProjectId}
>
{children}
</ProviderWeb3>
<SDKLegacyProvider
defaultChainId={defaultChain.id}
supportedChains={supportedChains}
rpc={backendRPC}
>
{children}
</SDKLegacyProvider>
</ReefKnot>
</WagmiConfig>
);
};
Expand Down
24 changes: 10 additions & 14 deletions shared/wallet/fallback/useErrorMessage.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
import { useSupportedChains, useConnectorError } from 'reef-knot/web3-react';
import { CHAINS } from '@lido-sdk/constants';
import { useMemo } from 'react';
import {
useSupportedChains,
useConnectorError,
helpers,
} from 'reef-knot/web3-react';
import { useNetwork } from 'wagmi';

export const useErrorMessage = (): string | undefined => {
const error = useConnectorError();
const { isUnsupported, supportedChains } = useSupportedChains();

const chains = useMemo(() => {
const chains = supportedChains
.map(({ chainId, name }) => CHAINS[chainId] || name)
.filter((chain) => chain !== 'unknown');
const lastChain = chains.pop();

return [chains.join(', '), lastChain].filter((chain) => chain).join(' or ');
}, [supportedChains]);
const { isUnsupported } = useSupportedChains();
const { chains: supportedChains } = useNetwork();

// TODO: fix useConnectorError in reef-knot and remove this block
if (isUnsupported) {
return `Unsupported chain. Please switch to ${chains} in your wallet and restart the page.`;
return helpers.getUnsupportedChainError(supportedChains).message;
}

return error?.message;
Expand Down
Loading

0 comments on commit f402657

Please sign in to comment.