Skip to content

Commit

Permalink
feat: add Optimism Sepolia chain support
Browse files Browse the repository at this point in the history
  • Loading branch information
solidovic authored Sep 24, 2024
1 parent 725be9a commit 783d503
Show file tree
Hide file tree
Showing 25 changed files with 119 additions and 87 deletions.
4 changes: 3 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ RESEARCH_ORIGIN=https://research.lido.fi
EL_RPC_URLS_1=
EL_RPC_URLS_17000=
EL_RPC_URLS_11155111=
EL_RPC_URLS_11155420=

# IPFS prefill RPC URLs - list of URLs delimited by commas
PREFILL_UNSAFE_EL_RPC_URLS_1=
PREFILL_UNSAFE_EL_RPC_URLS_17000=
PREFILL_UNSAFE_EL_RPC_URLS_11155111=
PREFILL_UNSAFE_EL_RPC_URLS_11155420=

# supported networks for connecting wallet
SUPPORTED_CHAINS=1,17000,11155111
SUPPORTED_CHAINS=1,17000,11155111,1115542

# this chain uses when a wallet is not connected
DEFAULT_CHAIN=1
Expand Down
9 changes: 9 additions & 0 deletions IPFS.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,14 @@
"enabledWithdrawalDexes": ["one-inch", "paraswap", "bebop"],
"multiChainBanner": []
}
},
"11155420": {
"__warning__": "For testing purposes only",
"cid": "",
"leastSafeVersion": "0.36.1",
"config": {
"enabledWithdrawalDexes": ["one-inch", "paraswap", "bebop"],
"multiChainBanner": []
}
}
}
3 changes: 3 additions & 0 deletions config/get-secret-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export type SecretConfigType = Modify<
rpcUrls_1: [string, ...string[]];
rpcUrls_17000: [string, ...string[]];
rpcUrls_11155111: [string, ...string[]];
rpcUrls_11155420: [string, ...string[]];
// Dynamic keys like rpcUrls_<number>
[key: `rpcUrls_${number}`]: string[];

Expand Down Expand Up @@ -44,6 +45,8 @@ export const getSecretConfig = (): SecretConfigType => {
],
rpcUrls_11155111: (serverRuntimeConfig.rpcUrls_11155111?.split(',') ??
[]) as [string, ...string[]],
rpcUrls_11155420: (serverRuntimeConfig.rpcUrls_11155420?.split(',') ??
[]) as [string, ...string[]],

cspReportOnly: toBoolean(serverRuntimeConfig.cspReportOnly),

Expand Down
1 change: 1 addition & 0 deletions config/user-config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export type UserConfigDefaultType = {
[CHAINS.Mainnet]: string[];
[CHAINS.Holesky]: string[];
[CHAINS.Sepolia]: string[];
[CHAINS.OptimismSepolia]: string[];
};
walletconnectProjectId: string | undefined;
};
1 change: 1 addition & 0 deletions config/user-config/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const getUserConfigDefault = (): UserConfigDefaultType => {
[CHAINS.Mainnet]: config.prefillUnsafeElRpcUrls1,
[CHAINS.Holesky]: config.prefillUnsafeElRpcUrls17000,
[CHAINS.Sepolia]: config.prefillUnsafeElRpcUrls11155111,
[CHAINS.OptimismSepolia]: config.prefillUnsafeElRpcUrls11155420,
},
walletconnectProjectId: config.walletconnectProjectId,
};
Expand Down
16 changes: 16 additions & 0 deletions consts/chains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export enum CHAINS {
Mainnet = 1,
Holesky = 17000,
Sepolia = 11155111,
OptimismSepolia = 11155420,
}

export enum LIDO_MULTICHAIN_CHAINS {
Expand All @@ -16,3 +17,18 @@ export enum LIDO_MULTICHAIN_CHAINS {
'BNB Chain' = 56,
'Mode Chain' = 34443,
}

// TODO: move to legacy lido-js-sdk package
export const SDK_LEGACY_SUPPORTED_CHAINS = [
CHAINS.Mainnet,
CHAINS.Holesky,
CHAINS.Sepolia,
];

// TODO: move to @lidofinance/lido-ethereum-sdk package
export const SDK_SUPPORTED_MULTICHAIN_CHAINS = [CHAINS.OptimismSepolia];

// TODO: move to @lidofinance/lido-ethereum-sdk package
export const isSDKSupportedL2Chain = (chainId: CHAINS) => {
return SDK_SUPPORTED_MULTICHAIN_CHAINS.indexOf(chainId) > -1;
};
2 changes: 2 additions & 0 deletions env-dynamics.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ export const prefillUnsafeElRpcUrls1 = process.env.PREFILL_UNSAFE_EL_RPC_URLS_1?
export const prefillUnsafeElRpcUrls17000 = process.env.PREFILL_UNSAFE_EL_RPC_URLS_17000?.split(',') ?? [];
/** @type string[] */
export const prefillUnsafeElRpcUrls11155111 = process.env.PREFILL_UNSAFE_EL_RPC_URLS_11155111?.split(',') ?? [];
/** @type string[] */
export const prefillUnsafeElRpcUrls11155420 = process.env.PREFILL_UNSAFE_EL_RPC_URLS_11155420?.split(',') ?? [];

/** @type boolean */
export const enableQaHelpers = toBoolean(process.env.ENABLE_QA_HELPERS);
Expand Down
4 changes: 2 additions & 2 deletions features/stake/stake-form/controls/stake-amount-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import { useStakingLimitWarning } from 'shared/hooks/use-staking-limit-warning';
import { useDappStatus } from 'shared/hooks/use-dapp-status';

export const StakeAmountInput = () => {
const { isWalletConnected, isDappActive } = useDappStatus();
const { isWalletConnected, isDappActive, isDappActiveOnL2 } = useDappStatus();
const { maxAmount, stakingLimitInfo } = useStakeFormData();
const { limitWarning, limitError } = useStakingLimitWarning(
stakingLimitInfo?.stakeLimitLevel,
);

return (
<TokenAmountInputHookForm
disabled={isWalletConnected && !isDappActive}
disabled={(isWalletConnected && !isDappActive) || isDappActiveOnL2}
fieldName="amount"
token={'ETH'}
data-testid="stakeInput"
Expand Down
3 changes: 2 additions & 1 deletion features/stake/stake-form/controls/stake-submit-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import { useDappStatus } from 'shared/hooks/use-dapp-status';
import { useStakeFormData } from '../stake-form-context';

export const StakeSubmitButton = () => {
const { isDappActive } = useDappStatus();
const { isDappActive, isDappActiveOnL2 } = useDappStatus();
const { stakingLimitInfo } = useStakeFormData();

return (
<SubmitButtonHookForm
disabled={
!isDappActive ||
isDappActiveOnL2 ||
stakingLimitInfo?.stakeLimitLevel === LIMIT_LEVEL.REACHED
}
data-testid="stakeSubmitBtn"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const useWithdrawalsBaseData =
const { contractRpc } = useWithdrawalsContract();

return useLidoSWR(
['swr:wqBaseData', contractRpc.address, chainId],
['swr:wqBaseData', contractRpc?.address, chainId],
async () => {
const [minAmount, maxAmount, isPausedMode, isBunkerMode] =
await Promise.all([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ import { SubmitButtonHookForm } from 'shared/hook-form/controls/submit-button-ho
import { useFormState } from 'react-hook-form';
import { isValidationErrorTypeUnhandled } from 'shared/hook-form/validation/validation-error';
import { useIsMultisig } from 'shared/hooks/useIsMultisig';
import { useDappStatus } from 'shared/hooks/use-dapp-status';

// conditional render breaks useFormState, so it can't be inside SubmitButton
export const useRequestSubmitButtonProps = (): SubmitButtonRequestProps => {
const { isDappActiveOnL2 } = useDappStatus();
const { isPaused } = useWithdrawals();
const { isValidating, isSubmitting, errors } =
useFormState<RequestFormInputType>({ name: ['requests', 'amount'] });
Expand All @@ -19,6 +21,7 @@ export const useRequestSubmitButtonProps = (): SubmitButtonRequestProps => {
loading: isValidating || isSubmitting,
disabled:
isPaused ||
isDappActiveOnL2 ||
(!!errors.amount && !isValidationErrorTypeUnhandled(errors.amount.type)),
};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ import { TokenAmountInputHookForm } from 'shared/hook-form/controls/token-amount
import { useDappStatus } from 'shared/hooks/use-dapp-status';

export const TokenAmountInputRequest = () => {
const { isWalletConnected, isDappActive } = useDappStatus();
const { isWalletConnected, isDappActive, isDappActiveOnL2 } = useDappStatus();
const token = useWatch<RequestFormInputType, 'token'>({ name: 'token' });
const { maxAmount, isTokenLocked } = useRequestFormData();

const { balanceDiff } = useTvlMessage();

return (
<TokenAmountInputHookForm
disabled={isWalletConnected && !isDappActive}
disabled={(isWalletConnected && !isDappActive) || isDappActiveOnL2}
fieldName="amount"
data-testid="requestInput"
token={token}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ const OPTIONS: TokenOption[] = [
];

export const TokenSelectRequest = () => {
const { isWalletConnected, isDappActive } = useDappStatus();
const { isWalletConnected, isDappActive, isDappActiveOnL2 } = useDappStatus();

return (
<TokenSelectHookForm
disabled={isWalletConnected && !isDappActive}
disabled={(isWalletConnected && !isDappActive) || isDappActiveOnL2}
options={OPTIONS}
/>
);
Expand Down
8 changes: 7 additions & 1 deletion features/wsteth/wrap/hooks/use-approve-gas-limit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {

import { config } from 'config';
import { WSTETH_APPROVE_GAS_LIMIT } from 'consts/tx';
import { SDK_LEGACY_SUPPORTED_CHAINS, CHAINS } from 'consts/chains';
import { STRATEGY_IMMUTABLE } from 'consts/swr-strategies';

export const useApproveGasLimit = () => {
Expand All @@ -18,7 +19,12 @@ export const useApproveGasLimit = () => {
const { data } = useLidoSWR(
['swr:approve-wrap-gas-limit', chainId],
async (_key, chainId) => {
if (!chainId) return;
if (
!chainId ||
SDK_LEGACY_SUPPORTED_CHAINS.indexOf(chainId as CHAINS) < 0
) {
return;
}

try {
const gasLimit = await steth.estimateGas.approve(
Expand Down
1 change: 1 addition & 0 deletions global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ declare module 'next/config' {
rpcUrls_1: string | undefined;
rpcUrls_17000: string | undefined;
rpcUrls_11155111: string | undefined;
rpcUrls_11155420: string | undefined;

cspTrustedHosts: string | undefined;
cspReportUri: string | undefined;
Expand Down
1 change: 1 addition & 0 deletions next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ export default withBundleAnalyzer({
rpcUrls_1: process.env.EL_RPC_URLS_1,
rpcUrls_17000: process.env.EL_RPC_URLS_17000,
rpcUrls_11155111: process.env.EL_RPC_URLS_11155111,
rpcUrls_11155420: process.env.EL_RPC_URLS_11155420,

cspTrustedHosts: process.env.CSP_TRUSTED_HOSTS,
cspReportUri: process.env.CSP_REPORT_URI,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"@lidofinance/api-rpc": "^0.45.1",
"@lidofinance/eth-api-providers": "^0.45.1",
"@lidofinance/eth-providers": "^0.45.1",
"@lidofinance/lido-ethereum-sdk": "^3.4.0",
"@lidofinance/lido-ethereum-sdk": "3.5.0-alpha.1",
"@lidofinance/lido-ui": "^3.26.0",
"@lidofinance/next-api-wrapper": "^0.45.1",
"@lidofinance/next-ip-rate-limit": "^0.45.1",
Expand Down
3 changes: 2 additions & 1 deletion pages/api/rpc.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { CHAINS } from '@lido-sdk/constants';
import { wrapRequest as wrapNextRequest } from '@lidofinance/next-api-wrapper';
import { trackedFetchRpcFactory } from '@lidofinance/api-rpc';

import { config, secretConfig } from 'config';
import { API_ROUTES } from 'consts/api';
import { CHAINS } from 'consts/chains';
import { METRICS_PREFIX } from 'consts/metrics';
import {
rateLimit,
Expand Down Expand Up @@ -54,6 +54,7 @@ const rpc = rpcFactory({
[CHAINS.Mainnet]: secretConfig.rpcUrls_1,
[CHAINS.Holesky]: secretConfig.rpcUrls_17000,
[CHAINS.Sepolia]: secretConfig.rpcUrls_11155111,
[CHAINS.OptimismSepolia]: secretConfig.rpcUrls_11155420,
},
allowedRPCMethods: [
'test',
Expand Down
18 changes: 17 additions & 1 deletion providers/lido-sdk.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import {
LidoSDKstETH,
LidoSDKwstETH,
} from '@lidofinance/lido-ethereum-sdk/erc20';
import {
LidoSDKL2Steth,
LidoSDKL2Wsteth,
} from '@lidofinance/lido-ethereum-sdk/l2';
import invariant from 'tiny-invariant';
import { useChainId, useClient, useConnectorClient } from 'wagmi';
import { useTokenTransferSubscription } from 'shared/hooks/use-balance';
Expand All @@ -13,6 +17,8 @@ type LidoSDKContextValue = {
core: LidoSDKCore;
steth: LidoSDKstETH;
wsteth: LidoSDKwstETH;
l2Steth: LidoSDKL2Steth;
l2Wsteth: LidoSDKL2Wsteth;
subscribeToTokenUpdates: ReturnType<typeof useTokenTransferSubscription>;
};

Expand Down Expand Up @@ -46,7 +52,17 @@ export const LidoSDKProvider = ({ children }: React.PropsWithChildren) => {
const steth = new LidoSDKstETH({ core });
const wsteth = new LidoSDKwstETH({ core });

return { core, steth, wsteth, subscribeToTokenUpdates: subscribe };
const l2Steth = new LidoSDKL2Steth({ core });
const l2Wsteth = new LidoSDKL2Wsteth({ core });

return {
core,
steth,
wsteth,
l2Steth,
l2Wsteth,
subscribeToTokenUpdates: subscribe,
};
}, [chainId, fallbackRpcUrl, publicClient, subscribe, walletClient]);
return (
<LidoSDKContext.Provider value={sdk}>{children}</LidoSDKContext.Provider>
Expand Down
4 changes: 3 additions & 1 deletion providers/sdk-legacy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ 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';

type SDKLegacyProviderProps = PropsWithChildren<{
Expand Down Expand Up @@ -76,7 +77,8 @@ export const SDKLegacyProvider = ({
);

const chainId = useMemo(() => {
return supportedChainIds.indexOf(wagmiChainId) > -1
return supportedChainIds.indexOf(wagmiChainId) > -1 &&
SDK_LEGACY_SUPPORTED_CHAINS.indexOf(wagmiChainId) > -1
? wagmiChainId
: defaultChainId;
}, [defaultChainId, supportedChainIds, wagmiChainId]);
Expand Down
1 change: 1 addition & 0 deletions scripts/log-environment-variables.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export const secretKeys = [
'EL_RPC_URLS_5',
'EL_RPC_URLS_17000',
'EL_RPC_URLS_11155111',
'EL_RPC_URLS_11155420',
]


Expand Down
21 changes: 14 additions & 7 deletions shared/hooks/use-balance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,22 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */

import { QueryKey, useQuery, useQueryClient } from '@tanstack/react-query';
import type { AbstractLidoSDKErc20 } from '@lidofinance/lido-ethereum-sdk/erc20';
import { BigNumber } from 'ethers';
import { useLidoSDK } from 'providers/lido-sdk';
import { useCallback, useEffect, useMemo, useState } from 'react';
import type { Address, WatchContractEventOnLogsFn } from 'viem';
import {
useBlockNumber,
useBalance,
useAccount,
useReadContract,
useWatchContractEvent,
} from 'wagmi';

import type { AbstractLidoSDKErc20 } from '@lidofinance/lido-ethereum-sdk/erc20';
import type { GetBalanceData } from 'wagmi/query';
import type { Address, WatchContractEventOnLogsFn } from 'viem';

import { config } from 'config';
import { isSDKSupportedL2Chain, CHAINS } from 'consts/chains';

const nativeToBN = (data: bigint) => BigNumber.from(data.toString());

Expand Down Expand Up @@ -254,14 +255,17 @@ export const useStethBalance = ({
const { address } = useAccount();
const mergedAccount = account ?? address;

const { steth, core } = useLidoSDK();
const { steth, l2Steth, core } = useLidoSDK();

const { data: contract, isLoading } = useQuery({
queryKey: ['steth-contract', core.chainId],
enabled: !!mergedAccount,

staleTime: Infinity,
queryFn: async () => steth.getContract(),
queryFn: async () =>
isSDKSupportedL2Chain(core.chainId as CHAINS)
? l2Steth.getContract()
: steth.getContract(),
});

const balanceData = useTokenBalance(
Expand All @@ -280,13 +284,16 @@ export const useWstethBalance = ({
const { address } = useAccount();
const mergedAccount = account ?? address;

const { wsteth, core } = useLidoSDK();
const { wsteth, l2Wsteth, core } = useLidoSDK();

const { data: contract, isLoading } = useQuery({
queryKey: ['wsteth-contract', core.chainId],
enabled: !!mergedAccount,
staleTime: Infinity,
queryFn: async () => wsteth.getContract(),
queryFn: async () =>
isSDKSupportedL2Chain(core.chainId as CHAINS)
? l2Wsteth.getContract()
: wsteth.getContract(),
});

const balanceData = useTokenBalance(
Expand Down
Loading

0 comments on commit 783d503

Please sign in to comment.