Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update reef-knot to v2 #265

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.0.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>
);
};
75 changes: 45 additions & 30 deletions providers/web3.tsx
Original file line number Diff line number Diff line change
@@ -1,50 +1,53 @@
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 {
defaultChain: defaultChainId,
supportedChainIds,
walletconnectProjectId,
} = useClientConfig();

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

// Adding Mumbai as a temporary workaround
// for the wagmi and walletconnect bug, when some wallets are failing to connect
// when there are only one supported network, so we need at least 2 of them.
// Mumbai should be the last in the array, otherwise wagmi can send request to it.
// TODO: remove after updating wagmi to v1+
supportedChains.push(wagmiChains.polygonMumbai);

const defaultChain =
supportedChains.find((chain) => chain.id === defaultChainId) ||
supportedChains[0]; // first supported chain as fallback

const getRpcUrlByChainId = useGetRpcUrlByChainId();

const backendRPC = useMemo(
() =>
supportedChainIds.reduce<Record<number, string>>(
supportedChainIds.reduce(
(res, curr) => ({ ...res, [curr]: getRpcUrlByChainId(curr) }),
{
// Required by reef-knot
// 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 wagmiChainsArray = Object.values({ ...wagmiChains, holesky });
const supportedChains = wagmiChainsArray.filter((chain) =>
dynamics.supportedChains.includes(chain.id),
);

// Adding Mumbai as a temporary workaround
// for the wagmi and walletconnect bug, when some wallets are failing to connect
// when there are only one supported network, so we need at least 2 of them.
// Mumbai should be the last in the array, otherwise wagmi can send request to it.
// TODO: remove after updating wagmi to v1+
supportedChains.push(wagmiChains.polygonMumbai);

const defaultChain =
wagmiChainsArray.find((chain) => chain.id === dynamics.defaultChain) ||
supportedChains[0]; // first supported chain as fallback

const jsonRpcBatchProvider = (chain: Chain) => ({
provider: () =>
getStaticRpcBatchProvider(
Expand Down Expand Up @@ -81,19 +84,31 @@ 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}
pollingInterval={1200}
>
{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
Loading