Skip to content

Commit

Permalink
feat: wire legacy sdk provider trough viem+new sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeday committed Oct 14, 2024
1 parent efd07b9 commit 418119d
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 104 deletions.
5 changes: 4 additions & 1 deletion providers/lido-sdk.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ import { LidoSDKWrap } from '@lidofinance/lido-ethereum-sdk/wrap';
import { config } from 'config';
import { useTokenTransferSubscription } from 'shared/hooks/use-balance';
import { LIDO_L2_CONTRACT_ADDRESSES } from '@lidofinance/lido-ethereum-sdk/common';
import { SDKLegacyProvider } from './sdk-legacy';

type LidoSDKContextValue = {
core: LidoSDKCore;
stETH: LidoSDKstETH;
wstETH: LidoSDKwstETH;
l2: LidoSDKL2;
wrap: LidoSDKWrap;
chainId: CHAINS;
isL2: boolean;
subscribeToTokenUpdates: ReturnType<typeof useTokenTransferSubscription>;
};
Expand Down Expand Up @@ -86,13 +88,14 @@ export const LidoSDKProvider = ({ children }: React.PropsWithChildren) => {
wstETH,
wrap,
l2,
chainId: core.chainId,
isL2: !!LIDO_L2_CONTRACT_ADDRESSES[chainId as CHAINS],
subscribeToTokenUpdates: subscribe,
};
}, [chainId, publicClient, subscribe, walletClient]);
return (
<LidoSDKContext.Provider value={contextValue}>
{children}
<SDKLegacyProvider>{children}</SDKLegacyProvider>
</LidoSDKContext.Provider>
);
};
137 changes: 42 additions & 95 deletions providers/sdk-legacy.tsx
Original file line number Diff line number Diff line change
@@ -1,121 +1,68 @@
import React, { PropsWithChildren, useEffect, useMemo, useState } from 'react';
import { useReefKnotContext } from 'reef-knot/core-react';
// TODO: to remove the 'reef-knot/web3-react' after it will be deprecated
import { useSupportedChains } from 'reef-knot/web3-react';
import { useAccount, useClient, useConfig } from 'wagmi';
import { mainnet } from 'wagmi/chains';
import React, { PropsWithChildren, useMemo } from 'react';
import { useAccount, usePublicClient } from 'wagmi';

import { Web3Provider } from '@ethersproject/providers';
import { ProviderSDK } from '@lido-sdk/react';
import { getStaticRpcBatchProvider } from '@lido-sdk/providers';

import { SDK_LEGACY_SUPPORTED_CHAINS } from 'consts/chains';
import { useDappStatus } from 'shared/hooks/use-dapp-status';
import { useLidoSDK } from './lido-sdk';
import { config } from 'config';
import { isSDKSupportedL2Chain } from 'consts/chains';

type SDKLegacyProviderProps = PropsWithChildren<{
defaultChainId: number;
pollingInterval: number;
}>;

export const SDKLegacyProvider = ({
children,
defaultChainId,
pollingInterval,
}: SDKLegacyProviderProps) => {
const { chainId: wagmiChainId = defaultChainId, address } = useAccount();
const { supportedChains } = useSupportedChains();
const { isDappActiveOnL1 } = useDappStatus();
const config = useConfig();
const client = useClient();
const { rpc } = useReefKnotContext();

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

useEffect(() => {
let isHookMounted = true;

const getProviderTransport = async () => {
const { state } = config;
if (!state.current) return client?.transport;
const connector = state.connections.get(state.current)?.connector;
if (!connector) return client?.transport;
const provider: any = await connector.getProvider();
return provider || client?.transport;
};

const getProviderValue = async () => {
// old sdk can only supports wallet connection on L1
if (!client || !address || !isDappActiveOnL1) return undefined;
const { chain } = client;
const providerTransport = await getProviderTransport();

// https://wagmi.sh/core/guides/ethers#reference-implementation-1
const provider = new Web3Provider(providerTransport, {
chainId: chain.id,
name: chain.name,
ensAddress: chain.contracts?.ensRegistry?.address,
});
provider.pollingInterval = pollingInterval;

return provider;
};

const getProviderAndSet = async () => {
const provider = await getProviderValue();
if (isHookMounted) setProviderWeb3(provider);
};

void getProviderAndSet();

return () => {
isHookMounted = false;
};
}, [
config,
config.state,
client,
address,
isDappActiveOnL1,
pollingInterval,
]);
export const SDKLegacyProvider = ({ children }: PropsWithChildren) => {
const { defaultChain, supportedChains, PROVIDER_POLLING_INTERVAL } = config;
const { address } = useAccount();
const { core, isL2, chainId } = useLidoSDK();

const supportedChainIds = useMemo(
() => supportedChains.map((chain) => chain.chainId),
() => supportedChains.filter((chain) => !isSDKSupportedL2Chain(chain)),
[supportedChains],
);

const chainId = useMemo(() => {
if (providerWeb3) {
return supportedChainIds.indexOf(wagmiChainId) > -1 &&
SDK_LEGACY_SUPPORTED_CHAINS.indexOf(wagmiChainId) > -1
? wagmiChainId
: defaultChainId;
const ethersWeb3Provider = useMemo(() => {
if (isL2 || !core.web3Provider) return undefined;
const { chain, web3Provider } = core;
const transport = web3Provider.transport;

const provider = new Web3Provider(transport, {
chainId: chain.id,
name: chain.name,
ensAddress: chain.contracts?.ensRegistry?.address,
});
provider.pollingInterval = PROVIDER_POLLING_INTERVAL;
return provider;
}, [isL2, core, PROVIDER_POLLING_INTERVAL]);

const onlyL1chainId = useMemo(() => {
if (ethersWeb3Provider) {
return chainId;
}
return defaultChainId;
}, [defaultChainId, providerWeb3, supportedChainIds, wagmiChainId]);
return defaultChain;
}, [chainId, defaultChain, ethersWeb3Provider]);

const onlyL1publicClient = usePublicClient({ chainId: onlyL1chainId });
const publicMainnetClient = usePublicClient({ chainId: 1 });

// only Web3Provider can accept viem transport
const providerRpc = useMemo(
() => getStaticRpcBatchProvider(chainId, rpc[chainId], 0, pollingInterval),
[rpc, chainId, pollingInterval],
() =>
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
new Web3Provider(onlyL1publicClient!.transport, onlyL1chainId),
[onlyL1chainId, onlyL1publicClient],
);

const providerMainnetRpc = useMemo(
() =>
getStaticRpcBatchProvider(
mainnet.id,
rpc[mainnet.id],
0,
pollingInterval,
),
[rpc, pollingInterval],
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
new Web3Provider(publicMainnetClient!.transport, 1),
[publicMainnetClient],
);

return (
// @ts-expect-error Property children does not exist on type
<ProviderSDK
chainId={chainId}
chainId={onlyL1chainId}
supportedChainIds={supportedChainIds}
providerWeb3={providerWeb3}
providerWeb3={ethersWeb3Provider}
providerRpc={providerRpc}
providerMainnetRpc={providerMainnetRpc}
account={address ?? undefined}
Expand Down
11 changes: 3 additions & 8 deletions providers/web3.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { useGetRpcUrlByChainId } from 'config/rpc';
import { CHAINS } from 'consts/chains';
import { ConnectWalletModal } from 'shared/wallet/connect-wallet-modal';

import { SDKLegacyProvider } from './sdk-legacy';
import { useWeb3Transport } from 'utils/use-web3-transport';

type ChainsList = [wagmiChains.Chain, ...wagmiChains.Chain[]];
Expand Down Expand Up @@ -115,13 +114,9 @@ const Web3Provider: FC<PropsWithChildren> = ({ children }) => {
walletDataList={walletsDataList}
>
{isWalletConnectionAllowed && <AutoConnect autoConnect />}
<SDKLegacyProvider
defaultChainId={defaultChain.id}
pollingInterval={config.PROVIDER_POLLING_INTERVAL}
>
{children}
<ConnectWalletModal />
</SDKLegacyProvider>

{children}
<ConnectWalletModal />
</ReefKnot>
</QueryClientProvider>
</WagmiProvider>
Expand Down

0 comments on commit 418119d

Please sign in to comment.