From f08e945e33407b05f325a7c0ced283821dec6325 Mon Sep 17 00:00:00 2001 From: Anton Shalimov Date: Mon, 2 Dec 2024 17:34:10 +0300 Subject: [PATCH 01/23] refactor: migrate to new SDK, to bigint, to viem, to react-query --- .babelrc | 15 + Dockerfile | 2 +- abi/aggregator-abi.ts | 201 ++++++ abi/ens-registry-abi.ts | 205 ++++++ abi/ens-registry.abi.json | 274 -------- abi/ens-resolver-abi.ts | 190 ++++++ abi/ens-resolver.abi.json | 585 ------------------ abi/l2-steth.abi.json | 438 ------------- abi/l2-wstesth.abi.json | 296 --------- abi/lidoLocator.abi.json | 201 ------ abi/partial-curve-abi.ts | 14 + abi/partial-staking-router.ts | 110 ++++ abi/partialCurveAbi.abi.json | 13 - abi/partialStakingRouter.abi.json | 125 ---- config/external-config/types.ts | 4 +- .../use-external-config-context.ts | 74 +-- config/feature-flags/context-hook.tsx | 3 +- config/groups/stake.ts | 8 +- config/groups/web3.ts | 4 - config/groups/withdrawal-queue-estimate.ts | 13 +- config/rpc/index.ts | 6 - config/user-config/context-hook.tsx | 3 +- consts/aggregator.ts | 5 +- consts/contract-addresses.ts | 30 + consts/react-query-strategies.ts | 25 + consts/staking-router.ts | 24 - consts/swr-strategies.ts | 41 -- consts/token-addresses.ts | 34 + consts/tokens.ts | 4 + consts/tx.ts | 16 +- .../use-remote-version.ts | 62 +- .../use-version-status.ts | 59 +- features/rewards/components/EthSymbol.tsx | 4 +- features/rewards/components/IndexerLink.tsx | 2 +- features/rewards/components/NumberFormat.tsx | 28 +- .../rewardsListContent/RewardsListContent.tsx | 9 +- .../rewardsListContent/RewardsListsEmpty.tsx | 1 + .../RewardsListsUnsupportedChain.tsx | 3 +- .../components/stats/average-apr-block.tsx | 4 +- .../components/stats/steth-balance-block.tsx | 4 +- .../components/stats/steth-price-block.tsx | 10 +- .../components/stats/steth-rewarded-block.tsx | 8 +- features/rewards/constants.ts | 5 +- features/rewards/features/top-card/wallet.tsx | 4 +- features/rewards/helpers/big.ts | 47 -- features/rewards/helpers/index.ts | 1 - .../rewards/hooks/use-rewards-balance-data.ts | 29 +- features/rewards/hooks/use-steth-eth-rate.ts | 46 +- .../rewards/hooks/useGetCurrentAddress.ts | 19 +- features/rewards/hooks/useRewardsDataLoad.ts | 37 +- features/rewards/utils/addressValidation.ts | 7 +- features/rewards/utils/genExportData.ts | 10 +- features/rewards/utils/numberFormatting.ts | 93 +-- features/rewards/utils/resolveEns.ts | 12 +- .../settings/settings-form/settings-form.tsx | 10 +- features/stake/lido-stats/lido-stats.tsx | 36 +- features/stake/stake-faq/list/lido-fee.tsx | 4 +- features/stake/stake-form/hooks.ts | 39 +- .../hooks/use-tx-modal-stages-stake.tsx | 20 +- .../stake-form-context/stake-form-context.tsx | 50 +- .../stake-form/stake-form-context/types.ts | 21 +- .../stake-form-context/validation.ts | 22 +- features/stake/stake-form/stake-form-info.tsx | 11 +- features/stake/stake-form/use-stake.ts | 126 ++-- features/stake/stake-form/utils.ts | 14 +- features/stake/stake-form/wallet/wallet.tsx | 6 +- .../swap-discount-banner/integrations.tsx | 9 +- .../swap-discount-banner.tsx | 4 +- .../swap-discount-banner/use-swap-discount.ts | 32 +- .../claim-form-context/use-helper-state.ts | 10 +- .../claim/form/requests-list/request-item.tsx | 17 +- .../withdrawals/claim/form/submit-button.tsx | 8 +- .../claim/form/transaction-info.tsx | 5 +- .../use-tx-modal-stages-claim.tsx | 9 +- .../claim/wallet/wallet-availale-amount.tsx | 4 +- .../claim/wallet/wallet-pending-amount.tsx | 8 +- .../contexts/claim-data-context/index.tsx | 3 +- .../contexts/withdrawals-context.tsx | 14 +- features/withdrawals/hooks/contract/index.ts | 1 + .../hooks/contract/use-withdrawal-approve.ts | 50 ++ .../withdrawals/hooks/contract/useClaim.ts | 101 ++- .../hooks/contract/useLidoShareRate.ts | 26 - .../withdrawals/hooks/contract/useRequest.ts | 370 +++-------- .../hooks/contract/useTotalSupply.ts | 14 + .../hooks/contract/useUnfinalizedSteth.ts | 19 +- .../hooks/contract/useWithdrawalsBaseData.ts | 51 +- .../hooks/contract/useWithdrawalsContract.ts | 14 - .../hooks/contract/useWithdrawalsData.ts | 143 +++-- .../hooks/use-withdraw-claim-tx-price.ts | 60 ++ .../hooks/use-withdraw-request-tx-price.ts | 108 ++++ .../hooks/useEthAmountByStethWsteth.ts | 24 +- .../withdrawals/hooks/useNftDataByTxHash.ts | 60 +- features/withdrawals/hooks/useTvlMessage.ts | 2 +- features/withdrawals/hooks/useWaitingTime.ts | 34 +- .../withdrawals/hooks/useWithdrawTxPrice.ts | 170 ----- .../controls/token-amount-input-request.tsx | 2 +- .../form/controls/token-select-request.tsx | 6 +- .../form/options/dex-options/dex-options.tsx | 16 +- .../request/form/options/lido-option.tsx | 6 +- .../request/form/options/options-picker.tsx | 31 +- .../request/form/requests-info.tsx | 4 +- .../request/form/transaction-info.tsx | 17 +- .../__tests__/validators.test.ts | 46 +- .../request-form-context.tsx | 8 +- .../request/request-form-context/types.ts | 29 +- .../use-request-form-data-context-value.ts | 40 +- .../use-validation-context.ts | 14 +- .../request-form-context/validators.ts | 60 +- .../tx-stage-request-success.tsx | 16 +- .../use-tx-modal-stages-request.tsx | 18 +- .../request/wallet/wallet-queue-tooltip.tsx | 2 +- .../request/wallet/wallet-wsteth-balance.tsx | 7 +- .../withdrawals/request/wallet/wallet.tsx | 7 +- .../request/withdrawal-rates/integrations.ts | 50 +- .../request/withdrawal-rates/types.ts | 14 +- .../withdrawal-rates/use-withdrawal-rates.ts | 74 ++- .../input-decorator-tvl-stake.tsx | 5 +- .../wallet-my-requests/wallet-my-requests.tsx | 4 +- features/withdrawals/types/request-status.ts | 16 +- .../withdrawals/types/tokens-withdrawable.ts | 9 +- .../utils/calc-expected-request-eth.ts | 10 +- features/withdrawals/utils/calc-share-rate.ts | 14 +- .../list/unstake-amount-boundaries.tsx | 4 +- .../hooks/use-debounced-wsteth-steth.ts | 59 +- features/wsteth/shared/types.ts | 11 +- features/wsteth/shared/wallet/wallet.tsx | 31 +- .../hooks/use-tx-modal-stages-unwrap.tsx | 13 +- .../use-unwra-form-validation-context.ts | 2 +- .../hooks/use-unwrap-form-processing.ts | 182 +++--- .../unwrap/hooks/use-unwrap-gas-limit.ts | 48 +- .../hooks/use-unwrap-tx-on-l2-approve.ts | 51 +- .../unwrap/unwrap-form-context/types.ts | 6 +- .../unwrap-form-context.tsx | 3 +- .../unwrap-form-validators.tsx | 17 +- .../amount-input-unwrap.tsx | 5 +- .../unwrap/unwrap-form/unwrap-stats.tsx | 33 +- .../wrap/hooks/use-approve-gas-limit.tsx | 54 +- .../wrap/hooks/use-tx-modal-stages-wrap.tsx | 25 +- .../wrap/hooks/use-wrap-form-network-data.ts | 10 +- .../wrap/hooks/use-wrap-form-processing.ts | 209 ++++--- .../hooks/use-wrap-form-validation-context.ts | 11 +- .../wsteth/wrap/hooks/use-wrap-gas-limit.ts | 129 ++-- .../wrap/hooks/use-wrap-tx-on-l1-approve.ts | 93 ++- .../hooks/use-wrap-tx-on-l1-processing.ts | 65 -- .../wsteth/wrap/wrap-form-context/types.ts | 19 +- .../wrap-form-context/wrap-form-context.tsx | 20 +- .../wrap-form-context/wrap-form-validators.ts | 20 +- .../wrap-form-controls/token-select-wrap.tsx | 2 +- features/wsteth/wrap/wrap-form/wrap-stats.tsx | 47 +- jest.config.cjs => jest.config.mjs | 2 +- modules/web3/consts/index.ts | 3 + modules/web3/consts/symbols.ts | 1 + modules/web3/consts/tx.ts | 9 + modules/web3/consts/units.ts | 5 + modules/web3/hooks/index.ts | 7 +- modules/web3/hooks/use-allowance.ts | 6 +- modules/web3/hooks/use-balance.ts | 36 +- modules/web3/hooks/use-contract-address.ts | 35 ++ modules/web3/hooks/use-max-gas-price.ts | 10 +- .../web3/hooks/use-stETH-by-wstETH-on-l2.ts | 27 - modules/web3/hooks/use-stETH-by-wstETH.ts | 23 + .../web3/hooks/use-staking-limit-warning.ts | 2 +- .../web3/hooks/use-steth-contract-address.ts | 15 + .../web3/hooks/use-wstETH-by-stETH-on-l2.ts | 27 - modules/web3/hooks/use-wstETH-by-stETH.ts | 22 + .../web3/hooks/use-wsteth-contract-address.ts | 15 + modules/web3/index.ts | 3 + .../web3/utils/apply-round-up-gas-limit.ts | 3 + modules/web3/utils/index.ts | 2 +- .../utils/send-tx/apply-round-up-gas-limit.ts | 8 - modules/web3/utils/send-tx/estimate-gas.ts | 25 - modules/web3/utils/send-tx/get-fee-data.ts | 53 -- modules/web3/utils/send-tx/index.ts | 1 - modules/web3/utils/send-tx/send-tx.ts | 47 -- modules/web3/web3-provider/dapp-chain.tsx | 21 +- modules/web3/web3-provider/index.ts | 3 +- modules/web3/web3-provider/lido-sdk-l2.tsx | 53 ++ modules/web3/web3-provider/lido-sdk.tsx | 31 +- modules/web3/web3-provider/sdk-legacy.tsx | 80 --- .../web3/web3-provider/use-web3-transport.ts | 18 +- modules/web3/web3-provider/web3-provider.tsx | 111 +++- package.json | 29 +- pages/api/rpc.ts | 35 +- providers/index.tsx | 39 +- providers/ipfs-info-box-statuses.tsx | 30 +- providers/rewardsHistory.tsx | 29 +- shared/banners/curve/curve.tsx | 4 +- shared/banners/curve/useCurve.ts | 19 +- .../modal-pool-banners/modal-pool-banners.tsx | 1 + .../allowance-data-table-row.tsx | 14 +- .../data-table-row-steth-by-wsteth.tsx | 25 +- .../components/input-amount/input-amount.tsx | 33 +- .../header/components/header-wallet.tsx | 30 +- .../tx-link-etherscan/tx-link-etherscan.tsx | 9 +- shared/formatters/format-date.tsx | 22 - shared/formatters/format-percent.tsx | 21 - shared/formatters/format-token.tsx | 22 +- shared/formatters/index.ts | 2 - .../controls/token-amount-input-hook-form.tsx | 3 +- .../token-select-hook-form.tsx | 25 +- .../validation/__tests__/validation.tests.ts | 40 +- .../validation/validate-bigint-max.ts | 10 + .../validation/validate-bigint-min.ts | 10 + .../validation/validate-bignumber-max.ts | 11 - .../validation/validate-bignumber-min.ts | 11 - .../validation/validate-ether-amount.ts | 22 +- .../validation/validate-stake-eth.ts | 29 +- .../hook-form/validation/validation-error.ts | 8 - shared/hooks/index.ts | 5 - shared/hooks/txCost.ts | 30 - .../hooks/use-current-static-rpc-provider.ts | 29 - shared/hooks/use-eth-usd.ts | 73 ++- shared/hooks/use-local-storage.ts | 75 +++ .../hooks/use-mainnet-static-rpc-provider.ts | 19 - shared/hooks/use-protocol-fee.ts | 77 +-- shared/hooks/use-stakign-router-contract.ts | 7 - shared/hooks/use-token-address.ts | 52 +- shared/hooks/use-token-max-amount.ts | 22 +- shared/hooks/use-tx-cost-in-usd.ts | 33 + shared/hooks/useApproveOnL1.ts | 116 ---- shared/hooks/useERC20PermitSignature.ts | 124 ---- shared/hooks/useLidoApr.ts | 87 ++- shared/hooks/useLidoStats.ts | 35 +- shared/hooks/useLidoSwr.ts | 17 - shared/hooks/useStakingLimitInfo.ts | 102 +-- shared/hooks/useStethByWsteth.ts | 13 - shared/hooks/useWstethBySteth.ts | 13 - .../tx-stages-basic/tx-stage-pending.tsx | 3 +- .../tx-stages-basic/tx-stage-success.tsx | 3 +- .../tx-stage-amount-operation.tsx | 9 +- ...-stage-operation-succeed-balance-shown.tsx | 13 +- .../tx-stages-parts/success-text.tsx | 3 +- .../tx-stages-parts/tx-amount.tsx | 3 +- shared/wallet/button/button.tsx | 3 +- shared/wallet/wallet-modal/wallet-modal.tsx | 16 +- tsconfig.json | 4 +- utils/__tests__/formatBalance.test.ts | 37 +- utils/apply-gas-limit-ratio.ts | 8 +- utils/check-rpc-url.ts | 72 ++- utils/convert-to-big-number.ts | 8 - utils/etherscan.ts | 36 ++ utils/formatBalance.ts | 16 +- utils/formatBalanceString.ts | 16 - utils/get-bebop-rate.ts | 32 +- utils/get-chain-color.ts | 18 + utils/get-etherscan-address-link.ts | 26 - utils/get-etherscan-tx-link.ts | 18 - utils/get-one-inch-rate.ts | 9 +- utils/get-open-ocean-rate.ts | 47 +- utils/getNFTUrl.ts | 14 +- utils/getTokenDisplayName.ts | 13 +- utils/index.ts | 3 - utils/isContract.ts | 12 - utils/logger.ts | 54 -- utils/open-window.ts | 5 + utils/rpc-error-handler.ts | 31 - utils/swrAbortableMiddleware.ts | 22 - utils/weiToEth.ts | 5 +- utilsApi/contractAddressesMetricsMap.ts | 240 +++---- utilsApi/metrics/startup-metrics.ts | 4 +- utilsApi/nextApiWrappers.ts | 55 +- utilsApi/rpcFactory/validation.ts | 22 +- yarn.lock | 363 +++-------- 263 files changed, 4055 insertions(+), 6244 deletions(-) create mode 100644 .babelrc create mode 100644 abi/aggregator-abi.ts create mode 100644 abi/ens-registry-abi.ts delete mode 100644 abi/ens-registry.abi.json create mode 100644 abi/ens-resolver-abi.ts delete mode 100644 abi/ens-resolver.abi.json delete mode 100644 abi/l2-steth.abi.json delete mode 100644 abi/l2-wstesth.abi.json delete mode 100644 abi/lidoLocator.abi.json create mode 100644 abi/partial-curve-abi.ts create mode 100644 abi/partial-staking-router.ts delete mode 100644 abi/partialCurveAbi.abi.json delete mode 100644 abi/partialStakingRouter.abi.json create mode 100644 consts/contract-addresses.ts create mode 100644 consts/react-query-strategies.ts delete mode 100644 consts/staking-router.ts delete mode 100644 consts/swr-strategies.ts create mode 100644 consts/token-addresses.ts create mode 100644 consts/tokens.ts delete mode 100644 features/rewards/helpers/big.ts delete mode 100644 features/rewards/helpers/index.ts create mode 100644 features/withdrawals/hooks/contract/use-withdrawal-approve.ts delete mode 100644 features/withdrawals/hooks/contract/useLidoShareRate.ts create mode 100644 features/withdrawals/hooks/contract/useTotalSupply.ts delete mode 100644 features/withdrawals/hooks/contract/useWithdrawalsContract.ts create mode 100644 features/withdrawals/hooks/use-withdraw-claim-tx-price.ts create mode 100644 features/withdrawals/hooks/use-withdraw-request-tx-price.ts delete mode 100644 features/withdrawals/hooks/useWithdrawTxPrice.ts delete mode 100644 features/wsteth/wrap/hooks/use-wrap-tx-on-l1-processing.ts rename jest.config.cjs => jest.config.mjs (88%) create mode 100644 modules/web3/consts/index.ts create mode 100644 modules/web3/consts/symbols.ts create mode 100644 modules/web3/consts/tx.ts create mode 100644 modules/web3/consts/units.ts create mode 100644 modules/web3/hooks/use-contract-address.ts delete mode 100644 modules/web3/hooks/use-stETH-by-wstETH-on-l2.ts create mode 100644 modules/web3/hooks/use-stETH-by-wstETH.ts create mode 100644 modules/web3/hooks/use-steth-contract-address.ts delete mode 100644 modules/web3/hooks/use-wstETH-by-stETH-on-l2.ts create mode 100644 modules/web3/hooks/use-wstETH-by-stETH.ts create mode 100644 modules/web3/hooks/use-wsteth-contract-address.ts create mode 100644 modules/web3/utils/apply-round-up-gas-limit.ts delete mode 100644 modules/web3/utils/send-tx/apply-round-up-gas-limit.ts delete mode 100644 modules/web3/utils/send-tx/estimate-gas.ts delete mode 100644 modules/web3/utils/send-tx/get-fee-data.ts delete mode 100644 modules/web3/utils/send-tx/index.ts delete mode 100644 modules/web3/utils/send-tx/send-tx.ts create mode 100644 modules/web3/web3-provider/lido-sdk-l2.tsx delete mode 100644 modules/web3/web3-provider/sdk-legacy.tsx delete mode 100644 shared/formatters/format-date.tsx delete mode 100644 shared/formatters/format-percent.tsx create mode 100644 shared/hook-form/validation/validate-bigint-max.ts create mode 100644 shared/hook-form/validation/validate-bigint-min.ts delete mode 100644 shared/hook-form/validation/validate-bignumber-max.ts delete mode 100644 shared/hook-form/validation/validate-bignumber-min.ts delete mode 100644 shared/hooks/txCost.ts delete mode 100644 shared/hooks/use-current-static-rpc-provider.ts create mode 100644 shared/hooks/use-local-storage.ts delete mode 100644 shared/hooks/use-mainnet-static-rpc-provider.ts delete mode 100644 shared/hooks/use-stakign-router-contract.ts create mode 100644 shared/hooks/use-tx-cost-in-usd.ts delete mode 100644 shared/hooks/useApproveOnL1.ts delete mode 100644 shared/hooks/useERC20PermitSignature.ts delete mode 100644 shared/hooks/useLidoSwr.ts delete mode 100644 shared/hooks/useStethByWsteth.ts delete mode 100644 shared/hooks/useWstethBySteth.ts delete mode 100644 utils/convert-to-big-number.ts create mode 100644 utils/etherscan.ts delete mode 100644 utils/formatBalanceString.ts create mode 100644 utils/get-chain-color.ts delete mode 100644 utils/get-etherscan-address-link.ts delete mode 100644 utils/get-etherscan-tx-link.ts delete mode 100644 utils/isContract.ts delete mode 100644 utils/logger.ts create mode 100644 utils/open-window.ts delete mode 100644 utils/rpc-error-handler.ts delete mode 100644 utils/swrAbortableMiddleware.ts diff --git a/.babelrc b/.babelrc new file mode 100644 index 000000000..5c9d91c2d --- /dev/null +++ b/.babelrc @@ -0,0 +1,15 @@ +{ + "presets": [ + [ + "next/babel", + { + "preset-env": { + "exclude": ["transform-exponentiation-operator"] + } + } + ] + ], + "plugins": [ + "babel-plugin-styled-components" + ] +} diff --git a/Dockerfile b/Dockerfile index bd38b97aa..96d523d80 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,7 @@ COPY package.json yarn.lock ./ RUN yarn install --frozen-lockfile --non-interactive --ignore-scripts && yarn cache clean COPY . . -RUN NODE_NO_BUILD_DYNAMICS=true yarn typechain && yarn build +RUN NODE_NO_BUILD_DYNAMICS=true yarn build # public/runtime is used to inject runtime vars; it should exist and user node should have write access there for it RUN rm -rf /app/public/runtime && mkdir /app/public/runtime && chown node /app/public/runtime diff --git a/abi/aggregator-abi.ts b/abi/aggregator-abi.ts new file mode 100644 index 000000000..73b36489c --- /dev/null +++ b/abi/aggregator-abi.ts @@ -0,0 +1,201 @@ +export const AggregatorAbi = [ + { + inputs: [ + { internalType: 'address', name: '_aggregator', type: 'address' }, + { internalType: 'address', name: '_accessController', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'int256', + name: 'current', + type: 'int256', + }, + { + indexed: true, + internalType: 'uint256', + name: 'roundId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'updatedAt', + type: 'uint256', + }, + ], + name: 'AnswerUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'roundId', + type: 'uint256', + }, + { + indexed: true, + internalType: 'address', + name: 'startedBy', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'startedAt', + type: 'uint256', + }, + ], + name: 'NewRound', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'OwnershipTransferRequested', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + inputs: [], + name: 'acceptOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'accessController', + outputs: [ + { + internalType: 'contract AccessControllerInterface', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'aggregator', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_aggregator', type: 'address' }], + name: 'confirmAggregator', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'description', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_roundId', type: 'uint256' }], + name: 'getAnswer', + outputs: [{ internalType: 'int256', name: '', type: 'int256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint80', name: '_roundId', type: 'uint80' }], + name: 'getRoundData', + outputs: [ + { internalType: 'uint80', name: 'roundId', type: 'uint80' }, + { internalType: 'int256', name: 'answer', type: 'int256' }, + { internalType: 'uint256', name: 'startedAt', type: 'uint256' }, + { internalType: 'uint256', name: 'updatedAt', type: 'uint256' }, + { internalType: 'uint80', name: 'answeredInRound', type: 'uint80' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_roundId', type: 'uint256' }], + name: 'getTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'latestAnswer', + outputs: [{ internalType: 'int256', name: '', type: 'int256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'latestRound', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'latestRoundData', + outputs: [ + { internalType: 'uint80', name: 'roundId', type: 'uint80' }, + { internalType: 'int256', name: 'answer', type: 'int256' }, + { internalType: 'uint256', name: 'startedAt', type: 'uint256' }, + { internalType: 'uint256', name: 'updatedAt', type: 'uint256' }, + { internalType: 'uint80', name: 'answeredInRound', type: 'uint80' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_to', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'version', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, +] as const; diff --git a/abi/ens-registry-abi.ts b/abi/ens-registry-abi.ts new file mode 100644 index 000000000..373733b89 --- /dev/null +++ b/abi/ens-registry-abi.ts @@ -0,0 +1,205 @@ +export const ENSRegistryAbi = [ + { + inputs: [{ internalType: 'contract ENS', name: '_old', type: 'address' }], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'operator', + type: 'address', + }, + { indexed: false, internalType: 'bool', name: 'approved', type: 'bool' }, + ], + name: 'ApprovalForAll', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'bytes32', name: 'node', type: 'bytes32' }, + { + indexed: true, + internalType: 'bytes32', + name: 'label', + type: 'bytes32', + }, + { + indexed: false, + internalType: 'address', + name: 'owner', + type: 'address', + }, + ], + name: 'NewOwner', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'bytes32', name: 'node', type: 'bytes32' }, + { + indexed: false, + internalType: 'address', + name: 'resolver', + type: 'address', + }, + ], + name: 'NewResolver', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'bytes32', name: 'node', type: 'bytes32' }, + { indexed: false, internalType: 'uint64', name: 'ttl', type: 'uint64' }, + ], + name: 'NewTTL', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'bytes32', name: 'node', type: 'bytes32' }, + { + indexed: false, + internalType: 'address', + name: 'owner', + type: 'address', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'operator', type: 'address' }, + ], + name: 'isApprovedForAll', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'old', + outputs: [{ internalType: 'contract ENS', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes32', name: 'node', type: 'bytes32' }], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes32', name: 'node', type: 'bytes32' }], + name: 'recordExists', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes32', name: 'node', type: 'bytes32' }], + name: 'resolver', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'operator', type: 'address' }, + { internalType: 'bool', name: 'approved', type: 'bool' }, + ], + name: 'setApprovalForAll', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'node', type: 'bytes32' }, + { internalType: 'address', name: 'owner', type: 'address' }, + ], + name: 'setOwner', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'node', type: 'bytes32' }, + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'resolver', type: 'address' }, + { internalType: 'uint64', name: 'ttl', type: 'uint64' }, + ], + name: 'setRecord', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'node', type: 'bytes32' }, + { internalType: 'address', name: 'resolver', type: 'address' }, + ], + name: 'setResolver', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'node', type: 'bytes32' }, + { internalType: 'bytes32', name: 'label', type: 'bytes32' }, + { internalType: 'address', name: 'owner', type: 'address' }, + ], + name: 'setSubnodeOwner', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'node', type: 'bytes32' }, + { internalType: 'bytes32', name: 'label', type: 'bytes32' }, + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'resolver', type: 'address' }, + { internalType: 'uint64', name: 'ttl', type: 'uint64' }, + ], + name: 'setSubnodeRecord', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'node', type: 'bytes32' }, + { internalType: 'uint64', name: 'ttl', type: 'uint64' }, + ], + name: 'setTTL', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes32', name: 'node', type: 'bytes32' }], + name: 'ttl', + outputs: [{ internalType: 'uint64', name: '', type: 'uint64' }], + stateMutability: 'view', + type: 'function', + }, +] as const; diff --git a/abi/ens-registry.abi.json b/abi/ens-registry.abi.json deleted file mode 100644 index e7b04b5bd..000000000 --- a/abi/ens-registry.abi.json +++ /dev/null @@ -1,274 +0,0 @@ -[ - { - "inputs": [ - { "internalType": "contract ENS", "name": "_old", "type": "address" } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "ApprovalForAll", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "node", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "label", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "NewOwner", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "node", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "address", - "name": "resolver", - "type": "address" - } - ], - "name": "NewResolver", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "node", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "uint64", - "name": "ttl", - "type": "uint64" - } - ], - "name": "NewTTL", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "node", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "constant": true, - "inputs": [ - { "internalType": "address", "name": "owner", "type": "address" }, - { "internalType": "address", "name": "operator", "type": "address" } - ], - "name": "isApprovedForAll", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "old", - "outputs": [ - { "internalType": "contract ENS", "name": "", "type": "address" } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" } - ], - "name": "owner", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" } - ], - "name": "recordExists", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" } - ], - "name": "resolver", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "internalType": "address", "name": "operator", "type": "address" }, - { "internalType": "bool", "name": "approved", "type": "bool" } - ], - "name": "setApprovalForAll", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" }, - { "internalType": "address", "name": "owner", "type": "address" } - ], - "name": "setOwner", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" }, - { "internalType": "address", "name": "owner", "type": "address" }, - { "internalType": "address", "name": "resolver", "type": "address" }, - { "internalType": "uint64", "name": "ttl", "type": "uint64" } - ], - "name": "setRecord", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" }, - { "internalType": "address", "name": "resolver", "type": "address" } - ], - "name": "setResolver", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" }, - { "internalType": "bytes32", "name": "label", "type": "bytes32" }, - { "internalType": "address", "name": "owner", "type": "address" } - ], - "name": "setSubnodeOwner", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" }, - { "internalType": "bytes32", "name": "label", "type": "bytes32" }, - { "internalType": "address", "name": "owner", "type": "address" }, - { "internalType": "address", "name": "resolver", "type": "address" }, - { "internalType": "uint64", "name": "ttl", "type": "uint64" } - ], - "name": "setSubnodeRecord", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" }, - { "internalType": "uint64", "name": "ttl", "type": "uint64" } - ], - "name": "setTTL", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" } - ], - "name": "ttl", - "outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }], - "payable": false, - "stateMutability": "view", - "type": "function" - } -] diff --git a/abi/ens-resolver-abi.ts b/abi/ens-resolver-abi.ts new file mode 100644 index 000000000..6139f31f6 --- /dev/null +++ b/abi/ens-resolver-abi.ts @@ -0,0 +1,190 @@ +export const ENSResolverAbi = [ + { + inputs: [{ internalType: 'contract ENS', name: '_ens', type: 'address' }], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'bytes32', name: 'node', type: 'bytes32' }, + { + indexed: true, + internalType: 'uint256', + name: 'contentType', + type: 'uint256', + }, + ], + name: 'ABIChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'bytes32', name: 'node', type: 'bytes32' }, + { indexed: false, internalType: 'address', name: 'a', type: 'address' }, + ], + name: 'AddrChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'bytes32', name: 'node', type: 'bytes32' }, + { + indexed: false, + internalType: 'uint256', + name: 'coinType', + type: 'uint256', + }, + { + indexed: false, + internalType: 'bytes', + name: 'newAddress', + type: 'bytes', + }, + ], + name: 'AddressChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'bytes32', name: 'node', type: 'bytes32' }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'target', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'isAuthorised', + type: 'bool', + }, + ], + name: 'AuthorisationChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'bytes32', name: 'node', type: 'bytes32' }, + { indexed: false, internalType: 'bytes', name: 'hash', type: 'bytes' }, + ], + name: 'ContenthashChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'bytes32', name: 'node', type: 'bytes32' }, + { indexed: false, internalType: 'bytes', name: 'name', type: 'bytes' }, + { + indexed: false, + internalType: 'uint16', + name: 'resource', + type: 'uint16', + }, + { indexed: false, internalType: 'bytes', name: 'record', type: 'bytes' }, + ], + name: 'DNSRecordChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'bytes32', name: 'node', type: 'bytes32' }, + { indexed: false, internalType: 'bytes', name: 'name', type: 'bytes' }, + { + indexed: false, + internalType: 'uint16', + name: 'resource', + type: 'uint16', + }, + ], + name: 'DNSRecordDeleted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'bytes32', name: 'node', type: 'bytes32' }, + ], + name: 'DNSZoneCleared', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'bytes32', name: 'node', type: 'bytes32' }, + { + indexed: true, + internalType: 'bytes4', + name: 'interfaceID', + type: 'bytes4', + }, + { + indexed: false, + internalType: 'address', + name: 'implementer', + type: 'address', + }, + ], + name: 'InterfaceChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'bytes32', name: 'node', type: 'bytes32' }, + { indexed: false, internalType: 'string', name: 'name', type: 'string' }, + ], + name: 'NameChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'bytes32', name: 'node', type: 'bytes32' }, + { indexed: false, internalType: 'bytes32', name: 'x', type: 'bytes32' }, + { indexed: false, internalType: 'bytes32', name: 'y', type: 'bytes32' }, + ], + name: 'PubkeyChanged', + type: 'event', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'node', type: 'bytes32' }, + { internalType: 'string', name: 'key', type: 'string' }, + ], + name: 'text', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'node', type: 'bytes32' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + ], + name: 'setDNSRecords', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes4', name: 'interfaceID', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'pure', + type: 'function', + }, +] as const; diff --git a/abi/ens-resolver.abi.json b/abi/ens-resolver.abi.json deleted file mode 100644 index 2176b5edb..000000000 --- a/abi/ens-resolver.abi.json +++ /dev/null @@ -1,585 +0,0 @@ -[ - { - "inputs": [ - { "internalType": "contract ENS", "name": "_ens", "type": "address" } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "node", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "contentType", - "type": "uint256" - } - ], - "name": "ABIChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "node", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "address", - "name": "a", - "type": "address" - } - ], - "name": "AddrChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "node", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "coinType", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "newAddress", - "type": "bytes" - } - ], - "name": "AddressChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "node", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "isAuthorised", - "type": "bool" - } - ], - "name": "AuthorisationChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "node", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "hash", - "type": "bytes" - } - ], - "name": "ContenthashChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "node", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "name", - "type": "bytes" - }, - { - "indexed": false, - "internalType": "uint16", - "name": "resource", - "type": "uint16" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "record", - "type": "bytes" - } - ], - "name": "DNSRecordChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "node", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "name", - "type": "bytes" - }, - { - "indexed": false, - "internalType": "uint16", - "name": "resource", - "type": "uint16" - } - ], - "name": "DNSRecordDeleted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "node", - "type": "bytes32" - } - ], - "name": "DNSZoneCleared", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "node", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes4", - "name": "interfaceID", - "type": "bytes4" - }, - { - "indexed": false, - "internalType": "address", - "name": "implementer", - "type": "address" - } - ], - "name": "InterfaceChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "node", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "string", - "name": "name", - "type": "string" - } - ], - "name": "NameChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "node", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "x", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "y", - "type": "bytes32" - } - ], - "name": "PubkeyChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "node", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "string", - "name": "indexedKey", - "type": "string" - }, - { - "indexed": false, - "internalType": "string", - "name": "key", - "type": "string" - } - ], - "name": "TextChanged", - "type": "event" - }, - { - "constant": true, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" }, - { "internalType": "uint256", "name": "contentTypes", "type": "uint256" } - ], - "name": "ABI", - "outputs": [ - { "internalType": "uint256", "name": "", "type": "uint256" }, - { "internalType": "bytes", "name": "", "type": "bytes" } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" } - ], - "name": "addr", - "outputs": [ - { "internalType": "address payable", "name": "", "type": "address" } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" }, - { "internalType": "uint256", "name": "coinType", "type": "uint256" } - ], - "name": "addr", - "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { "internalType": "bytes32", "name": "", "type": "bytes32" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" } - ], - "name": "authorisations", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" } - ], - "name": "clearDNSZone", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" } - ], - "name": "contenthash", - "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" }, - { "internalType": "bytes32", "name": "name", "type": "bytes32" }, - { "internalType": "uint16", "name": "resource", "type": "uint16" } - ], - "name": "dnsRecord", - "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" }, - { "internalType": "bytes32", "name": "name", "type": "bytes32" } - ], - "name": "hasDNSRecords", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" }, - { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" } - ], - "name": "interfaceImplementer", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "internalType": "bytes[]", "name": "data", "type": "bytes[]" } - ], - "name": "multicall", - "outputs": [ - { "internalType": "bytes[]", "name": "results", "type": "bytes[]" } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" } - ], - "name": "name", - "outputs": [{ "internalType": "string", "name": "", "type": "string" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" } - ], - "name": "pubkey", - "outputs": [ - { "internalType": "bytes32", "name": "x", "type": "bytes32" }, - { "internalType": "bytes32", "name": "y", "type": "bytes32" } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" }, - { "internalType": "uint256", "name": "contentType", "type": "uint256" }, - { "internalType": "bytes", "name": "data", "type": "bytes" } - ], - "name": "setABI", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" }, - { "internalType": "uint256", "name": "coinType", "type": "uint256" }, - { "internalType": "bytes", "name": "a", "type": "bytes" } - ], - "name": "setAddr", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" }, - { "internalType": "address", "name": "a", "type": "address" } - ], - "name": "setAddr", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" }, - { "internalType": "address", "name": "target", "type": "address" }, - { "internalType": "bool", "name": "isAuthorised", "type": "bool" } - ], - "name": "setAuthorisation", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" }, - { "internalType": "bytes", "name": "hash", "type": "bytes" } - ], - "name": "setContenthash", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" }, - { "internalType": "bytes", "name": "data", "type": "bytes" } - ], - "name": "setDNSRecords", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" }, - { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }, - { "internalType": "address", "name": "implementer", "type": "address" } - ], - "name": "setInterface", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" }, - { "internalType": "string", "name": "name", "type": "string" } - ], - "name": "setName", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" }, - { "internalType": "bytes32", "name": "x", "type": "bytes32" }, - { "internalType": "bytes32", "name": "y", "type": "bytes32" } - ], - "name": "setPubkey", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" }, - { "internalType": "string", "name": "key", "type": "string" }, - { "internalType": "string", "name": "value", "type": "string" } - ], - "name": "setText", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" } - ], - "name": "supportsInterface", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "payable": false, - "stateMutability": "pure", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { "internalType": "bytes32", "name": "node", "type": "bytes32" }, - { "internalType": "string", "name": "key", "type": "string" } - ], - "name": "text", - "outputs": [{ "internalType": "string", "name": "", "type": "string" }], - "payable": false, - "stateMutability": "view", - "type": "function" - } -] diff --git a/abi/l2-steth.abi.json b/abi/l2-steth.abi.json deleted file mode 100644 index 247cdc8f4..000000000 --- a/abi/l2-steth.abi.json +++ /dev/null @@ -1,438 +0,0 @@ -[ - { - "inputs": [ - { "internalType": "string", "name": "name_", "type": "string" }, - { "internalType": "string", "name": "symbol_", "type": "string" }, - { "internalType": "string", "name": "version_", "type": "string" }, - { "internalType": "uint8", "name": "decimals_", "type": "uint8" }, - { - "internalType": "address", - "name": "tokenToWrapFrom_", - "type": "address" - }, - { - "internalType": "address", - "name": "tokenRateOracle_", - "type": "address" - }, - { "internalType": "address", "name": "bridge_", "type": "address" } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { "inputs": [], "name": "ErrorAccountIsZeroAddress", "type": "error" }, - { "inputs": [], "name": "ErrorDeadlineExpired", "type": "error" }, - { "inputs": [], "name": "ErrorInvalidSignature", "type": "error" }, - { "inputs": [], "name": "ErrorNameIsEmpty", "type": "error" }, - { "inputs": [], "name": "ErrorNotBridge", "type": "error" }, - { "inputs": [], "name": "ErrorNotEnoughAllowance", "type": "error" }, - { "inputs": [], "name": "ErrorNotEnoughBalance", "type": "error" }, - { "inputs": [], "name": "ErrorSymbolIsEmpty", "type": "error" }, - { "inputs": [], "name": "ErrorTransferToRebasableContract", "type": "error" }, - { - "inputs": [], - "name": "ErrorZeroAddressL2ERC20TokenBridge", - "type": "error" - }, - { "inputs": [], "name": "ErrorZeroAddressTokenRateOracle", "type": "error" }, - { "inputs": [], "name": "ErrorZeroAddressTokenToWrapFrom", "type": "error" }, - { "inputs": [], "name": "ErrorZeroDecimals", "type": "error" }, - { "inputs": [], "name": "ErrorZeroSharesUnwrap", "type": "error" }, - { "inputs": [], "name": "ErrorZeroSharesWrap", "type": "error" }, - { "inputs": [], "name": "ErrorZeroTokensUnwrap", "type": "error" }, - { "inputs": [], "name": "InvalidContractVersionIncrement", "type": "error" }, - { "inputs": [], "name": "NonZeroContractVersionOnInit", "type": "error" }, - { - "inputs": [ - { "internalType": "uint256", "name": "expected", "type": "uint256" }, - { "internalType": "uint256", "name": "received", "type": "uint256" } - ], - "name": "UnexpectedContractVersion", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "version", - "type": "uint256" - } - ], - "name": "ContractVersionSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "sharesValue", - "type": "uint256" - } - ], - "name": "TransferShares", - "type": "event" - }, - { - "inputs": [], - "name": "DOMAIN_SEPARATOR", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "L2_ERC20_TOKEN_BRIDGE", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "TOKEN_RATE_ORACLE", - "outputs": [ - { - "internalType": "contract ITokenRateOracle", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "TOKEN_RATE_ORACLE_DECIMALS", - "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "TOKEN_TO_WRAP_FROM", - "outputs": [ - { "internalType": "contract IERC20", "name": "", "type": "address" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "owner", "type": "address" }, - { "internalType": "address", "name": "spender", "type": "address" } - ], - "name": "allowance", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "spender_", "type": "address" }, - { "internalType": "uint256", "name": "amount_", "type": "uint256" } - ], - "name": "approve", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "account_", "type": "address" } - ], - "name": "balanceOf", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "account_", "type": "address" }, - { "internalType": "uint256", "name": "tokenAmount_", "type": "uint256" } - ], - "name": "bridgeUnwrap", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "account_", "type": "address" }, - { "internalType": "uint256", "name": "sharesAmount_", "type": "uint256" } - ], - "name": "bridgeWrap", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "decimals", - "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "eip712Domain", - "outputs": [ - { "internalType": "bytes1", "name": "fields", "type": "bytes1" }, - { "internalType": "string", "name": "name", "type": "string" }, - { "internalType": "string", "name": "version", "type": "string" }, - { "internalType": "uint256", "name": "chainId", "type": "uint256" }, - { - "internalType": "address", - "name": "verifyingContract", - "type": "address" - }, - { "internalType": "bytes32", "name": "salt", "type": "bytes32" }, - { "internalType": "uint256[]", "name": "extensions", "type": "uint256[]" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getContractVersion", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "tokenAmount_", "type": "uint256" } - ], - "name": "getSharesByTokens", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "sharesAmount_", "type": "uint256" } - ], - "name": "getTokensByShares", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getTotalShares", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "string", "name": "name_", "type": "string" }, - { "internalType": "string", "name": "symbol_", "type": "string" }, - { "internalType": "string", "name": "version_", "type": "string" } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [{ "internalType": "string", "name": "", "type": "string" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "owner", "type": "address" } - ], - "name": "nonces", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "owner_", "type": "address" }, - { "internalType": "address", "name": "spender_", "type": "address" }, - { "internalType": "uint256", "name": "value_", "type": "uint256" }, - { "internalType": "uint256", "name": "deadline_", "type": "uint256" }, - { "internalType": "bytes", "name": "signature_", "type": "bytes" } - ], - "name": "permit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "owner_", "type": "address" }, - { "internalType": "address", "name": "spender_", "type": "address" }, - { "internalType": "uint256", "name": "value_", "type": "uint256" }, - { "internalType": "uint256", "name": "deadline_", "type": "uint256" }, - { "internalType": "uint8", "name": "v_", "type": "uint8" }, - { "internalType": "bytes32", "name": "r_", "type": "bytes32" }, - { "internalType": "bytes32", "name": "s_", "type": "bytes32" } - ], - "name": "permit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "account_", "type": "address" } - ], - "name": "sharesOf", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [{ "internalType": "string", "name": "", "type": "string" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "to_", "type": "address" }, - { "internalType": "uint256", "name": "amount_", "type": "uint256" } - ], - "name": "transfer", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "from_", "type": "address" }, - { "internalType": "address", "name": "to_", "type": "address" }, - { "internalType": "uint256", "name": "amount_", "type": "uint256" } - ], - "name": "transferFrom", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "recipient_", "type": "address" }, - { "internalType": "uint256", "name": "sharesAmount_", "type": "uint256" } - ], - "name": "transferShares", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "sender_", "type": "address" }, - { "internalType": "address", "name": "recipient_", "type": "address" }, - { "internalType": "uint256", "name": "sharesAmount_", "type": "uint256" } - ], - "name": "transferSharesFrom", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "tokenAmount_", "type": "uint256" } - ], - "name": "unwrap", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "sharesAmount_", "type": "uint256" } - ], - "name": "unwrapShares", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "sharesAmount_", "type": "uint256" } - ], - "name": "wrap", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "nonpayable", - "type": "function" - } -] diff --git a/abi/l2-wstesth.abi.json b/abi/l2-wstesth.abi.json deleted file mode 100644 index 518cc00c8..000000000 --- a/abi/l2-wstesth.abi.json +++ /dev/null @@ -1,296 +0,0 @@ -[ - { - "inputs": [ - { "internalType": "string", "name": "name_", "type": "string" }, - { "internalType": "string", "name": "symbol_", "type": "string" }, - { "internalType": "string", "name": "version_", "type": "string" }, - { "internalType": "uint8", "name": "decimals_", "type": "uint8" }, - { "internalType": "address", "name": "bridge_", "type": "address" } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { "inputs": [], "name": "ErrorAccountIsZeroAddress", "type": "error" }, - { "inputs": [], "name": "ErrorDeadlineExpired", "type": "error" }, - { "inputs": [], "name": "ErrorInvalidSignature", "type": "error" }, - { - "inputs": [], - "name": "ErrorMetadataIsAlreadyInitialized", - "type": "error" - }, - { "inputs": [], "name": "ErrorMetadataIsNotInitialized", "type": "error" }, - { "inputs": [], "name": "ErrorNameIsEmpty", "type": "error" }, - { "inputs": [], "name": "ErrorNotBridge", "type": "error" }, - { "inputs": [], "name": "ErrorNotEnoughAllowance", "type": "error" }, - { "inputs": [], "name": "ErrorNotEnoughBalance", "type": "error" }, - { "inputs": [], "name": "ErrorSymbolIsEmpty", "type": "error" }, - { "inputs": [], "name": "ErrorZeroAddressBridge", "type": "error" }, - { "inputs": [], "name": "ErrorZeroDecimals", "type": "error" }, - { "inputs": [], "name": "InvalidContractVersionIncrement", "type": "error" }, - { "inputs": [], "name": "NonZeroContractVersionOnInit", "type": "error" }, - { - "inputs": [ - { "internalType": "uint256", "name": "expected", "type": "uint256" }, - { "internalType": "uint256", "name": "received", "type": "uint256" } - ], - "name": "UnexpectedContractVersion", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "version", - "type": "uint256" - } - ], - "name": "ContractVersionSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "inputs": [], - "name": "DOMAIN_SEPARATOR", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" } - ], - "name": "allowance", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "spender_", "type": "address" }, - { "internalType": "uint256", "name": "amount_", "type": "uint256" } - ], - "name": "approve", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [{ "internalType": "address", "name": "", "type": "address" }], - "name": "balanceOf", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "bridge", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "account_", "type": "address" }, - { "internalType": "uint256", "name": "amount_", "type": "uint256" } - ], - "name": "bridgeBurn", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "account_", "type": "address" }, - { "internalType": "uint256", "name": "amount_", "type": "uint256" } - ], - "name": "bridgeMint", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "decimals", - "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "eip712Domain", - "outputs": [ - { "internalType": "bytes1", "name": "fields", "type": "bytes1" }, - { "internalType": "string", "name": "name", "type": "string" }, - { "internalType": "string", "name": "version", "type": "string" }, - { "internalType": "uint256", "name": "chainId", "type": "uint256" }, - { - "internalType": "address", - "name": "verifyingContract", - "type": "address" - }, - { "internalType": "bytes32", "name": "salt", "type": "bytes32" }, - { "internalType": "uint256[]", "name": "extensions", "type": "uint256[]" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "string", "name": "name_", "type": "string" }, - { "internalType": "string", "name": "version_", "type": "string" } - ], - "name": "finalizeUpgrade_v2", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "getContractVersion", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "string", "name": "name_", "type": "string" }, - { "internalType": "string", "name": "symbol_", "type": "string" }, - { "internalType": "string", "name": "version_", "type": "string" } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [{ "internalType": "string", "name": "", "type": "string" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "owner", "type": "address" } - ], - "name": "nonces", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "owner_", "type": "address" }, - { "internalType": "address", "name": "spender_", "type": "address" }, - { "internalType": "uint256", "name": "value_", "type": "uint256" }, - { "internalType": "uint256", "name": "deadline_", "type": "uint256" }, - { "internalType": "bytes", "name": "signature_", "type": "bytes" } - ], - "name": "permit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "owner_", "type": "address" }, - { "internalType": "address", "name": "spender_", "type": "address" }, - { "internalType": "uint256", "name": "value_", "type": "uint256" }, - { "internalType": "uint256", "name": "deadline_", "type": "uint256" }, - { "internalType": "uint8", "name": "v_", "type": "uint8" }, - { "internalType": "bytes32", "name": "r_", "type": "bytes32" }, - { "internalType": "bytes32", "name": "s_", "type": "bytes32" } - ], - "name": "permit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [{ "internalType": "string", "name": "", "type": "string" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "to_", "type": "address" }, - { "internalType": "uint256", "name": "amount_", "type": "uint256" } - ], - "name": "transfer", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "from_", "type": "address" }, - { "internalType": "address", "name": "to_", "type": "address" }, - { "internalType": "uint256", "name": "amount_", "type": "uint256" } - ], - "name": "transferFrom", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "nonpayable", - "type": "function" - } -] diff --git a/abi/lidoLocator.abi.json b/abi/lidoLocator.abi.json deleted file mode 100644 index 8cfca3276..000000000 --- a/abi/lidoLocator.abi.json +++ /dev/null @@ -1,201 +0,0 @@ -[ - { - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "accountingOracle", - "type": "address" - }, - { - "internalType": "address", - "name": "depositSecurityModule", - "type": "address" - }, - { - "internalType": "address", - "name": "elRewardsVault", - "type": "address" - }, - { - "internalType": "address", - "name": "legacyOracle", - "type": "address" - }, - { "internalType": "address", "name": "lido", "type": "address" }, - { - "internalType": "address", - "name": "oracleReportSanityChecker", - "type": "address" - }, - { - "internalType": "address", - "name": "postTokenRebaseReceiver", - "type": "address" - }, - { "internalType": "address", "name": "burner", "type": "address" }, - { - "internalType": "address", - "name": "stakingRouter", - "type": "address" - }, - { "internalType": "address", "name": "treasury", "type": "address" }, - { - "internalType": "address", - "name": "validatorsExitBusOracle", - "type": "address" - }, - { - "internalType": "address", - "name": "withdrawalQueue", - "type": "address" - }, - { - "internalType": "address", - "name": "withdrawalVault", - "type": "address" - }, - { - "internalType": "address", - "name": "oracleDaemonConfig", - "type": "address" - } - ], - "internalType": "struct LidoLocator.Config", - "name": "_config", - "type": "tuple" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { "inputs": [], "name": "ZeroAddress", "type": "error" }, - { - "inputs": [], - "name": "accountingOracle", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "burner", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "coreComponents", - "outputs": [ - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "depositSecurityModule", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "elRewardsVault", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "legacyOracle", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "lido", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "oracleDaemonConfig", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "oracleReportComponentsForLido", - "outputs": [ - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "address", "name": "", "type": "address" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "oracleReportSanityChecker", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "postTokenRebaseReceiver", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "stakingRouter", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "treasury", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "validatorsExitBusOracle", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "withdrawalQueue", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "withdrawalVault", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - } -] diff --git a/abi/partial-curve-abi.ts b/abi/partial-curve-abi.ts new file mode 100644 index 000000000..1f78f2ca8 --- /dev/null +++ b/abi/partial-curve-abi.ts @@ -0,0 +1,14 @@ +export const PartialCurveAbi = [ + { + constant: true, + inputs: [ + { name: 'i', type: 'int128' }, + { name: 'j', type: 'int128' }, + { name: 'dx', type: 'uint256' }, + ], + name: 'get_dy', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, +] as const; diff --git a/abi/partial-staking-router.ts b/abi/partial-staking-router.ts new file mode 100644 index 000000000..f44a49f9a --- /dev/null +++ b/abi/partial-staking-router.ts @@ -0,0 +1,110 @@ +export const PartialStakingRouterAbi = [ + { + inputs: [ + { internalType: 'address', name: '_depositContract', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'stakingModuleId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'stakingModuleFee', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'treasuryFee', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'setBy', + type: 'address', + }, + ], + name: 'StakingModuleFeesSet', + type: 'event', + }, + { + inputs: [], + name: 'FEE_PRECISION_POINTS', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'TOTAL_BASIS_POINTS', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getLido', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getStakingFeeAggregateDistribution', + outputs: [ + { internalType: 'uint96', name: 'modulesFee', type: 'uint96' }, + { internalType: 'uint96', name: 'treasuryFee', type: 'uint96' }, + { internalType: 'uint256', name: 'basePrecision', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getStakingFeeAggregateDistributionE4Precision', + outputs: [ + { internalType: 'uint16', name: 'modulesFee', type: 'uint16' }, + { internalType: 'uint16', name: 'treasuryFee', type: 'uint16' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getStakingRewardsDistribution', + outputs: [ + { internalType: 'address[]', name: 'recipients', type: 'address[]' }, + { + internalType: 'uint256[]', + name: 'stakingModuleIds', + type: 'uint256[]', + }, + { internalType: 'uint96[]', name: 'stakingModuleFees', type: 'uint96[]' }, + { internalType: 'uint96', name: 'totalFee', type: 'uint96' }, + { internalType: 'uint256', name: 'precisionPoints', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getTotalFeeE4Precision', + outputs: [{ internalType: 'uint16', name: 'totalFee', type: 'uint16' }], + stateMutability: 'view', + type: 'function', + }, + { + stateMutability: 'payable', + type: 'receive', + }, +] as const; diff --git a/abi/partialCurveAbi.abi.json b/abi/partialCurveAbi.abi.json deleted file mode 100644 index 7bac8cdaa..000000000 --- a/abi/partialCurveAbi.abi.json +++ /dev/null @@ -1,13 +0,0 @@ -[ - { - "name": "get_dy", - "outputs": [{ "type": "uint256", "name": "" }], - "inputs": [ - { "type": "int128", "name": "i" }, - { "type": "int128", "name": "j" }, - { "type": "uint256", "name": "dx" } - ], - "stateMutability": "view", - "type": "function" - } -] diff --git a/abi/partialStakingRouter.abi.json b/abi/partialStakingRouter.abi.json deleted file mode 100644 index 3d98c089e..000000000 --- a/abi/partialStakingRouter.abi.json +++ /dev/null @@ -1,125 +0,0 @@ -[ - { - "inputs": [ - { - "internalType": "address", - "name": "_depositContract", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "stakingModuleId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "stakingModuleFee", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "treasuryFee", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address", - "name": "setBy", - "type": "address" - } - ], - "name": "StakingModuleFeesSet", - "type": "event" - }, - { - "inputs": [], - "name": "FEE_PRECISION_POINTS", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "TOTAL_BASIS_POINTS", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getLido", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getStakingFeeAggregateDistribution", - "outputs": [ - { "internalType": "uint96", "name": "modulesFee", "type": "uint96" }, - { "internalType": "uint96", "name": "treasuryFee", "type": "uint96" }, - { "internalType": "uint256", "name": "basePrecision", "type": "uint256" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getStakingFeeAggregateDistributionE4Precision", - "outputs": [ - { "internalType": "uint16", "name": "modulesFee", "type": "uint16" }, - { "internalType": "uint16", "name": "treasuryFee", "type": "uint16" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getStakingRewardsDistribution", - "outputs": [ - { - "internalType": "address[]", - "name": "recipients", - "type": "address[]" - }, - { - "internalType": "uint256[]", - "name": "stakingModuleIds", - "type": "uint256[]" - }, - { - "internalType": "uint96[]", - "name": "stakingModuleFees", - "type": "uint96[]" - }, - { "internalType": "uint96", "name": "totalFee", "type": "uint96" }, - { - "internalType": "uint256", - "name": "precisionPoints", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getTotalFeeE4Precision", - "outputs": [ - { "internalType": "uint16", "name": "totalFee", "type": "uint16" } - ], - "stateMutability": "view", - "type": "function" - }, - { "stateMutability": "payable", "type": "receive" } -] diff --git a/config/external-config/types.ts b/config/external-config/types.ts index f63aaaa5d..6131ad22e 100644 --- a/config/external-config/types.ts +++ b/config/external-config/types.ts @@ -1,5 +1,5 @@ +import type { UseQueryResult } from '@tanstack/react-query'; import type { DexWithdrawalApi } from 'features/withdrawals/request/withdrawal-rates'; -import { SWRResponse } from 'swr'; export type Manifest = Record; @@ -20,5 +20,5 @@ export type ManifestConfig = { export type ExternalConfig = Omit & ManifestConfig & { - fetchMeta: SWRResponse; + fetchMeta: UseQueryResult; }; diff --git a/config/external-config/use-external-config-context.ts b/config/external-config/use-external-config-context.ts index dc3dceca0..29d25bea6 100644 --- a/config/external-config/use-external-config-context.ts +++ b/config/external-config/use-external-config-context.ts @@ -1,59 +1,61 @@ import { useMemo } from 'react'; -import useSWR from 'swr'; +import { useQuery } from '@tanstack/react-query'; -import { STRATEGY_LAZY } from 'consts/swr-strategies'; -import { getConfig } from '../get-config'; -import { standardFetcher } from 'utils/standardFetcher'; +import { config } from 'config'; +import { STRATEGY_LAZY } from 'consts/react-query-strategies'; import { IPFS_MANIFEST_URL } from 'consts/external-links'; +import { standardFetcher } from 'utils/standardFetcher'; + import { getBackwardCompatibleConfig, isManifestEntryValid, useFallbackManifestEntry, } from './utils'; - import type { ExternalConfig, ManifestEntry } from './types'; -const onFetchError = (error: unknown) => { - console.warn( - '[useExternalConfigContext] while fetching external config:', - error, - ); -}; - export const useExternalConfigContext = ( prefetchedManifest?: unknown, ): ExternalConfig => { - const { defaultChain } = getConfig(); + const defaultChain = config.defaultChain; const fallbackData = useFallbackManifestEntry( prefetchedManifest, defaultChain, ); - const swr = useSWR( - ['swr:external-config', defaultChain], - async () => { - const result = await standardFetcher>( - IPFS_MANIFEST_URL, - { - headers: { Accept: 'application/json' }, - }, - ); - const entry = result[defaultChain.toString()]; - if (isManifestEntryValid(entry)) return entry; - throw new Error( - '[useExternalConfigContext] received invalid manifest', - result, - ); - }, - { - ...STRATEGY_LAZY, - onError: onFetchError, + const queryResult = useQuery({ + queryKey: ['external-config', defaultChain], + ...STRATEGY_LAZY, + enabled: !!defaultChain, + queryFn: async () => { + try { + const result = await standardFetcher>( + IPFS_MANIFEST_URL, + { + headers: { Accept: 'application/json' }, + }, + ); + + const entry = result[defaultChain.toString()]; + if (isManifestEntryValid(entry)) return entry; + + throw new Error( + '[useExternalConfig] received invalid manifest', + result, + ); + } catch (err) { + console.warn( + '[useExternalConfigContext] while fetching external config:', + err, + ); + // This line is necessary so that useQuery can handle the error and return undefined + throw err; + } }, - ); + }); return useMemo(() => { - const { config, ...rest } = swr.data ?? fallbackData; + const { config, ...rest } = queryResult.data ?? fallbackData; const cleanConfig = getBackwardCompatibleConfig(config); - return { ...cleanConfig, ...rest, fetchMeta: swr }; - }, [swr, fallbackData]); + return { ...cleanConfig, ...rest, fetchMeta: queryResult }; + }, [queryResult, fallbackData]); }; diff --git a/config/feature-flags/context-hook.tsx b/config/feature-flags/context-hook.tsx index 78eb24fc0..6f27f18e3 100644 --- a/config/feature-flags/context-hook.tsx +++ b/config/feature-flags/context-hook.tsx @@ -1,5 +1,6 @@ import { useMemo, useState, useCallback } from 'react'; -import { useLocalStorage } from '@lido-sdk/react'; + +import { useLocalStorage } from 'shared/hooks/use-local-storage'; import { getFeatureFlagsDefault } from './utils'; import { FeatureFlagsType } from './types'; diff --git a/config/groups/stake.ts b/config/groups/stake.ts index ebebb908a..4b4f73d75 100644 --- a/config/groups/stake.ts +++ b/config/groups/stake.ts @@ -1,6 +1,3 @@ -import { BigNumber } from 'ethers'; -import { parseEther } from '@ethersproject/units'; - import { StakeSwapDiscountIntegrationKey } from 'features/stake/swap-discount-banner'; import { IPFS_REFERRAL_ADDRESS } from './ipfs'; @@ -12,14 +9,11 @@ import { preConfig } from '../get-preconfig'; export const PRECISION = 10 ** 6; -// how much to leave out on user balance when max is pressed -export const BALANCE_PADDING = parseEther('0.01'); - export const SUBMIT_EXTRA_GAS_TRANSACTION_RATIO = 1.05; export const STETH_SUBMIT_GAS_LIMIT_DEFAULT = 90000; -export const STAKE_GASLIMIT_FALLBACK = BigNumber.from( +export const STAKE_GASLIMIT_FALLBACK = BigInt( Math.floor( STETH_SUBMIT_GAS_LIMIT_DEFAULT * SUBMIT_EXTRA_GAS_TRANSACTION_RATIO, ), diff --git a/config/groups/web3.ts b/config/groups/web3.ts index 57f3bdf32..c2752b838 100644 --- a/config/groups/web3.ts +++ b/config/groups/web3.ts @@ -1,5 +1,3 @@ -import { parseEther } from '@ethersproject/units'; - // interval in ms for RPC event polling for token balance and tx updates export const PROVIDER_POLLING_INTERVAL = 12_000; // how long in ms to wait for RPC batching(multicall and provider) @@ -20,5 +18,3 @@ export const PROVIDER_MAX_BATCH = 20; // on Mainnet, Holesky, Sepolia, Optimism, Optimism Sepolia export const ESTIMATE_ACCOUNT = '0x87c0e047F4e4D3e289A56a36570D4CB957A37Ef1'; - -export const ESTIMATE_AMOUNT = parseEther('0.001'); diff --git a/config/groups/withdrawal-queue-estimate.ts b/config/groups/withdrawal-queue-estimate.ts index a69fc6757..40cca5aea 100644 --- a/config/groups/withdrawal-queue-estimate.ts +++ b/config/groups/withdrawal-queue-estimate.ts @@ -1,14 +1,11 @@ -import { BigNumber } from 'ethers'; - // fallback gas limits per 1 withdraw request -export const WITHDRAWAL_QUEUE_REQUEST_STETH_PERMIT_GAS_LIMIT_DEFAULT = - BigNumber.from(255350); +export const WITHDRAWAL_QUEUE_REQUEST_STETH_PERMIT_GAS_LIMIT_DEFAULT = 255_350n; export const WITHDRAWAL_QUEUE_REQUEST_WSTETH_PERMIT_GAS_LIMIT_DEFAULT = - BigNumber.from(312626); + 312_626n; export const WITHDRAWAL_QUEUE_REQUEST_STETH_APPROVED_GAS_LIMIT_DEFAULT = - BigNumber.from(228163); + 228_163n; export const WITHDRAWAL_QUEUE_REQUEST_WSTETH_APPROVED_GAS_LIMIT_DEFAULT = - BigNumber.from(280096); + 280_096n; -export const WITHDRAWAL_QUEUE_CLAIM_GAS_LIMIT_DEFAULT = BigNumber.from(89818); +export const WITHDRAWAL_QUEUE_CLAIM_GAS_LIMIT_DEFAULT = 89_818n; diff --git a/config/rpc/index.ts b/config/rpc/index.ts index b1d07f47a..7b3ce3e09 100644 --- a/config/rpc/index.ts +++ b/config/rpc/index.ts @@ -1,6 +1,5 @@ import { useCallback } from 'react'; import invariant from 'tiny-invariant'; -import { useSDK } from '@lido-sdk/react'; import { CHAINS } from 'consts/chains'; @@ -40,8 +39,3 @@ export const useGetRpcUrlByChainId = () => { [userConfig], ); }; - -export const useRpcUrl = () => { - const { chainId } = useSDK(); - return useGetRpcUrlByChainId()(chainId as number); -}; diff --git a/config/user-config/context-hook.tsx b/config/user-config/context-hook.tsx index b6d535b8c..03dd8fc75 100644 --- a/config/user-config/context-hook.tsx +++ b/config/user-config/context-hook.tsx @@ -1,8 +1,7 @@ import { useMemo, useState, useCallback } from 'react'; -import { useLocalStorage } from '@lido-sdk/react'; - import { CHAINS } from 'consts/chains'; +import { useLocalStorage } from 'shared/hooks/use-local-storage'; import { getUserConfigDefault } from './utils'; import { UserConfigDefaultType } from './types'; diff --git a/consts/aggregator.ts b/consts/aggregator.ts index 5da55d340..bf3209838 100644 --- a/consts/aggregator.ts +++ b/consts/aggregator.ts @@ -1,9 +1,10 @@ -import { CHAINS } from '@lido-sdk/constants'; +import type { Address } from 'viem'; import invariant from 'tiny-invariant'; +import { CHAINS } from '@lidofinance/lido-ethereum-sdk'; // https://etherscan.io/address/0xcfe54b5cd566ab89272946f602d76ea879cab4a8 export const AGGREGATOR_STETH_USD_PRICE_FEED_BY_NETWORK: { - [key in CHAINS]?: string; + [key in CHAINS]?: Address; } = { [CHAINS.Mainnet]: '0xcfe54b5cd566ab89272946f602d76ea879cab4a8', }; diff --git a/consts/contract-addresses.ts b/consts/contract-addresses.ts new file mode 100644 index 000000000..c07deae16 --- /dev/null +++ b/consts/contract-addresses.ts @@ -0,0 +1,30 @@ +import { CHAINS } from '@lidofinance/lido-ethereum-sdk'; +import type { Address } from 'viem'; + +export const STAKING_ROUTER_BY_NETWORK: { + [key in CHAINS]?: Address; +} = { + [CHAINS.Mainnet]: '0xFdDf38947aFB03C621C71b06C9C70bce73f12999', + [CHAINS.Holesky]: '0xd6EbF043D30A7fe46D1Db32BA90a0A51207FE229', + [CHAINS.Sepolia]: '0x4F36aAEb18Ab56A4e380241bea6ebF215b9cb12c', +}; + +export const getStakingRouterAddress = ( + chainId: CHAINS, +): Address | undefined => { + return STAKING_ROUTER_BY_NETWORK[chainId] || undefined; +}; + +export const WITHDRAWAL_QUEUE_BY_NETWORK: { + [key in CHAINS]?: Address; +} = { + [CHAINS.Mainnet]: '0x889edC2eDab5f40e902b864aD4d7AdE8E412F9B1', + [CHAINS.Holesky]: '0xc7cc160b58F8Bb0baC94b80847E2CF2800565C50', + [CHAINS.Sepolia]: '0x1583C7b3f4C3B008720E6BcE5726336b0aB25fdd', +}; + +export const getWithdrawalQueueAddress = ( + chainId: CHAINS, +): Address | undefined => { + return WITHDRAWAL_QUEUE_BY_NETWORK[chainId] || undefined; +}; diff --git a/consts/react-query-strategies.ts b/consts/react-query-strategies.ts new file mode 100644 index 000000000..94a4d9ee1 --- /dev/null +++ b/consts/react-query-strategies.ts @@ -0,0 +1,25 @@ +export const STRATEGY_IMMUTABLE = { + staleTime: Infinity, + refetchOnWindowFocus: false, + refetchOnReconnect: false, +}; + +export const STRATEGY_CONSTANT = { + staleTime: Infinity, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + refetchInterval: 10 * 60 * 1000, // 10 minutes +}; + +export const STRATEGY_LAZY = { + staleTime: 5 * 60 * 1000, // 5 minutes + refetchOnWindowFocus: false, + refetchOnReconnect: true, +}; + +export const STRATEGY_EAGER = { + staleTime: 3000, // 3 seconds + refetchOnWindowFocus: true, + refetchOnReconnect: true, + refetchInterval: 10000, // 10 seconds +}; diff --git a/consts/staking-router.ts b/consts/staking-router.ts deleted file mode 100644 index 3e16c4874..000000000 --- a/consts/staking-router.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { CHAINS } from '@lido-sdk/constants'; -import { contractHooksFactory } from '@lido-sdk/react'; -import invariant from 'tiny-invariant'; - -import { PartialStakingRouterAbi__factory } from 'generated/factories/PartialStakingRouterAbi__factory'; - -export const STAKING_ROUTER_BY_NETWORK: { - [key in CHAINS]?: string; -} = { - [CHAINS.Mainnet]: '0xFdDf38947aFB03C621C71b06C9C70bce73f12999', - [CHAINS.Holesky]: '0xd6EbF043D30A7fe46D1Db32BA90a0A51207FE229', - [CHAINS.Sepolia]: '0x4F36aAEb18Ab56A4e380241bea6ebF215b9cb12c', -}; - -export const getStakingRouterAddress = (chainId: CHAINS): string => { - const address = STAKING_ROUTER_BY_NETWORK[chainId]; - invariant(address, 'chain is not supported'); - return address; -}; - -export const stakingRouter = contractHooksFactory( - PartialStakingRouterAbi__factory, - (chainId) => getStakingRouterAddress(chainId), -); diff --git a/consts/swr-strategies.ts b/consts/swr-strategies.ts deleted file mode 100644 index 13af19fba..000000000 --- a/consts/swr-strategies.ts +++ /dev/null @@ -1,41 +0,0 @@ -import type { SWRConfiguration } from 'swr'; - -const MINUTE_MS = 1000 * 60; - -type StrategyConfig = Pick< - SWRConfiguration, - | 'revalidateIfStale' - | 'revalidateOnFocus' - | 'revalidateOnReconnect' - | 'refreshInterval' - | 'focusThrottleInterval' - | 'dedupingInterval' ->; - -export const STRATEGY_IMMUTABLE: StrategyConfig = { - revalidateIfStale: false, - revalidateOnFocus: false, - revalidateOnReconnect: false, -}; - -export const STRATEGY_CONSTANT: StrategyConfig = { - revalidateIfStale: false, - revalidateOnFocus: false, - revalidateOnReconnect: false, - refreshInterval: 10 * MINUTE_MS, -}; - -export const STRATEGY_LAZY: StrategyConfig = { - revalidateOnFocus: false, - revalidateIfStale: true, - revalidateOnReconnect: true, - refreshInterval: 5 * MINUTE_MS, -}; - -export const STRATEGY_EAGER: StrategyConfig = { - revalidateOnFocus: true, - revalidateIfStale: true, - revalidateOnReconnect: true, - focusThrottleInterval: 10000, - dedupingInterval: 3000, -}; diff --git a/consts/token-addresses.ts b/consts/token-addresses.ts new file mode 100644 index 000000000..d217e0dc3 --- /dev/null +++ b/consts/token-addresses.ts @@ -0,0 +1,34 @@ +import type { Address } from 'viem'; +import { LIDO_TOKENS, CHAINS } from '@lidofinance/lido-ethereum-sdk'; + +export type TOKENS = + | Exclude<(typeof LIDO_TOKENS)[keyof typeof LIDO_TOKENS], 'unstETH'> + | 'LDO'; + +export const TOKENS_BY_NETWORK: { + [key in CHAINS]?: { [key in TOKENS]?: Address }; +} = { + [CHAINS.Mainnet]: { + [LIDO_TOKENS.steth]: '0xae7ab96520de3a18e5e111b5eaab095312d7fe84', + [LIDO_TOKENS.wsteth]: '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0', + LDO: '0x5a98fcbea516cf06857215779fd812ca3bef1b32', + }, + [CHAINS.Holesky]: { + [LIDO_TOKENS.steth]: '0x3F1c547b21f65e10480dE3ad8E19fAAC46C95034', + [LIDO_TOKENS.wsteth]: '0x8d09a4502Cc8Cf1547aD300E066060D043f6982D', + LDO: '0x14ae7daeecdf57034f3E9db8564e46Dba8D97344', + }, + [CHAINS.Sepolia]: { + [LIDO_TOKENS.steth]: '0x3e3FE7dBc6B4C189E7128855dD526361c49b40Af', + [LIDO_TOKENS.wsteth]: '0xB82381A3fBD3FaFA77B3a7bE693342618240067b', + LDO: '0xd06dF83b8ad6D89C86a187fba4Eae918d497BdCB', + }, +}; + +export const getRateTokenAddress = ( + chainId: CHAINS, + token: TOKENS, +): Address | undefined => { + if (token === 'ETH') return '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'; + return TOKENS_BY_NETWORK?.[chainId]?.[token]; +}; diff --git a/consts/tokens.ts b/consts/tokens.ts new file mode 100644 index 000000000..1a4036631 --- /dev/null +++ b/consts/tokens.ts @@ -0,0 +1,4 @@ +import { LIDO_TOKENS } from '@lidofinance/lido-ethereum-sdk'; + +export type LIDO_TOKENS_KEYS = keyof typeof LIDO_TOKENS; +export type LIDO_TOKENS_VALUES = (typeof LIDO_TOKENS)[keyof typeof LIDO_TOKENS]; diff --git a/consts/tx.ts b/consts/tx.ts index d011e0e6f..22597b51b 100644 --- a/consts/tx.ts +++ b/consts/tx.ts @@ -1,11 +1,11 @@ -import { BigNumber } from 'ethers'; +export const WSTETH_APPROVE_GAS_LIMIT = 78_000n; +export const STETH_L2_APPROVE_GAS_LIMIT = 52_500n; -export const WSTETH_APPROVE_GAS_LIMIT = BigNumber.from(78000); -export const STETH_L2_APPROVE_GAS_LIMIT = BigNumber.from(52500); +export const WRAP_FROM_ETH_GAS_LIMIT = 100_000n; +export const WRAP_GAS_LIMIT = 140_000n; +export const WRAP_L2_GAS_LIMIT = 95_500n; -export const WRAP_FROM_ETH_GAS_LIMIT = BigNumber.from(100000); -export const WRAP_GAS_LIMIT = BigNumber.from(140000); -export const WRAP_L2_GAS_LIMIT = BigNumber.from(95500); +export const UNWRAP_GAS_LIMIT = 115_000n; +export const UNWRAP_L2_GAS_LIMIT = 77_500n; -export const UNWRAP_GAS_LIMIT = BigNumber.from(115000); -export const UNWRAP_L2_GAS_LIMIT = BigNumber.from(77500); +export const WEI_PER_ETHER = 1_000_000_000_000_000_000n; // 10n ** 18n; diff --git a/features/ipfs/security-status-banner/use-remote-version.ts b/features/ipfs/security-status-banner/use-remote-version.ts index d970860bc..e7ab4af3f 100644 --- a/features/ipfs/security-status-banner/use-remote-version.ts +++ b/features/ipfs/security-status-banner/use-remote-version.ts @@ -1,7 +1,9 @@ -import { useLidoSWR } from '@lido-sdk/react'; +import { getEnsResolver, getEnsText } from 'viem/ens'; +import { useQuery } from '@tanstack/react-query'; + import { useConfig } from 'config'; -import { STRATEGY_LAZY } from 'consts/swr-strategies'; -import { useMainnetStaticRpcProvider } from 'shared/hooks/use-mainnet-static-rpc-provider'; +import { STRATEGY_LAZY } from 'consts/react-query-strategies'; +import { useMainnetOnlyWagmi } from 'modules/web3'; type EnsHashCheckReturn = { cid: string; @@ -11,22 +13,29 @@ type EnsHashCheckReturn = { }; export const useRemoteVersion = () => { - const provider = useMainnetStaticRpcProvider(); + const { publicClientMainnet } = useMainnetOnlyWagmi(); // we use directly non-optimistic manifest data // can't trust static props(in IPFS esp) to generate warnings/disconnect wallet - const externalConfigSwr = useConfig().externalConfig.fetchMeta; - const { data, error } = externalConfigSwr; + const externalConfigQueryReact = useConfig().externalConfig.fetchMeta; + const { data, error } = externalConfigQueryReact; - // we only need this as swr because of possible future ENS support + // we only need this as 'react query result' because of possible future ENS support // otherwise there is no fetch - const swr = useLidoSWR( - ['swr:use-remote-version', externalConfigSwr.data], - async (): Promise => { + const queryResult = useQuery({ + queryKey: ['use-remote-version', externalConfigQueryReact.data], + ...STRATEGY_LAZY, + enabled: !!(data || error), + queryFn: async (): Promise => { if (data?.ens) { - const resolver = await provider.getResolver(data.ens); - if (resolver) { - const contentHash = await resolver.getContentHash(); + const resolverAddress = await getEnsResolver(publicClientMainnet, { + name: data.ens, + }); + if (resolverAddress) { + const contentHash = await getEnsText(publicClientMainnet, { + name: data.ens, + key: 'contenthash', + }); if (contentHash) { return { cid: contentHash, @@ -47,29 +56,20 @@ export const useRemoteVersion = () => { throw new Error('[useRemoteVersion] invalid IPFS manifest content'); }, - { - ...STRATEGY_LAZY, - // we postpone fetch if we don't have external data and don't have error - // empty data will force fetcher to produce correct error - isPaused: () => !(data || error), - }, - ); + }); - // merged externalConfigSwr && cidSwr + // merged externalConfigQueryReact && cidQueryResult (queryResult) return { - data: swr.data, - get initialLoading() { - return ( - swr.initialLoading || - (externalConfigSwr.data == null && externalConfigSwr.isValidating) - ); + data: queryResult.data, + get isLoading() { + return queryResult.isLoading || externalConfigQueryReact.isLoading; }, - get loading() { - return swr.loading || externalConfigSwr.isValidating; + get isFetching() { + return queryResult.isFetching || externalConfigQueryReact.isFetching; }, get error() { - return swr.error || error; + return queryResult.error || error; }, - update: swr.update, + update: queryResult.refetch, }; }; diff --git a/features/ipfs/security-status-banner/use-version-status.ts b/features/ipfs/security-status-banner/use-version-status.ts index d18684484..595cd0133 100644 --- a/features/ipfs/security-status-banner/use-version-status.ts +++ b/features/ipfs/security-status-banner/use-version-status.ts @@ -1,11 +1,11 @@ import { useEffect, useState } from 'react'; import { useForceDisconnect } from 'reef-knot/core-react'; -import { useLidoSWR } from '@lido-sdk/react'; +import { useQuery } from '@tanstack/react-query'; import buildInfo from 'build-info.json'; import { config } from 'config'; import { useUserConfig } from 'config/user-config'; -import { STRATEGY_IMMUTABLE } from 'consts/swr-strategies'; +import { STRATEGY_IMMUTABLE } from 'consts/react-query-strategies'; import { useDappStatus } from 'modules/web3'; import { overrideWithQAMockBoolean } from 'utils/qa'; @@ -25,53 +25,56 @@ export const useVersionStatus = () => { const [areConditionsAccepted, setConditionsAccepted] = useState(false); // only IPFS: local cid extraction - const currentCidSWR = useLidoSWR( - ['swr:ipfs-cid-extraction'], - async () => { + const currentCidQueryResult = useQuery({ + queryKey: ['ipfs-cid-extraction'], + ...STRATEGY_IMMUTABLE, + enabled: !!config.ipfsMode, + queryFn: async () => { const urlCid = URL_CID_REGEX.exec(window.location.href)?.groups?.cid; if (urlCid) return urlCid; - const headers = await fetch( + + const response = await fetch( `${config.BASE_PATH_ASSET}/runtime/window-env.js`, { method: 'HEAD', }, ); - return headers.headers.get('X-Ipfs-Roots'); + + return response.headers.get('X-Ipfs-Roots'); }, - { ...STRATEGY_IMMUTABLE, isPaused: () => !config.ipfsMode }, - ); + }); // ens cid extraction - const remoteVersionSWR = useRemoteVersion(); + const remoteVersionQueryResult = useRemoteVersion(); // update is available // for INFRA - leastSafeVersion is not NO_SAFE_VERSION // for IPFS - ^this and current cid doesn't match const isUpdateAvailable = overrideWithQAMockBoolean( Boolean( - remoteVersionSWR.data && - ((currentCidSWR.data && - remoteVersionSWR.data.cid !== currentCidSWR.data) || + remoteVersionQueryResult.data && + ((currentCidQueryResult.data && + remoteVersionQueryResult.data.cid !== currentCidQueryResult.data) || !config.ipfsMode) && - remoteVersionSWR.data.leastSafeVersion !== NO_SAFE_VERSION, + remoteVersionQueryResult.data.leastSafeVersion !== NO_SAFE_VERSION, ), 'mock-qa-helpers-security-banner-is-update-available', ); const isVersionUnsafe = overrideWithQAMockBoolean( Boolean( - remoteVersionSWR.data?.leastSafeVersion && - (remoteVersionSWR.data.leastSafeVersion === NO_SAFE_VERSION || + remoteVersionQueryResult.data?.leastSafeVersion && + (remoteVersionQueryResult.data.leastSafeVersion === NO_SAFE_VERSION || isVersionLess( buildInfo.version, - remoteVersionSWR.data.leastSafeVersion, + remoteVersionQueryResult.data.leastSafeVersion, )), ), 'mock-qa-helpers-security-banner-is-version-unsafe', ); const isNotVerifiable = overrideWithQAMockBoolean( - !!remoteVersionSWR.error, + !!remoteVersionQueryResult.error, 'mock-qa-helpers-security-banner-is-not-verifiable', ); @@ -103,19 +106,23 @@ export const useVersionStatus = () => { get data() { return { - remoteCid: remoteVersionSWR.data?.cid, - currentCid: currentCidSWR.data, - remoteCidLink: remoteVersionSWR.data?.link, + remoteCid: remoteVersionQueryResult.data?.cid, + currentCid: currentCidQueryResult.data, + remoteCidLink: remoteVersionQueryResult.data?.link, }; }, - get initialLoading() { - return remoteVersionSWR.initialLoading || currentCidSWR.initialLoading; + get isLoading() { + return ( + remoteVersionQueryResult.isLoading || currentCidQueryResult.isLoading + ); }, - get loading() { - return remoteVersionSWR.loading || currentCidSWR.loading; + get isFetching() { + return ( + remoteVersionQueryResult.isFetching || currentCidQueryResult.isFetching + ); }, get error() { - return remoteVersionSWR.error || currentCidSWR.error; + return remoteVersionQueryResult.error || currentCidQueryResult.error; }, }; }; diff --git a/features/rewards/components/EthSymbol.tsx b/features/rewards/components/EthSymbol.tsx index ea04918e9..b3cf440d2 100644 --- a/features/rewards/components/EthSymbol.tsx +++ b/features/rewards/components/EthSymbol.tsx @@ -1,10 +1,10 @@ import { Box } from '@lidofinance/lido-ui'; -import { constants } from 'ethers'; +import { ETHER_SYMBOL } from 'modules/web3'; // TODO: move to separate folders const EthSymbol = () => ( - {constants.EtherSymbol} + {ETHER_SYMBOL} ); diff --git a/features/rewards/components/IndexerLink.tsx b/features/rewards/components/IndexerLink.tsx index b2a064ab7..5d66fe4b5 100644 --- a/features/rewards/components/IndexerLink.tsx +++ b/features/rewards/components/IndexerLink.tsx @@ -1,7 +1,7 @@ import { Box, External as ExternalLinkIcon } from '@lidofinance/lido-ui'; -import { getEtherscanTxLink } from 'utils/get-etherscan-tx-link'; import { config } from 'config'; +import { getEtherscanTxLink } from 'utils/etherscan'; // TODO: move to separate folders type Props = { diff --git a/features/rewards/components/NumberFormat.tsx b/features/rewards/components/NumberFormat.tsx index 1c69066fd..9b83a47dc 100644 --- a/features/rewards/components/NumberFormat.tsx +++ b/features/rewards/components/NumberFormat.tsx @@ -1,18 +1,14 @@ +import { Tooltip, Box, InlineLoader } from '@lidofinance/lido-ui'; import { formatWEI, formatETH, - formatStEthEth, formatCurrency, + formatStEthEth, formatPercentage, } from 'features/rewards/utils/numberFormatting'; -import { Tooltip, Box, InlineLoader } from '@lidofinance/lido-ui'; -import type { BigNumber } from 'features/rewards/helpers'; -import { Big, BigDecimal } from 'features/rewards/helpers'; - -// TODO: move to separate folders type FormatArgs = { - number?: string | number | BigNumber | undefined; + number?: string | number | undefined; StEthEth?: boolean; currency?: boolean; percent?: boolean; @@ -20,24 +16,22 @@ type FormatArgs = { }; // Using ETH as a default formatter -const format = ( - { number, StEthEth, currency, percent, ETH }: FormatArgs, - manyDigits?: boolean, -): string => { +const format = (props: FormatArgs, manyDigits?: boolean): string => { + const { number, StEthEth, currency, percent, ETH } = props; if (number === undefined) return ''; - const args = [new BigDecimal(number), Boolean(manyDigits)] as const; + const numberString = typeof number === 'string' ? number : number.toString(); if (StEthEth) { - return formatStEthEth(...args); + return formatStEthEth(numberString, manyDigits); } else if (currency) { - return formatCurrency(...args); + return formatCurrency(numberString, manyDigits); } else if (percent) { - return formatPercentage(...args); + return formatPercentage(numberString, manyDigits); } else if (ETH) { - return formatETH(...args); + return formatETH(numberString, manyDigits); } else { - return formatWEI(new Big(number), args[1]); + return formatWEI(numberString, manyDigits); } }; diff --git a/features/rewards/components/rewardsListContent/RewardsListContent.tsx b/features/rewards/components/rewardsListContent/RewardsListContent.tsx index f4eca9a9a..3154382f0 100644 --- a/features/rewards/components/rewardsListContent/RewardsListContent.tsx +++ b/features/rewards/components/rewardsListContent/RewardsListContent.tsx @@ -1,6 +1,5 @@ import { FC } from 'react'; import { Loader, Divider } from '@lidofinance/lido-ui'; -import { Zero } from '@ethersproject/constants'; import { useRewardsHistory } from 'features/rewards/hooks'; import { ErrorBlockNoSteth } from 'features/rewards/components/errorBlocks/ErrorBlockNoSteth'; @@ -23,7 +22,7 @@ export const RewardsListContent: FC = () => { const { address, error, - initialLoading, + isLoading, data, currencyObject, page, @@ -35,16 +34,16 @@ export const RewardsListContent: FC = () => { account: address as Address, shouldSubscribeToUpdates: false, }); - const hasSteth = stethBalance?.gt(Zero); + const hasSteth = !!stethBalance; if (!isSupportedChain) return ; - if (!data && !initialLoading && !error) return ; + if (!data && !isLoading && !error) return ; // showing loading when canceling requests and empty response if ( (!data && !error) || - (initialLoading && !data?.events.length) || + (isLoading && !data?.events.length) || isStethBalanceLoading ) { return ( diff --git a/features/rewards/components/rewardsListContent/RewardsListsEmpty.tsx b/features/rewards/components/rewardsListContent/RewardsListsEmpty.tsx index b483d88cf..08aa0552b 100644 --- a/features/rewards/components/rewardsListContent/RewardsListsEmpty.tsx +++ b/features/rewards/components/rewardsListContent/RewardsListsEmpty.tsx @@ -6,6 +6,7 @@ import { Button, Divider } from '@lidofinance/lido-ui'; import { useUserConfig } from 'config/user-config'; import { MATOMO_CLICK_EVENTS } from 'consts/matomo-click-events'; import { useDappStatus } from 'modules/web3'; + import { RewardsListEmptyButtonWrapper, RewardsListEmptyWrapper, diff --git a/features/rewards/components/rewardsListContent/RewardsListsUnsupportedChain.tsx b/features/rewards/components/rewardsListContent/RewardsListsUnsupportedChain.tsx index 1ace34774..3c94e82aa 100644 --- a/features/rewards/components/rewardsListContent/RewardsListsUnsupportedChain.tsx +++ b/features/rewards/components/rewardsListContent/RewardsListsUnsupportedChain.tsx @@ -1,10 +1,11 @@ import { FC } from 'react'; import { Divider } from '@lidofinance/lido-ui'; -import { RewardsListEmptyWrapper } from './RewardsListsEmptyStyles'; import { useDappStatus } from 'modules/web3'; import { joinWithOr } from 'utils/join-with-or'; +import { RewardsListEmptyWrapper } from './RewardsListsEmptyStyles'; + export const RewardsListsUnsupportedChain: FC = () => { const { supportedChainLabels } = useDappStatus(); diff --git a/features/rewards/components/stats/average-apr-block.tsx b/features/rewards/components/stats/average-apr-block.tsx index e2e5aefeb..a708fd538 100644 --- a/features/rewards/components/stats/average-apr-block.tsx +++ b/features/rewards/components/stats/average-apr-block.tsx @@ -8,11 +8,11 @@ import { Item } from './components/item'; import { FlexCenter } from './components/styles'; export const AverageAprBlock: FC = () => { - const { data, initialLoading: loading } = useRewardsHistory(); + const { data, isLoading } = useRewardsHistory(); return ( diff --git a/features/rewards/components/stats/steth-balance-block.tsx b/features/rewards/components/stats/steth-balance-block.tsx index 9fb0832ce..efad6e439 100644 --- a/features/rewards/components/stats/steth-balance-block.tsx +++ b/features/rewards/components/stats/steth-balance-block.tsx @@ -12,12 +12,12 @@ export const StEthBalanceBlock: FC = () => { const { data: dataRewards, currencyObject: currency, - loading, + isLoading, } = useRewardsHistory(); return ( { - const { - currencyObject: currency, - data, - initialLoading: loading, - } = useRewardsHistory(); - const stEthEth = useStethEthRate(); + const { currencyObject: currency, data, isLoading } = useRewardsHistory(); + const { data: stEthEth, isLoading: isLoadingStEthEth } = useStethEthRate(); return ( { - const { - currencyObject: currency, - data, - initialLoading: loading, - } = useRewardsHistory(); + const { currencyObject: currency, data, isLoading } = useRewardsHistory(); return ( { diff --git a/features/rewards/features/top-card/wallet.tsx b/features/rewards/features/top-card/wallet.tsx index 7a429f731..e469ed90d 100644 --- a/features/rewards/features/top-card/wallet.tsx +++ b/features/rewards/features/top-card/wallet.tsx @@ -13,7 +13,7 @@ export const Wallet: FC = () => { isAddressResolving, inputValue, setInputValue, - loading, + isLoading, } = useRewardsHistory(); return ( @@ -26,7 +26,7 @@ export const Wallet: FC = () => { inputValue={inputValue} handleInputChange={setInputValue} isAddressResolving={isAddressResolving} - loading={loading} + loading={isLoading} /> diff --git a/features/rewards/helpers/big.ts b/features/rewards/helpers/big.ts deleted file mode 100644 index 45f4ca678..000000000 --- a/features/rewards/helpers/big.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { BigNumber } from 'bignumber.js'; -import { PRECISE_DECIMALS } from 'features/rewards/constants'; - -// TODO: change to general solution - -// Default WEI Solidity-like instance -class Big extends BigNumber.clone() {} - -// Special non-int mode for ETH amounts, APR and other final calculations -class BigDecimal extends BigNumber.clone() {} - -// Behave as ints-only until we are in BigDecimal mode -Big.set({ DECIMAL_PLACES: 0 }); -BigDecimal.set({ DECIMAL_PLACES: PRECISE_DECIMALS }); - -// Match solidity calculations by default -Big.set({ ROUNDING_MODE: BigNumber.ROUND_DOWN }); -BigDecimal.set({ ROUNDING_MODE: BigNumber.ROUND_HALF_UP }); - -// Never output scientific notations, we don't want our users to see them -Big.set({ EXPONENTIAL_AT: [-70000000, 210000000] }); -BigDecimal.set({ EXPONENTIAL_AT: [-70000000, 210000000] }); - -// Formatting for human readability -BigDecimal.set({ - FORMAT: { - // string to prepend - prefix: '', - // decimal separator - decimalSeparator: '.', - // grouping separator of the integer part - groupSeparator: ',', - // primary grouping size of the integer part - groupSize: 3, - // secondary grouping size of the integer part - secondaryGroupSize: 0, - // grouping separator of the fraction part - fractionGroupSeparator: ' ', - // grouping size of the fraction part - fractionGroupSize: 0, - // string to append - suffix: '', - }, -}); - -// BigNumber is here to highlight a universal type between the two instances -export { Big, BigDecimal, type BigNumber }; diff --git a/features/rewards/helpers/index.ts b/features/rewards/helpers/index.ts deleted file mode 100644 index 2c9e668fd..000000000 --- a/features/rewards/helpers/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './big'; diff --git a/features/rewards/hooks/use-rewards-balance-data.ts b/features/rewards/hooks/use-rewards-balance-data.ts index 08a62fb14..dfe0ead60 100644 --- a/features/rewards/hooks/use-rewards-balance-data.ts +++ b/features/rewards/hooks/use-rewards-balance-data.ts @@ -1,37 +1,32 @@ import { useMemo } from 'react'; -import { useSDK, useTokenBalance } from '@lido-sdk/react'; -import { TOKENS, getTokenAddress } from '@lido-sdk/constants'; +import { getAddress } from 'viem'; -import { STRATEGY_LAZY } from 'consts/swr-strategies'; +import { useStethBalance } from 'modules/web3'; import { ETHER } from 'features/rewards/constants'; import { useRewardsHistory } from './useRewardsHistory'; import { useLaggyDataWrapper } from './use-laggy-data-wrapper'; -import { Big, BigDecimal } from '../helpers'; export const useRewardsBalanceData = () => { - const { chainId } = useSDK(); const { address, data, currencyObject } = useRewardsHistory(); - - const { data: steth } = useTokenBalance( - getTokenAddress(chainId, TOKENS.STETH), - address, - STRATEGY_LAZY, - ); + const { data: stethBalance } = useStethBalance({ + account: address ? getAddress(address) : undefined, + }); const balanceData = useMemo( () => - steth + stethBalance ? { - stEthBalanceParsed: new Big(steth.toString()), + stEthBalanceParsed: stethBalance.toString(), stEthCurrencyBalance: + // accuracy is okay for display data && - new BigDecimal(steth.toString()) // Convert to right BN - .div(ETHER) - .times(data.stETHCurrencyPrice[currencyObject.id]), + stethBalance && + (Number(stethBalance) / Number(ETHER)) * + data?.stETHCurrencyPrice[currencyObject.id], } : null, - [currencyObject.id, data, steth], + [currencyObject.id, data, stethBalance], ); const { isLagging, dataOrLaggyData } = useLaggyDataWrapper(balanceData); diff --git a/features/rewards/hooks/use-steth-eth-rate.ts b/features/rewards/hooks/use-steth-eth-rate.ts index 39ddb8fa9..67dcb22fe 100644 --- a/features/rewards/hooks/use-steth-eth-rate.ts +++ b/features/rewards/hooks/use-steth-eth-rate.ts @@ -1,28 +1,38 @@ -import { useContractSWR, useSDK } from '@lido-sdk/react'; +import invariant from 'tiny-invariant'; +import { useQuery } from '@tanstack/react-query'; -import { STRATEGY_LAZY } from 'consts/swr-strategies'; -import { useMainnetStaticRpcProvider } from 'shared/hooks/use-mainnet-static-rpc-provider'; -import { constants } from 'ethers'; -import { PartialCurveAbiAbi__factory } from 'generated'; -import { createContractGetter } from '@lido-sdk/contracts'; +import { PartialCurveAbi } from 'abi/partial-curve-abi'; +import { WEI_PER_ETHER } from 'consts/tx'; +import { useMainnetOnlyWagmi } from 'modules/web3'; -const getCurveContract = createContractGetter(PartialCurveAbiAbi__factory); export const MAINNET_CURVE = '0xDC24316b9AE028F1497c275EB9192a3Ea0f67022'; export const useStethEthRate = () => { - const { chainId } = useSDK(); - const mainnetStaticRpcProvider = useMainnetStaticRpcProvider(); + const { publicClientMainnet } = useMainnetOnlyWagmi(); - const contract = getCurveContract(MAINNET_CURVE, mainnetStaticRpcProvider); + const { data, error, isLoading, refetch, isFetching } = useQuery({ + queryKey: ['get_dy', publicClientMainnet], + enabled: !!publicClientMainnet, + queryFn: () => { + invariant( + publicClientMainnet, + '[useStethEthRate] The "publicClientMainnet" must be define', + ); - const swr = useContractSWR({ - contract, - method: 'get_dy', - params: [0, 1, String(10 ** 18)], - config: STRATEGY_LAZY, - shouldFetch: chainId === 1, + return publicClientMainnet.readContract({ + address: MAINNET_CURVE, + abi: PartialCurveAbi, + functionName: 'get_dy', + args: [0n, 1n, WEI_PER_ETHER], + }); + }, }); - if (chainId !== 1) return constants.WeiPerEther; - return swr.data; + return { + data: data || WEI_PER_ETHER, + isLoading, + error, + isFetching, + update: refetch, + }; }; diff --git a/features/rewards/hooks/useGetCurrentAddress.ts b/features/rewards/hooks/useGetCurrentAddress.ts index e618b952e..657e5b732 100644 --- a/features/rewards/hooks/useGetCurrentAddress.ts +++ b/features/rewards/hooks/useGetCurrentAddress.ts @@ -1,12 +1,11 @@ import { useCallback, useEffect, useMemo, useState } from 'react'; import { useRouter } from 'next/router'; import debounce from 'lodash/debounce'; +import { usePublicClient } from 'wagmi'; +import { isAddress, type PublicClient } from 'viem'; -import { useSDK } from '@lido-sdk/react'; - -import { resolveEns, isValidEns, isValidAddress } from 'features/rewards/utils'; -import { useCurrentStaticRpcProvider } from 'shared/hooks/use-current-static-rpc-provider'; import { useDappStatus } from 'modules/web3'; +import { resolveEns, isValidEns } from 'features/rewards/utils'; type UseGetCurrentAddress = () => { address: string; @@ -25,10 +24,10 @@ export const useGetCurrentAddress: UseGetCurrentAddress = () => { const [address, setAddress] = useState(''); const [addressError, setAddressError] = useState(''); - const { account } = useSDK(); - const { staticRpcProvider } = useCurrentStaticRpcProvider(); const { isReady, query } = useRouter(); - const { isSupportedChain } = useDappStatus(); + const { address: account, chainId, isSupportedChain } = useDappStatus(); + // it works, but typing issue + const publicClient = usePublicClient({ chainId: chainId }) as PublicClient; const getEnsAddress = useCallback( async (value: string) => { @@ -38,7 +37,7 @@ export const useGetCurrentAddress: UseGetCurrentAddress = () => { setIsAddressResolving(true); try { - result = await resolveEns(value, staticRpcProvider); + result = await resolveEns(value, publicClient); } catch (e) { console.error(e); error = 'An error happened during ENS name resolving'; @@ -54,7 +53,7 @@ export const useGetCurrentAddress: UseGetCurrentAddress = () => { setAddressError("The ENS name entered couldn't be found"); } }, - [staticRpcProvider], + [publicClient], ); const resolveInputValue = useMemo( @@ -62,7 +61,7 @@ export const useGetCurrentAddress: UseGetCurrentAddress = () => { debounce(async (value: string) => { if (value && isValidEns(value)) { await getEnsAddress(value); - } else if (isValidAddress(value)) { + } else if (isAddress(value)) { setAddress(value); } else { setAddress(''); diff --git a/features/rewards/hooks/useRewardsDataLoad.ts b/features/rewards/hooks/useRewardsDataLoad.ts index 5696098cf..6b3c1b3f5 100644 --- a/features/rewards/hooks/useRewardsDataLoad.ts +++ b/features/rewards/hooks/useRewardsDataLoad.ts @@ -1,7 +1,9 @@ +import { useQuery } from '@tanstack/react-query'; import { config } from 'config'; +import { STRATEGY_LAZY } from 'consts/react-query-strategies'; import { Backend } from 'features/rewards/types'; -import { useLidoSWR } from 'shared/hooks'; -import { swrAbortableMiddleware } from 'utils'; + +import { standardFetcher } from 'utils/standardFetcher'; import { useLaggyDataWrapper } from './use-laggy-data-wrapper'; type UseRewardsDataLoad = (props: { @@ -14,8 +16,8 @@ type UseRewardsDataLoad = (props: { }) => { data?: Backend; error?: unknown; - loading: boolean; - initialLoading: boolean; + isFetching: boolean; + isLoading: boolean; isLagging: boolean; }; @@ -50,16 +52,25 @@ export const useRewardsDataLoad: UseRewardsDataLoad = (props) => { apiRewardsUrl = `/api/rewards?${params.toString()}`; } - const { data, ...rest } = useLidoSWR( - address ? apiRewardsUrl : null, - { - shouldRetryOnError: false, - revalidateOnFocus: false, - use: [swrAbortableMiddleware], - }, - ); + const { data, error, isFetching, isLoading } = useQuery({ + queryKey: ['rewards-data', address, apiRewardsUrl], + enabled: !!address, + ...STRATEGY_LAZY, + queryFn: ({ signal }) => + // The 'react-query' has AbortController support built in, + // and it automatically cancels requests when + // the component is unmounted or the queryKey changes. + standardFetcher(apiRewardsUrl, { signal }), + }); const { isLagging, dataOrLaggyData } = useLaggyDataWrapper(data); - return { ...rest, isLagging: !!address && isLagging, data: dataOrLaggyData }; + return { + error, + isFetching, + isLoading, + // Fix 'Type 'TQueryFnData' is not assignable to type 'Backend'' + data: dataOrLaggyData as Backend, + isLagging: !!address && isLagging, + }; }; diff --git a/features/rewards/utils/addressValidation.ts b/features/rewards/utils/addressValidation.ts index f40ad81be..96e7b2593 100644 --- a/features/rewards/utils/addressValidation.ts +++ b/features/rewards/utils/addressValidation.ts @@ -1,11 +1,8 @@ -import { ethers } from 'ethers'; +import { isAddress } from 'viem'; const regex = new RegExp('[-a-zA-Z0-9@._]{1,256}.eth'); -export const isValidAddress = (address: string) => - ethers.utils.isAddress(address); - export const isValidEns = (ens: string) => regex.test(ens); export const isValidAnyAddress = (input: string) => - isValidAddress(input) || isValidEns(input); + isAddress(input) || isValidEns(input); diff --git a/features/rewards/utils/genExportData.ts b/features/rewards/utils/genExportData.ts index 43e4511fb..ea4314c29 100644 --- a/features/rewards/utils/genExportData.ts +++ b/features/rewards/utils/genExportData.ts @@ -1,20 +1,20 @@ -import { weiToEther } from 'features/rewards/utils'; +import { fromUnixTime } from 'date-fns'; +import { formatEther } from 'viem'; + import type { Event } from 'features/rewards/types'; import type { CurrencyType } from 'features/rewards/constants'; -import { fromUnixTime } from 'date-fns'; - export const genExportData = (currency: CurrencyType, data: Event[] | null) => data ? data.map((item) => ({ date: fromUnixTime(parseInt(item.blockTime)).toISOString(), type: item.type, direction: item.direction, - change: weiToEther(item.change).toString(), + change: formatEther(BigInt(item.change)), change_wei: item.change.toString(), [`change_${currency.code}`]: item.currencyChange?.toString(), apr: item.apr, - balance: weiToEther(item.balance).toString(), + balance: formatEther(BigInt(item.balance)), balance_wei: item.balance, })) : []; diff --git a/features/rewards/utils/numberFormatting.ts b/features/rewards/utils/numberFormatting.ts index 578c25937..aeb819f87 100644 --- a/features/rewards/utils/numberFormatting.ts +++ b/features/rewards/utils/numberFormatting.ts @@ -1,4 +1,4 @@ -import { BigDecimal } from 'features/rewards/helpers'; +import { formatEther, parseEther } from 'viem'; import { ETHER, HUMAN_DECIMALS, @@ -9,81 +9,42 @@ import { PRECISE_DECIMALS_CURRENCY, } from 'features/rewards/constants'; -import type { BigNumber } from 'features/rewards/helpers'; - -// TODO: change to general solution - -export const weiToEther = (wei: BigNumber | string) => - new BigDecimal(wei).div(ETHER); - -export const formatWEI = (input: BigNumber, manyDigits: boolean) => { - const decimals = manyDigits ? PRECISE_DECIMALS : HUMAN_DECIMALS; - const inWei = weiToEther(input).decimalPlaces(decimals); - - return inWei.toFormat(); +export const formatWEI = (input: string, manyDigits?: boolean) => { + const ethers = formatEther(parseEther(input) / ETHER); + if (manyDigits) { + return Number(ethers).toFixed(PRECISE_DECIMALS); + } + return Number(ethers).toFixed(HUMAN_DECIMALS); }; -export const formatETH = (input: BigNumber, manyDigits: boolean) => { - const decimals = manyDigits ? PRECISE_DECIMALS : HUMAN_DECIMALS; - const inWei = input.decimalPlaces(decimals); - - return inWei.toFormat(); +export const formatETH = (input: string, manyDigits?: boolean) => { + return parseFloat(input).toFixed( + manyDigits ? PRECISE_DECIMALS : HUMAN_DECIMALS, + ); }; -// ETH-stETH ratio formatting -export const formatStEthEth = (stEthEth: BigNumber, manyDigits: boolean) => { - const ratio = new BigDecimal(1) - .div(new BigDecimal(stEthEth).div(ETHER)) - .times(ETHER); - - return formatWEI(ratio, manyDigits); +export const formatStEthEth = (input: string, manyDigits?: boolean) => { + const ethers = formatEther(parseEther(input) / ETHER); + if (manyDigits) { + return ethers; + } + return Number(ethers).toFixed(HUMAN_DECIMALS); }; -export const simpleFormatCurrency = ( - input: BigNumber, - manyDigits: boolean, - decimalOverride?: number, -) => { - const decimals = decimalOverride - ? HUMAN_DECIMALS_CURRENCY + decimalOverride - : manyDigits - ? PRECISE_DECIMALS_CURRENCY - : HUMAN_DECIMALS_CURRENCY; - +export const formatCurrency = (input: string, manyDigits?: boolean) => { const options = { - currency: 'USD', // TODO: make dynamic if beneficial - maximumFractionDigits: decimals, + currency: 'USD', + maximumFractionDigits: manyDigits + ? PRECISE_DECIMALS_CURRENCY + : HUMAN_DECIMALS_CURRENCY, }; - return new Intl.NumberFormat('en-GB', options).format(input.toNumber()); + return new Intl.NumberFormat('en-GB', options).format(Number(input)); }; -export const formatCurrency = ( - input: BigNumber, - manyDigits: boolean, - decimalOverride?: number, -): string | T => { - // Early sanity exit - if (decimalOverride && decimalOverride >= 10) { - return '0'; - } - - const formatted = simpleFormatCurrency(input, manyDigits, decimalOverride); - if (formatted !== '0') { - return formatted; - } else { - return formatCurrency( - input, - manyDigits, - decimalOverride ? decimalOverride + 1 : 1, - ); +export const formatPercentage = (input: string, manyDigits?: boolean) => { + if (manyDigits) { + return Number(input).toFixed(PRECISE_DECIMALS_PERCENT); } -}; - -export const formatPercentage = (input: BigNumber, manyDigits: boolean) => { - const decimals = manyDigits - ? PRECISE_DECIMALS_PERCENT - : HUMAN_DECIMALS_PERCENT; - - return input.decimalPlaces(decimals).toString(); + return Number(input).toFixed(HUMAN_DECIMALS_PERCENT); }; diff --git a/features/rewards/utils/resolveEns.ts b/features/rewards/utils/resolveEns.ts index 5fe044b04..1be6fdc2f 100644 --- a/features/rewards/utils/resolveEns.ts +++ b/features/rewards/utils/resolveEns.ts @@ -1,8 +1,12 @@ -import { StaticJsonRpcBatchProvider } from '@lidofinance/eth-providers'; +import { PublicClient } from 'viem'; +import { getEnsAddress, normalize } from 'viem/ens'; export const resolveEns = async ( name: string | Promise, - provider: StaticJsonRpcBatchProvider, -) => { - return await provider.resolveName(name); + client: PublicClient, +): Promise => { + const resolvedName = typeof name === 'string' ? name : await name; + return await getEnsAddress(client, { + name: normalize(resolvedName), + }); }; diff --git a/features/settings/settings-form/settings-form.tsx b/features/settings/settings-form/settings-form.tsx index 06920792e..c4145f902 100644 --- a/features/settings/settings-form/settings-form.tsx +++ b/features/settings/settings-form/settings-form.tsx @@ -1,11 +1,13 @@ import { useCallback } from 'react'; import { useForm } from 'react-hook-form'; +import type { LIDO_CONTRACT_NAMES } from '@lidofinance/lido-ethereum-sdk/common'; import { Button, ToastSuccess, Block, Input } from '@lidofinance/lido-ui'; import { useUserConfig } from 'config/user-config'; import { CHAINS } from 'consts/chains'; import { LinkArrow } from 'shared/components/link-arrow/link-arrow'; +import { useContractAddress } from 'modules/web3'; import { RPCErrorType, checkRpcUrl } from 'utils/check-rpc-url'; import { @@ -32,6 +34,10 @@ export const SettingsForm = () => { }, }); + const { data: stethAddress } = useContractAddress( + 'lido' as LIDO_CONTRACT_NAMES, + ); + const { formState, setValue, @@ -62,7 +68,7 @@ export const SettingsForm = () => { const validateRpcUrl = useCallback( async (rpcUrl: string) => { if (!rpcUrl) return true; - const rpcCheckResult = await checkRpcUrl(rpcUrl, chainId); + const rpcCheckResult = await checkRpcUrl(rpcUrl, chainId, stethAddress); switch (rpcCheckResult) { case true: return true; @@ -74,7 +80,7 @@ export const SettingsForm = () => { return 'Url is working, but network does not match'; } }, - [chainId], + [chainId, stethAddress], ); const handleReset = useCallback(() => { diff --git a/features/stake/lido-stats/lido-stats.tsx b/features/stake/lido-stats/lido-stats.tsx index f0deebd64..95e827fc0 100644 --- a/features/stake/lido-stats/lido-stats.tsx +++ b/features/stake/lido-stats/lido-stats.tsx @@ -1,17 +1,17 @@ import { FC, memo, useMemo } from 'react'; -import { getEtherscanTokenLink } from '@lido-sdk/helpers'; -import { useSDK } from '@lido-sdk/react'; -import { getTokenAddress, TOKENS } from '@lido-sdk/constants'; +import { LIDO_TOKENS } from '@lidofinance/lido-ethereum-sdk/common'; import { Block, DataTable, Question, Tooltip } from '@lidofinance/lido-ui'; -import { Section, MatomoLink } from 'shared/components'; -import { useLidoApr, useLidoStats } from 'shared/hooks'; - import { config } from 'config'; - import { LIDO_APR_TOOLTIP_TEXT, DATA_UNAVAILABLE } from 'consts/text'; import { MATOMO_CLICK_EVENTS_TYPES } from 'consts/matomo-click-events'; +import { useDappStatus } from 'modules/web3'; + +import { Section, MatomoLink } from 'shared/components'; +import { useLidoApr, useLidoStats } from 'shared/hooks'; +import { useTokenAddress } from 'shared/hooks/use-token-address'; +import { getEtherscanTokenLink } from 'utils/etherscan'; import { FlexCenterVertical } from './styles'; import { LidoStatsItem } from './lido-stats-item'; @@ -21,17 +21,15 @@ const isStatItemAvailable = (val: any): boolean => { }; export const LidoStats: FC = memo(() => { - const { chainId } = useSDK(); - const etherscanLink = useMemo(() => { - return getEtherscanTokenLink( - chainId, - getTokenAddress(chainId, TOKENS.STETH), - ); - }, [chainId]); - + const { chainId } = useDappStatus(); const lidoApr = useLidoApr(); const lidoStats = useLidoStats(); + const stethAddress = useTokenAddress(LIDO_TOKENS.steth); + const etherscanLink = useMemo(() => { + return getEtherscanTokenLink(chainId, stethAddress ?? ''); + }, [chainId, stethAddress]); + const showApr = !config.ipfsMode || isStatItemAvailable(lidoApr.apr); const showTotalStaked = !config.ipfsMode || isStatItemAvailable(lidoStats.data.totalStaked); @@ -69,7 +67,7 @@ export const LidoStats: FC = memo(() => { } show={showApr} - loading={lidoApr.initialLoading} + loading={lidoApr.isLoading} dataTestId="lidoAPR" highlight > @@ -79,7 +77,7 @@ export const LidoStats: FC = memo(() => { {lidoStats.data.totalStaked} @@ -88,7 +86,7 @@ export const LidoStats: FC = memo(() => { {lidoStats.data.stakers} @@ -97,7 +95,7 @@ export const LidoStats: FC = memo(() => { {lidoStats.data.marketCap} diff --git a/features/stake/stake-faq/list/lido-fee.tsx b/features/stake/stake-faq/list/lido-fee.tsx index 6e0fa1eb8..e4baf6fb4 100644 --- a/features/stake/stake-faq/list/lido-fee.tsx +++ b/features/stake/stake-faq/list/lido-fee.tsx @@ -8,9 +8,9 @@ export const LidoFee: FC = () => { const protocolFee = useProtocolFee(); const feeValue = - protocolFee.initialLoading || !protocolFee.data + protocolFee.isLoading || !protocolFee.totalFeeString ? DATA_UNAVAILABLE - : `${protocolFee.data}%`; + : `${protocolFee.totalFeeString}%`; return ( diff --git a/features/stake/stake-form/hooks.ts b/features/stake/stake-form/hooks.ts index 96718bc2c..6c77a8990 100644 --- a/features/stake/stake-form/hooks.ts +++ b/features/stake/stake-form/hooks.ts @@ -1,29 +1,22 @@ -import { BigNumber } from 'ethers'; -import { AddressZero } from '@ethersproject/constants'; -import { useLidoSWR, useSDK, useSTETHContractRPC } from '@lido-sdk/react'; - +import { useQuery } from '@tanstack/react-query'; +import { zeroAddress } from 'viem'; import { config } from 'config'; -import { STRATEGY_CONSTANT } from 'consts/swr-strategies'; - -import { applyGasLimitRatio } from 'utils/apply-gas-limit-ratio'; - -type UseStethSubmitGasLimit = () => BigNumber; +import { STRATEGY_CONSTANT } from 'consts/react-query-strategies'; +import { useLidoSDK, ESTIMATE_AMOUNT } from 'modules/web3'; -export const useStethSubmitGasLimit: UseStethSubmitGasLimit = () => { - const stethContractRPC = useSTETHContractRPC(); +export const useStethSubmitGasLimit = (): bigint => { + const { stake } = useLidoSDK(); - const { chainId } = useSDK(); - const { data } = useLidoSWR( - ['submit-gas-limit', chainId], - async () => { - const gasLimit = await stethContractRPC.estimateGas.submit(AddressZero, { - from: config.ESTIMATE_ACCOUNT, - value: config.ESTIMATE_AMOUNT, - }); - return applyGasLimitRatio(gasLimit); - }, - STRATEGY_CONSTANT, - ); + const { data } = useQuery({ + queryKey: ['submit-gas-limit', stake.core.chainId], + ...STRATEGY_CONSTANT, + queryFn: () => + stake.stakeEthEstimateGas({ + account: config.ESTIMATE_ACCOUNT, + value: ESTIMATE_AMOUNT, + referralAddress: zeroAddress, + }), + }); return data ?? config.STAKE_GASLIMIT_FALLBACK; }; diff --git a/features/stake/stake-form/hooks/use-tx-modal-stages-stake.tsx b/features/stake/stake-form/hooks/use-tx-modal-stages-stake.tsx index 81ed26b40..6c40068dc 100644 --- a/features/stake/stake-form/hooks/use-tx-modal-stages-stake.tsx +++ b/features/stake/stake-form/hooks/use-tx-modal-stages-stake.tsx @@ -1,19 +1,19 @@ +import type { Hash } from 'viem'; +import { Button, Link } from '@lidofinance/lido-ui'; +import { trackEvent } from '@lidofinance/analytics-matomo'; + +import { MATOMO_CLICK_EVENTS } from 'consts/matomo-click-events'; + +import { LINK_EXPLORE_STRATEGIES } from 'shared/banners/vaults-banner-info/const'; import { TransactionModalTransitStage, useTransactionModalStage, } from 'shared/transaction-modal/hooks/use-transaction-modal-stage'; import { getGeneralTransactionModalStages } from 'shared/transaction-modal/hooks/get-general-transaction-modal-stages'; - -import { Button, Link } from '@lidofinance/lido-ui'; import { VaultsBannerInfo } from 'shared/banners/vaults-banner-info'; import { TxStageSignOperationAmount } from 'shared/transaction-modal/tx-stages-composed/tx-stage-amount-operation'; import { TxStageOperationSucceedBalanceShown } from 'shared/transaction-modal/tx-stages-composed/tx-stage-operation-succeed-balance-shown'; -import type { BigNumber } from 'ethers'; -import { trackEvent } from '@lidofinance/analytics-matomo'; -import { MATOMO_CLICK_EVENTS } from 'consts/matomo-click-events'; -import { LINK_EXPLORE_STRATEGIES } from 'shared/banners/vaults-banner-info/const'; - const STAGE_OPERATION_ARGS = { token: 'ETH', willReceiveToken: 'stETH', @@ -23,7 +23,7 @@ const STAGE_OPERATION_ARGS = { const getTxModalStagesStake = (transitStage: TransactionModalTransitStage) => ({ ...getGeneralTransactionModalStages(transitStage), - sign: (amount: BigNumber) => + sign: (amount: bigint) => transitStage( ({ />, ), - pending: (amount: BigNumber, txHash?: string) => + pending: (amount: bigint, txHash?: Hash) => transitStage( ({ />, ), - success: (balance: BigNumber, txHash?: string) => + success: (balance: bigint, txHash?: Hash) => transitStage( { } = useStethBalance(); const { isMultisig, isLoading: isMultisigLoading } = useIsMultisig(); const gasLimit = useStethSubmitGasLimit(); - const { maxGasPrice, initialLoading: isMaxGasPriceLoading } = - useMaxGasPrice(); + const { maxGasPrice, isLoading: isMaxGasPriceLoading } = useMaxGasPrice(); const gasCost = useMemo( - () => (gasLimit && maxGasPrice ? gasLimit.mul(maxGasPrice) : undefined), + () => (gasLimit && maxGasPrice ? gasLimit * maxGasPrice : undefined), [gasLimit, maxGasPrice], ); @@ -79,14 +80,14 @@ const useStakeFormNetworkData = (): StakeFormNetworkData => { const { data: stakingLimitInfo, - mutate: mutateStakeLimit, - initialLoading: isStakingLimitLoading, + refetch: refetchStakeLimit, + isLoading: isStakingLimitIsLoading, } = useStakingLimitInfo(); const stakeableEther = useMemo(() => { - if (!etherBalance || !stakingLimitInfo) return undefined; + if (etherBalance === undefined || !stakingLimitInfo) return undefined; if (etherBalance && stakingLimitInfo.isStakingLimitSet) { - return etherBalance.lt(stakingLimitInfo.currentStakeLimit) + return etherBalance < stakingLimitInfo.currentStakeLimit ? etherBalance : stakingLimitInfo.currentStakeLimit; } @@ -98,7 +99,7 @@ const useStakeFormNetworkData = (): StakeFormNetworkData => { limit: stakingLimitInfo?.currentStakeLimit, isPadded: !isMultisig, gasLimit: gasLimit, - padding: config.BALANCE_PADDING, + padding: BALANCE_PADDING, isLoading: isMultisigLoading, }); @@ -106,14 +107,9 @@ const useStakeFormNetworkData = (): StakeFormNetworkData => { await Promise.allSettled([ updateStethBalance(), updateEtherBalance(), - mutateStakeLimit(stakingLimitInfo), + refetchStakeLimit(), ]); - }, [ - updateStethBalance, - updateEtherBalance, - mutateStakeLimit, - stakingLimitInfo, - ]); + }, [updateStethBalance, updateEtherBalance, refetchStakeLimit]); const loading = useMemo( () => ({ @@ -121,14 +117,14 @@ const useStakeFormNetworkData = (): StakeFormNetworkData => { isMultisigLoading, isMaxGasPriceLoading, isEtherBalanceLoading, - isStakeableEtherLoading: isStakingLimitLoading || isEtherBalanceLoading, + isStakeableEtherLoading: isStakingLimitIsLoading || isEtherBalanceLoading, }), [ - isEtherBalanceLoading, - isMaxGasPriceLoading, - isMultisigLoading, isStethBalanceLoading, - isStakingLimitLoading, + isMultisigLoading, + isMaxGasPriceLoading, + isEtherBalanceLoading, + isStakingLimitIsLoading, ], ); @@ -177,8 +173,8 @@ export const StakeFormProvider: FC = ({ children }) => { } if (typeof amount === 'string') { void replace({ pathname, query: rest }); - const amountBN = parseEther(amount); - setValue('amount', amountBN); + const amountBigInt = parseEther(amount); + setValue('amount', amountBigInt); } } catch { //noop diff --git a/features/stake/stake-form/stake-form-context/types.ts b/features/stake/stake-form/stake-form-context/types.ts index 6a920cead..9bb6675c3 100644 --- a/features/stake/stake-form/stake-form-context/types.ts +++ b/features/stake/stake-form/stake-form-context/types.ts @@ -1,11 +1,10 @@ -import { BigNumber } from 'ethers'; import { type StakeLimitFullInfo } from 'shared/hooks/useStakingLimitInfo'; import { LIMIT_LEVEL } from 'types'; export type StakeFormDataContextValue = StakeFormNetworkData; export type StakeFormInput = { - amount: BigNumber | null; + amount: bigint | null; referral: string | null; }; @@ -18,14 +17,14 @@ export type StakeFormLoading = { }; export type StakeFormNetworkData = { - etherBalance?: BigNumber; + etherBalance?: bigint; isMultisig?: boolean; - stethBalance?: BigNumber; - stakeableEther?: BigNumber; + stethBalance?: bigint; + stakeableEther?: bigint; stakingLimitInfo?: StakeLimitFullInfo; - gasLimit?: BigNumber; - gasCost?: BigNumber; - maxAmount?: BigNumber; + gasLimit?: bigint; + gasCost?: bigint; + maxAmount?: bigint; loading: StakeFormLoading; revalidate: () => Promise; }; @@ -33,8 +32,8 @@ export type StakeFormNetworkData = { export type StakeFormValidationContext = { isWalletActive: boolean; stakingLimitLevel: LIMIT_LEVEL; - currentStakeLimit: BigNumber; - gasCost: BigNumber; - etherBalance: BigNumber; + currentStakeLimit: bigint; + gasCost: bigint; + etherBalance: bigint; isMultisig: boolean; }; diff --git a/features/stake/stake-form/stake-form-context/validation.ts b/features/stake/stake-form/stake-form-context/validation.ts index b205ee76a..7cfcf7a97 100644 --- a/features/stake/stake-form/stake-form-context/validation.ts +++ b/features/stake/stake-form/stake-form-context/validation.ts @@ -1,21 +1,21 @@ import { useMemo } from 'react'; +import type { Resolver } from 'react-hook-form'; import invariant from 'tiny-invariant'; -import { Zero } from '@ethersproject/constants'; -import { validateEtherAmount } from 'shared/hook-form/validation/validate-ether-amount'; import { useDappStatus } from 'modules/web3'; import { VALIDATION_CONTEXT_TIMEOUT } from 'features/withdrawals/withdrawals-constants'; +import { TOKENS_TO_WRAP } from 'features/wsteth/shared/types'; +import { useAwaiter } from 'shared/hooks/use-awaiter'; +import { validateStakeEth } from 'shared/hook-form/validation/validate-stake-eth'; +import { validateEtherAmount } from 'shared/hook-form/validation/validate-ether-amount'; import { handleResolverValidationError } from 'shared/hook-form/validation/validation-error'; import { awaitWithTimeout } from 'utils/await-with-timeout'; -import { useAwaiter } from 'shared/hooks/use-awaiter'; -import type { Resolver } from 'react-hook-form'; import type { StakeFormInput, StakeFormNetworkData, StakeFormValidationContext, } from './types'; -import { validateStakeEth } from 'shared/hook-form/validation/validate-stake-eth'; export const stakeFormValidationResolver: Resolver< StakeFormInput, @@ -28,7 +28,7 @@ export const stakeFormValidationResolver: Resolver< 'validation context must be presented as context promise', ); - validateEtherAmount('amount', amount, 'ETH'); + validateEtherAmount('amount', amount, TOKENS_TO_WRAP.ETH); const { isWalletActive, @@ -74,19 +74,23 @@ export const useStakeFormValidationContext = ( ): Promise => { const { isDappActive } = useDappStatus(); const { stakingLimitInfo, etherBalance, isMultisig, gasCost } = networkData; + const validationContextAwaited = useMemo(() => { if ( stakingLimitInfo && // we ether not connected or must have all account related data - (!isDappActive || (etherBalance && gasCost && isMultisig !== undefined)) + (!isDappActive || + (etherBalance !== undefined && + gasCost !== undefined && + isMultisig !== undefined)) ) { return { isWalletActive: isDappActive, stakingLimitLevel: stakingLimitInfo.stakeLimitLevel, currentStakeLimit: stakingLimitInfo.currentStakeLimit, // condition above guaranties stubs will only be passed when isDappActive = false - etherBalance: etherBalance ?? Zero, - gasCost: gasCost ?? Zero, + etherBalance: etherBalance ?? 0n, + gasCost: gasCost ?? 0n, isMultisig: isMultisig ?? false, }; } diff --git a/features/stake/stake-form/stake-form-info.tsx b/features/stake/stake-form/stake-form-info.tsx index d2252f674..f004a929c 100644 --- a/features/stake/stake-form/stake-form-info.tsx +++ b/features/stake/stake-form/stake-form-info.tsx @@ -1,6 +1,5 @@ import { useWatch } from 'react-hook-form'; -import { Zero } from '@ethersproject/constants'; import { DataTable, DataTableRow } from '@lidofinance/lido-ui'; import { DATA_UNAVAILABLE } from 'consts/text'; @@ -14,13 +13,13 @@ export const StakeFormInfo = () => { const { gasCost, loading } = useStakeFormData(); const amount = useWatch({ name: 'amount' }); - const { usdAmount, initialLoading: isEthUsdLoading } = useEthUsd(gasCost); + const { usdAmount, isLoading: isEthUsdLoading } = useEthUsd(gasCost); const protocolFee = useProtocolFee(); return ( - + 1 ETH = 1 stETH @@ -35,11 +34,13 @@ export const StakeFormInfo = () => { - {!protocolFee.data ? DATA_UNAVAILABLE : `${protocolFee.data}%`} + {!protocolFee.totalFeeString + ? DATA_UNAVAILABLE + : `${protocolFee.totalFeeString}%`} ); diff --git a/features/stake/stake-form/use-stake.ts b/features/stake/stake-form/use-stake.ts index afd4c66e1..ae932ec1f 100644 --- a/features/stake/stake-form/use-stake.ts +++ b/features/stake/stake-form/use-stake.ts @@ -1,25 +1,21 @@ -import { BigNumber } from 'ethers'; +import type { Hash } from 'viem'; +import { getAddress as getAddressViem } from 'viem'; import { useCallback } from 'react'; import invariant from 'tiny-invariant'; import { - useSDK, - useSTETHContractRPC, - useSTETHContractWeb3, -} from '@lido-sdk/react'; + TransactionCallbackStage, + type TransactionCallback, +} from '@lidofinance/lido-ethereum-sdk'; import { config } from 'config'; -import { useCurrentStaticRpcProvider } from 'shared/hooks/use-current-static-rpc-provider'; -import { isContract } from 'utils/isContract'; -import { runWithTransactionLogger } from 'utils'; +import { applyRoundUpGasLimit, useDappStatus, useLidoSDK } from 'modules/web3'; -import { MockLimitReachedError, getAddress } from './utils'; +import { MockLimitReachedError, getRefferalAddress } from './utils'; import { useTxModalStagesStake } from './hooks/use-tx-modal-stages-stake'; -import { sendTx, useTxConfirmation, useDappStatus } from 'modules/web3'; - type StakeArguments = { - amount: BigNumber | null; + amount: bigint | null; referral: string | null; }; @@ -29,21 +25,15 @@ type StakeOptions = { }; export const useStake = ({ onConfirm, onRetry }: StakeOptions) => { - const stethContractWeb3 = useSTETHContractWeb3(); const { address } = useDappStatus(); - const stethContract = useSTETHContractRPC(); - const { staticRpcProvider } = useCurrentStaticRpcProvider(); - const { providerWeb3 } = useSDK(); + const { stake, stETH } = useLidoSDK(); const { txModalStages } = useTxModalStagesStake(); - const waitForTx = useTxConfirmation(); return useCallback( async ({ amount, referral }: StakeArguments): Promise => { try { invariant(amount, 'amount is null'); invariant(address, 'account is not defined'); - invariant(providerWeb3, 'providerWeb3 not defined'); - invariant(stethContractWeb3, 'steth is not defined'); if ( config.enableQaHelpers && @@ -52,54 +42,48 @@ export const useStake = ({ onConfirm, onRetry }: StakeOptions) => { throw new MockLimitReachedError('Stake limit reached'); } - txModalStages.sign(amount); - - const [isMultisig, referralAddress] = await Promise.all([ - isContract(address, staticRpcProvider), - referral - ? getAddress(referral, staticRpcProvider) - : config.STAKE_FALLBACK_REFERRAL_ADDRESS, - ]); - - const callback = async () => { - const tx = await stethContractWeb3.populateTransaction.submit( - referralAddress, - { - value: amount, - }, - ); - - return sendTx({ - tx, - isMultisig, - staticProvider: staticRpcProvider, - walletProvider: providerWeb3, - shouldApplyGasLimitRatio: true, - shouldRoundUpGasLimit: true, - }); + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const referralAddress = referral + ? await getRefferalAddress(referral, stake.core.rpcProvider) + : config.STAKE_FALLBACK_REFERRAL_ADDRESS; + + let txHash: Hash | undefined = undefined; + const txCallback: TransactionCallback = async ({ stage, payload }) => { + switch (stage) { + case TransactionCallbackStage.SIGN: + txModalStages.sign(amount); + return applyRoundUpGasLimit( + // the payload here is bigint + payload ?? config.STAKE_GASLIMIT_FALLBACK, + ); + case TransactionCallbackStage.RECEIPT: + txModalStages.pending(amount, payload); + // the payload here is txHash + txHash = payload; + break; + case TransactionCallbackStage.DONE: { + const [, balance] = await Promise.all([ + onConfirm?.(), + stETH.balance(address), + ]); + txModalStages.success(balance, txHash); + break; + } + case TransactionCallbackStage.MULTISIG_DONE: + txModalStages.successMultisig(); + break; + case TransactionCallbackStage.ERROR: + txModalStages.failed(payload, onRetry); + break; + default: + } }; - const txHash = await runWithTransactionLogger( - 'Stake signing', - callback, - ); - - if (isMultisig) { - txModalStages.successMultisig(); - return true; - } - - txModalStages.pending(amount, txHash); - - await runWithTransactionLogger('Stake block confirmation', () => - waitForTx(txHash), - ); - - const stethBalance = await stethContract.balanceOf(address); - - await onConfirm?.(); - - txModalStages.success(stethBalance, txHash); + await stake.stakeEth({ + value: amount, + callback: txCallback, + referralAddress: getAddressViem(referralAddress), + }); return true; } catch (error) { @@ -108,16 +92,6 @@ export const useStake = ({ onConfirm, onRetry }: StakeOptions) => { return false; } }, - [ - address, - providerWeb3, - stethContractWeb3, - txModalStages, - staticRpcProvider, - stethContract, - onConfirm, - waitForTx, - onRetry, - ], + [address, stake, txModalStages, onConfirm, stETH, onRetry], ); }; diff --git a/features/stake/stake-form/utils.ts b/features/stake/stake-form/utils.ts index 5f256852a..740b5f145 100644 --- a/features/stake/stake-form/utils.ts +++ b/features/stake/stake-form/utils.ts @@ -1,17 +1,19 @@ -import { isAddress } from 'ethers/lib/utils'; -import type { BaseProvider } from '@ethersproject/providers'; +import { PublicClient, isAddress } from 'viem'; +import { getEnsAddress } from 'viem/ens'; -export const getAddress = async ( +export const getRefferalAddress = async ( input: string, - providerRpc: BaseProvider, + provider: PublicClient, ): Promise => { try { if (isAddress(input)) return input; - const address = await providerRpc.resolveName(input); - if (address) return address; + const address = await getEnsAddress(provider, { name: input }); + if (address) return address.toString(); + return input; } catch { // noop } + // if code gets here, ref is invalid and we need to throw error throw new ReferralAddressError(); }; diff --git a/features/stake/stake-form/wallet/wallet.tsx b/features/stake/stake-form/wallet/wallet.tsx index daa1b3f7e..da3bc2cd5 100644 --- a/features/stake/stake-form/wallet/wallet.tsx +++ b/features/stake/stake-form/wallet/wallet.tsx @@ -1,4 +1,4 @@ -import { TOKENS } from '@lido-sdk/constants'; +import { LIDO_TOKENS } from '@lidofinance/lido-ethereum-sdk/common'; import { Divider, Question, Tooltip } from '@lidofinance/lido-ui'; import { LIDO_APR_TOOLTIP_TEXT, DATA_UNAVAILABLE } from 'consts/text'; @@ -17,7 +17,7 @@ import { FlexCenter, LidoAprStyled, StyledCard } from './styles'; const WalletComponent = () => { const { stakeableEther, stethBalance, loading } = useStakeFormData(); - const stethAddress = useTokenAddress(TOKENS.STETH); + const stethAddress = useTokenAddress(LIDO_TOKENS.steth); const lidoApr = useLidoApr(); return ( @@ -73,7 +73,7 @@ const WalletComponent = () => { )} } - loading={lidoApr.initialLoading} + loading={lidoApr.isLoading} value={ {lidoApr.apr ? `${lidoApr.apr}%` : DATA_UNAVAILABLE} diff --git a/features/stake/swap-discount-banner/integrations.tsx b/features/stake/swap-discount-banner/integrations.tsx index bfc676889..ac81651f5 100644 --- a/features/stake/swap-discount-banner/integrations.tsx +++ b/features/stake/swap-discount-banner/integrations.tsx @@ -1,5 +1,5 @@ -import { parseEther } from '@ethersproject/units'; -import { TOKENS } from '@lido-sdk/constants'; +import { parseEther } from 'viem'; +import { LIDO_TOKENS } from '@lidofinance/lido-ethereum-sdk'; import { OPEN_OCEAN_REFERRAL_ADDRESS } from 'consts/external-links'; import { MATOMO_CLICK_EVENTS } from 'consts/matomo-click-events'; @@ -12,6 +12,7 @@ import { StakeSwapDiscountIntegrationMap, } from './types'; import { OpenOceanIcon, OneInchIcon, OverlayLink } from './styles'; +import { TOKENS_TO_WITHDRAWLS } from '../../withdrawals/types/tokens-withdrawable'; const DEFAULT_AMOUNT = parseEther('1'); @@ -22,7 +23,7 @@ const STAKE_SWAP_INTEGRATION_CONFIG: StakeSwapDiscountIntegrationMap = { const { rate } = await getOpenOceanRate( DEFAULT_AMOUNT, 'ETH', - TOKENS.STETH, + TOKENS_TO_WITHDRAWLS.stETH, ); return rate; }, @@ -41,7 +42,7 @@ const STAKE_SWAP_INTEGRATION_CONFIG: StakeSwapDiscountIntegrationMap = { 'one-inch': { title: '1inch', async getRate() { - const { rate } = await getOneInchRate({ token: 'ETH' }); + const { rate } = await getOneInchRate({ token: LIDO_TOKENS.eth }); return rate; }, BannerText({ discountPercent }) { diff --git a/features/stake/swap-discount-banner/swap-discount-banner.tsx b/features/stake/swap-discount-banner/swap-discount-banner.tsx index 9305236af..f1914cc3d 100644 --- a/features/stake/swap-discount-banner/swap-discount-banner.tsx +++ b/features/stake/swap-discount-banner/swap-discount-banner.tsx @@ -5,9 +5,9 @@ import { useSwapDiscount } from './use-swap-discount'; import { Wrap, TextWrap, OverlayLink } from './styles'; export const SwapDiscountBanner = ({ children }: React.PropsWithChildren) => { - const { data, initialLoading } = useSwapDiscount(); + const { data, isLoading } = useSwapDiscount(); - if (initialLoading) return null; + if (isLoading) return null; if (!data || !data.shouldShowDiscount) return <>{children}; diff --git a/features/stake/swap-discount-banner/use-swap-discount.ts b/features/stake/swap-discount-banner/use-swap-discount.ts index 0f9457e9e..16a62207a 100644 --- a/features/stake/swap-discount-banner/use-swap-discount.ts +++ b/features/stake/swap-discount-banner/use-swap-discount.ts @@ -1,7 +1,6 @@ -import { useLidoSWR } from '@lido-sdk/react'; - +import { useQuery } from '@tanstack/react-query'; import { config } from 'config'; -import { STRATEGY_LAZY } from 'consts/swr-strategies'; +import { STRATEGY_LAZY } from 'consts/react-query-strategies'; import { getSwapIntegration } from './integrations'; import type { @@ -23,7 +22,6 @@ if (config.enableQaHelpers && typeof window !== 'undefined') { // we show banner if STETH is considerably cheaper to get on dex than staking // ETH -> stETH rate > THRESHOLD const fetchRate = async ( - _: string, integrationKey: StakeSwapDiscountIntegrationKey, ): Promise => { const integration = getSwapIntegration(integrationKey); @@ -43,19 +41,17 @@ const fetchRate = async ( }; export const useSwapDiscount = () => { - return useLidoSWR( - ['swr:swap-discount-rate', config.STAKE_SWAP_INTEGRATION], - // @ts-expect-error useLidoSWR has broken fetcher-key type signature - fetchRate, - { - ...STRATEGY_LAZY, - onError(error, key) { - console.warn( - `[useSwapDiscount] Error fetching ETH->Steth:`, - key, - error, - ); - }, + return useQuery({ + queryKey: ['swap-discount-rate', config.STAKE_SWAP_INTEGRATION], + ...STRATEGY_LAZY, + queryFn: async () => { + try { + return await fetchRate(config.STAKE_SWAP_INTEGRATION); + } catch (err) { + console.warn(`[useSwapDiscount] Error fetching ETH -> stETH: ${err}`); + // This line is necessary so that useQuery can handle the error and return undefined + throw err; + } }, - ); + }); }; diff --git a/features/withdrawals/claim/claim-form-context/use-helper-state.ts b/features/withdrawals/claim/claim-form-context/use-helper-state.ts index c1392bff0..af29445d1 100644 --- a/features/withdrawals/claim/claim-form-context/use-helper-state.ts +++ b/features/withdrawals/claim/claim-form-context/use-helper-state.ts @@ -1,7 +1,5 @@ import { useEffect, useState } from 'react'; import { type UseFormWatch } from 'react-hook-form'; -import { Zero } from '@ethersproject/constants'; -import { type BigNumber } from 'ethers'; import { RequestStatusClaimable } from 'features/withdrawals/types/request-status'; @@ -9,7 +7,7 @@ import { ClaimFormInputType } from './types'; export type ClaimFormHelperState = { selectedRequests: RequestStatusClaimable[]; - ethToClaim: BigNumber; + ethToClaim: bigint; canSelectMore: boolean; requestsCount: number; }; @@ -17,7 +15,7 @@ export type ClaimFormHelperState = { const initState = (): ClaimFormHelperState => ({ selectedRequests: [], canSelectMore: true, - ethToClaim: Zero, + ethToClaim: 0n, requestsCount: 0, }); @@ -37,8 +35,8 @@ export const useHelperState = ( .map((r) => r?.status as RequestStatusClaimable) ?? []; const ethToClaim = selectedRequests.reduce((ethSum, request) => { - return ethSum.add(request?.claimableEth ?? Zero); - }, Zero); + return ethSum + (request?.claimableEth ?? 0n); + }, 0n); setHelperState({ selectedRequests, diff --git a/features/withdrawals/claim/form/requests-list/request-item.tsx b/features/withdrawals/claim/form/requests-list/request-item.tsx index 8bae6e15c..1028e16ff 100644 --- a/features/withdrawals/claim/form/requests-list/request-item.tsx +++ b/features/withdrawals/claim/form/requests-list/request-item.tsx @@ -7,14 +7,15 @@ import { External, Tooltip, } from '@lidofinance/lido-ui'; +import type { LIDO_CONTRACT_NAMES } from '@lidofinance/lido-ethereum-sdk/common'; + import { FormatToken } from 'shared/formatters'; +import { useDappStatus, useContractAddress } from 'modules/web3'; +import { getNFTUrl } from 'utils'; -import { RequestStatus } from './request-item-status'; import { useClaimFormData, ClaimFormInputType } from '../../claim-form-context'; - -import { getNFTUrl } from 'utils'; +import { RequestStatus } from './request-item-status'; import { RequestStyled, LinkStyled } from './styles'; -import { useSDK } from '@lido-sdk/react'; type RequestItemProps = { token_id: string; @@ -24,7 +25,7 @@ type RequestItemProps = { export const RequestItem = forwardRef( ({ token_id, name, disabled, index, ...props }, ref) => { - const { chainId } = useSDK(); + const { chainId } = useDappStatus(); const { isSubmitting } = useFormState(); const { canSelectMore, maxSelectedCountReason } = useClaimFormData(); const { checked, status } = useWatch< @@ -34,6 +35,10 @@ export const RequestItem = forwardRef( name: `requests.${index}`, }); + const { data: withdrawalQueueAddress } = useContractAddress( + 'withdrawalQueue' as LIDO_CONTRACT_NAMES, + ); + const isDisabled = disabled || !status.isFinalized || @@ -79,7 +84,7 @@ export const RequestItem = forwardRef( /> diff --git a/features/withdrawals/claim/form/submit-button.tsx b/features/withdrawals/claim/form/submit-button.tsx index 3f5f18f79..d908687ad 100644 --- a/features/withdrawals/claim/form/submit-button.tsx +++ b/features/withdrawals/claim/form/submit-button.tsx @@ -1,14 +1,14 @@ import { useFormState } from 'react-hook-form'; import { Button } from '@lidofinance/lido-ui'; -import { Zero } from '@ethersproject/constants'; import { Connect, DisabledButton } from 'shared/wallet'; import { FormatToken } from 'shared/formatters/format-token'; import { isValidationErrorTypeUnhandled } from 'shared/hook-form/validation/validation-error'; -import { ClaimFormInputType, useClaimFormData } from '../claim-form-context'; import { useDappStatus } from 'modules/web3'; +import { ClaimFormInputType, useClaimFormData } from '../claim-form-context'; + export const SubmitButton = () => { const { isSupportedChain, isWalletConnected } = useDappStatus(); @@ -28,9 +28,9 @@ export const SubmitButton = () => { !isValidationErrorTypeUnhandled(errors.requests.type)) || selectedRequests.length === 0; - const claimButtonAmount = ethToClaim.lte(Zero) ? null : ( + const claimButtonAmount = ethToClaim ? ( - ); + ) : null; return (