From 7d1d7506aa824e67ed1da47a3fb217b11077c1f6 Mon Sep 17 00:00:00 2001 From: cyrbuzz Date: Tue, 27 Feb 2024 18:19:59 +0800 Subject: [PATCH 1/6] feat: style --- src/config/rainbowConf.tsx | 3 +- src/containers/Web3.tsx | 7 +- src/hooks/useInitContracts.ts | 25 +-- src/pages/bridge/index.module.less | 42 +++- src/pages/bridge/index.tsx | 331 ++++++++++++++++++++++------- src/stores/web3Account.ts | 12 +- 6 files changed, 317 insertions(+), 103 deletions(-) diff --git a/src/config/rainbowConf.tsx b/src/config/rainbowConf.tsx index dc8c1ed51..0ec5d5833 100644 --- a/src/config/rainbowConf.tsx +++ b/src/config/rainbowConf.tsx @@ -20,7 +20,8 @@ import '@rainbow-me/rainbowkit/styles.css'; const supportedChains = import.meta.env.VITE_NETWORK === 'testnet' ? [baseSepolia, sepolia] : [base, mainnet]; export const tipsChainIds: number[] = import.meta.env.VITE_NETWORK === 'testnet' ? [baseSepolia.id] : [base.id]; -export const tipsL1ChainIds: number[] = import.meta.env.VITE_NETWORK === 'testnet' ? [sepolia.id] : [mainnet.id]; +export const tipsL1ChainIds: number[] = + import.meta.env.VITE_NETWORK === 'testnet' ? [sepolia.id, baseSepolia.id] : [mainnet.id, base.id]; // This should ok. It seems is a bug of Ts. // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore diff --git a/src/containers/Web3.tsx b/src/containers/Web3.tsx index 6d9b8cada..66a437758 100644 --- a/src/containers/Web3.tsx +++ b/src/containers/Web3.tsx @@ -1,11 +1,11 @@ // Copyright 2020-2022 SubQuery Pte Ltd authors & contributors // SPDX-License-Identifier: Apache-2.0 -import React from 'react'; import mainnetJSON from '@subql/contract-sdk/publish/mainnet.json'; import testnetJSON from '@subql/contract-sdk/publish/testnet.json'; import { NETWORKS_CONFIG_INFO, SQNetworks } from '@subql/network-config'; -import { useAccount } from 'wagmi'; +import { base, baseSepolia } from 'viem/chains'; +import { mainnet, sepolia, useAccount } from 'wagmi'; export const NETWORK_NAME: SQNetworks = import.meta.env.VITE_NETWORK; export const isMainnet = import.meta.env.VITE_NETWORK === 'mainnet'; @@ -16,6 +16,9 @@ export const ECOSYSTEM_NETWORK = NETWORKS_CONFIG_INFO[SUPPORTED_NETWORK].chainNa export const NETWORK_DEPLOYMENT_DETAILS = isMainnet ? mainnetJSON : testnetJSON; +export const l1Chain = import.meta.env.VITE_NETWORK === 'testnet' ? sepolia : mainnet; +export const l2Chain = import.meta.env.VITE_NETWORK === 'testnet' ? baseSepolia : base; + // TODO: FIXME, Mainnet dont have this yet // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore diff --git a/src/hooks/useInitContracts.ts b/src/hooks/useInitContracts.ts index 35d43346c..94afcc884 100644 --- a/src/hooks/useInitContracts.ts +++ b/src/hooks/useInitContracts.ts @@ -2,14 +2,12 @@ // SPDX-License-Identifier: Apache-2.0 import React from 'react'; -import { NETWORK_NAME } from '@containers/Web3'; -import mainnetJSON from '@subql/contract-sdk/publish/mainnet.json'; -import testnetJSON from '@subql/contract-sdk/publish/testnet.json'; +import { l1Chain, l2Chain, NETWORK_NAME } from '@containers/Web3'; +import { RootContractSDK } from '@subql/contract-sdk/rootSdk'; import { ContractSDK } from '@subql/contract-sdk/sdk'; -import { SQToken__factory } from '@subql/contract-sdk/typechain/factories/contracts/root/SQToken__factory'; import { ContractClient } from '@subql/network-clients'; import { parseError } from '@utils'; -import { mainnet, sepolia } from 'viem/chains'; +import { base, baseSepolia, mainnet, sepolia } from 'viem/chains'; import { useWeb3Store } from 'src/stores'; @@ -23,12 +21,18 @@ export function useInitContracts(): { loading: boolean } { const ethereumProvider = useEthersProviderWithPublic({ chainId: import.meta.env.MODE === 'testnet' ? sepolia.id : mainnet.id, }); + const baseProvider = useEthersProviderWithPublic({ + chainId: import.meta.env.MODE === 'testnet' ? baseSepolia.id : base.id, + }); React.useEffect(() => { function initContract() { if (signer || provider) { try { - const contractInstance = ContractSDK.create(signer || provider, { network: NETWORK_NAME }); + const contractInstance = ContractSDK.create( + signer?.provider.network.chainId === l2Chain.id ? signer : baseProvider, + { network: NETWORK_NAME }, + ); setContracts(contractInstance); @@ -42,13 +46,10 @@ export function useInitContracts(): { loading: boolean } { } if (ethereumProvider) { - const sqTokenContract = SQToken__factory.connect( - import.meta.env.MODE === 'testnet' ? testnetJSON.root.SQToken.address : mainnetJSON.root.SQToken.address, - ethereumProvider, + const rootContractInstance = RootContractSDK.create( + signer?.provider.network.chainId === l1Chain.id ? signer : ethereumProvider, + { network: NETWORK_NAME }, ); - const rootContractInstance = { - sqToken: sqTokenContract, - }; setRootContracts(rootContractInstance); } } diff --git a/src/pages/bridge/index.module.less b/src/pages/bridge/index.module.less index 384f092ce..c907cecda 100644 --- a/src/pages/bridge/index.module.less +++ b/src/pages/bridge/index.module.less @@ -11,8 +11,9 @@ flex-direction: column; align-items: center; height: 100%; - padding: 40px; - max-width: 568px; + padding: 40px 0; + max-width: 582px; + width: 582px; gap: 10px; &Tabs { @@ -34,13 +35,13 @@ } .ant-tabs-ink-bar { - background: linear-gradient(96.26deg, #4388DD 13.8%, #FF4581 82.83%); + background: linear-gradient(96.26deg, #4388dd 13.8%, #ff4581 82.83%); } } } &Content { - border: 1px solid #DFE3E899; + border: 1px solid #dfe3e899; border-radius: 8px; padding: 24px; width: 100%; @@ -52,8 +53,8 @@ .smallCard { border-radius: 8px; border: 1px solid var(--sq-gray300); - width: 100%; - + width: 360px; + .top { background: var(--sq-gray200); padding: 16px; @@ -78,6 +79,9 @@ .input { text-align: center; border: none; + width: 100%; + box-shadow: none; + &:focus { border: none; outline: none; @@ -87,6 +91,32 @@ &:focus-visible { outline: none; } + + :global { + .ant-input-number-input { + text-align: center; + border: none; + &-wrap { + &:focus { + border: none; + outline: none; + box-shadow: none; + } + + &:focus-visible { + outline: none; + } + } + } + } + } + } +} + +.confirmModal { + :global { + .ant-modal-confirm-title { + font-family: var(--sq-font-family); } } } diff --git a/src/pages/bridge/index.tsx b/src/pages/bridge/index.tsx index bec556d28..1a507f34c 100644 --- a/src/pages/bridge/index.tsx +++ b/src/pages/bridge/index.tsx @@ -6,22 +6,20 @@ import { BsArrowDownSquareFill, BsLifePreserver } from 'react-icons/bs'; import { useNavigate } from 'react-router'; import { WalletRoute } from '@components'; import { useSQToken } from '@containers'; +import { l1Chain, l2Chain } from '@containers/Web3'; import { CrossChainMessenger } from '@eth-optimism/sdk/src/cross-chain-messenger'; import { publicClientToProvider, useEthersSigner } from '@hooks/useEthersProvider'; -import { Footer, openNotification, Spinner, Typography } from '@subql/components'; +import { Footer, Modal, openNotification, Spinner, Steps, Typography } from '@subql/components'; import mainnetJSON from '@subql/contract-sdk/publish/mainnet.json'; import testnetJSON from '@subql/contract-sdk/publish/testnet.json'; import { formatEther } from '@subql/react-hooks'; -import { Button, Input, Tabs } from 'antd'; +import { Button, InputNumber, Tabs } from 'antd'; +import { clsx } from 'clsx'; import { parseEther } from 'ethers/lib/utils'; -import { base, baseSepolia } from 'viem/chains'; -import { mainnet, sepolia, usePublicClient } from 'wagmi'; +import { useNetwork, usePublicClient, useSwitchNetwork } from 'wagmi'; import styles from './index.module.less'; -const l1Chain = import.meta.env.VITE_NETWORK === 'testnet' ? sepolia : mainnet; -const l2Chain = import.meta.env.VITE_NETWORK === 'testnet' ? baseSepolia : base; - const l1ContractTokenAddress = import.meta.env.VITE_NETWORK === 'testnet' ? testnetJSON.root.SQToken.address : mainnetJSON.root.SQToken.address; const l2ContractTokenAddress = @@ -30,13 +28,19 @@ const l2ContractTokenAddress = : mainnetJSON.child.L2SQToken.address; const Bridge: FC = () => { - const { ethSqtBalance } = useSQToken(); + const { ethSqtBalance, balance } = useSQToken(); const { signer } = useEthersSigner(); + const { chain } = useNetwork(); + const navigate = useNavigate(); const [val, setVal] = useState('0'); const [loading, setLoading] = useState(false); const [crossChainMessengerIns, setCrossChainMessengerIns] = useState(); const publicClient = usePublicClient({ chainId: l2Chain.id }); + const publicClientL1 = usePublicClient({ chainId: l1Chain.id }); + const { switchNetwork } = useSwitchNetwork(); + + const [currentTab, setCurrentTab] = useState<'ethToBase' | 'baseToEth'>('ethToBase'); const initCrossChainMessenger = async () => { if (!signer) return; @@ -44,8 +48,10 @@ const Bridge: FC = () => { const newCrossChainMessenger = new CrossChainMessenger({ l1ChainId: l1Chain.id, l2ChainId: l2Chain.id, - l1SignerOrProvider: signer, - l2SignerOrProvider: publicClientToProvider(publicClient), + l1SignerOrProvider: + signer.provider.network.chainId === l1Chain.id ? signer : publicClientToProvider(publicClientL1), + l2SignerOrProvider: + signer.provider.network.chainId === l2Chain.id ? signer : publicClientToProvider(publicClient), }); setCrossChainMessengerIns(newCrossChainMessenger); @@ -94,6 +100,73 @@ const Bridge: FC = () => { } }; + const withdrawStart = async () => { + if (!crossChainMessengerIns) return; + await Modal.confirm({ + width: 572, + className: styles.confirmModal, + title: 'Confirm Bridge', + closable: true, + icon: null, + content: ( +
+
+
+
+ + {val || '0'} + +
+
+ + SQT +
+
+ +
+
+ + {val || '0'} + +
+
+ + SQT +
+
+
+ + OP stack and Base requires that any bridging to Ethereum requires a 7 day withdraw period. If you do not + want to wait for the required 7 days, please consider a{' '} + + third party bridge + + . + +
+ ), + cancelButtonProps: { + style: { display: 'none' }, + }, + okText: `Confirm Bridge for ${(+val).toLocaleString()} SQT`, + okButtonProps: { + shape: 'round', + }, + }); + try { + setLoading(true); + const amount = parseEther(val); + } catch (e: any) { + console.error(e); + openNotification({ + type: 'error', + description: e.message, + }); + } finally { + setLoading(false); + } + }; + useEffect(() => { initCrossChainMessenger(); }, [signer]); @@ -114,89 +187,199 @@ const Bridge: FC = () => { { + setCurrentTab(key as 'ethToBase' | 'baseToEth'); + setVal('0'); + }} items={[ { - label: 'ETH -> BASE', + label: 'Ethereum -> Base', key: 'ethToBase', }, + { + label: 'Base -> Ethereum', + key: 'baseToEth', + }, ]} > -
-
- - FREE SQT - - - {ethSqtBalance.result.loading ? ( - - ) : ( - formatEther(ethSqtBalance.result.data || 0, 4) - )}{' '} - SQT - -
-
-
- - SQT + {currentTab === 'ethToBase' && ( +
+
+ + FREE SQT + + + {ethSqtBalance.result.loading ? ( + + ) : ( + formatEther(ethSqtBalance.result.data || 0, 4) + )}{' '} + SQT +
+
+
+ + SQT +
-
- { - const numericValue = newVal.target.value.replace(/[^0-9.]/g, ''); - setVal(numericValue); - }} - > +
+ { + setVal(newVal?.toString() || ''); + }} + > +
-
- -
-
- - SQT + +
+
+ + SQT +
+ +
+ + {val || '0'} + +
-
- - {val || '0'} +
+ + Transfer time: A few minutes
-
-
- - Transfer time: A few minutes + + + + +
+ Need help? please message #network-bridge-support on + Discord +
- {/* - Network fee (est.): 0.000000066 ETH ($0.000194 USD) - */}
+ )} - - - - -
- Need help? please message #network-bridge-support on - Discord + {currentTab === 'baseToEth' && ( +
+
+ + OP stack and Base requires that any bridging to Ethereum requires a 7 day withdraw period. If you do + not want to wait for the required 7 days, please consider a{' '} + + third party bridge + + . + + + + + + FREE SQT + + + {balance.result.loading ? : formatEther(balance.result.data || 0, 4)}{' '} + SQT +
- -
+
+
+ + SQT +
+ +
+ { + setVal(newVal?.toString() || ''); + }} + > +
+
+ +
+
+ + SQT +
+ +
+ + {val || '0'} + +
+
+ + + + + +
+ Need help? please message #network-bridge-support on + Discord +
+
+
+ )}
diff --git a/src/stores/web3Account.ts b/src/stores/web3Account.ts index 7c55c533a..f66cc11a6 100644 --- a/src/stores/web3Account.ts +++ b/src/stores/web3Account.ts @@ -1,8 +1,8 @@ // Copyright 2020-2022 SubQuery Pte Ltd authors & contributors // SPDX-License-Identifier: Apache-2.0 +import { RootContractSDK } from '@subql/contract-sdk/rootSdk'; import { ContractSDK } from '@subql/contract-sdk/sdk'; -import { SQToken } from '@subql/contract-sdk/typechain/contracts/root/SQToken'; import { ContractClient } from '@subql/network-clients'; import { ethers } from 'ethers'; import { create } from 'zustand'; @@ -13,10 +13,6 @@ import { create } from 'zustand'; * */ -interface rootContracts { - sqToken: SQToken; -} - interface Web3Store { error?: any; setError: (error: any) => void; @@ -32,8 +28,8 @@ interface Web3Store { contracts?: ContractSDK; setContracts: (contracts: ContractSDK) => void; - rootContracts?: rootContracts; - setRootContracts: (rootContracts: rootContracts) => void; + rootContracts?: RootContractSDK; + setRootContracts: (rootContracts: RootContractSDK) => void; contractClient?: ContractClient; setContractClient: (contracts: ContractClient) => void; @@ -44,7 +40,7 @@ export const useWeb3Store = create()((set) => ({ contracts: undefined, isInitialAccount: false, rootContracts: undefined, - setRootContracts: (rootContracts: rootContracts | undefined) => set((state) => ({ ...state, rootContracts })), + setRootContracts: (rootContracts: RootContractSDK | undefined) => set((state) => ({ ...state, rootContracts })), ethProvider: () => { const providers = [ new ethers.providers.JsonRpcProvider('https://eth.llamarpc.com'), From 8e07ebac251561ecf0189eb9a73e90380408da31 Mon Sep 17 00:00:00 2001 From: cyrbuzz Date: Wed, 28 Feb 2024 10:29:54 +0800 Subject: [PATCH 2/6] feat: change capture --- src/utils/parseError.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/utils/parseError.ts b/src/utils/parseError.ts index 145ffb9b2..358337421 100644 --- a/src/utils/parseError.ts +++ b/src/utils/parseError.ts @@ -122,7 +122,11 @@ export function parseError( const generalErrorMsg = () => { try { - captureException(error); + captureException('Unknown error, need review', { + extra: { + error: rawErrorMsg, + }, + }); } finally { return 'Unfortunately, something went wrong.'; } From 307c6f639d5fb4cd486e904ee940b457e56469b4 Mon Sep 17 00:00:00 2001 From: cyrbuzz Date: Wed, 28 Feb 2024 16:02:49 +0800 Subject: [PATCH 3/6] fix: first version --- package.json | 1 + src/pages/bridge/index.module.less | 37 +++ src/pages/bridge/index.tsx | 413 ++++++++++++++++++++++------- src/utils/parseError.ts | 10 +- yarn.lock | 250 ++++++++++++++++- 5 files changed, 609 insertions(+), 102 deletions(-) diff --git a/package.json b/package.json index ed1412a6d..8c793e9d4 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,7 @@ "vite": "^4.4.8", "vite-tsconfig-paths": "^4.0.5", "wagmi": "^1.4.6", + "web3": "^4.5.0", "yup": "^0.32.9", "zustand": "^4.1.5" }, diff --git a/src/pages/bridge/index.module.less b/src/pages/bridge/index.module.less index c907cecda..c11a0e726 100644 --- a/src/pages/bridge/index.module.less +++ b/src/pages/bridge/index.module.less @@ -113,8 +113,45 @@ } } +.pendingAction { + display: flex; + flex-direction: column; + align-items: center; + gap: 24px; + border: 1px solid #DFE3E899; + border-radius: 8px; + padding: 24px; + width: 100%; +} + .confirmModal { :global { + .ant-modal-content { + padding: 16px 32px; + } + + .ant-modal-confirm-paragraph { + row-gap: 16px; + } + + .ant-modal-confirm-content { + padding: 24px 0 0 0; + position: relative; + &::before { + content: ' '; + height: 1px; + width: 572px; + background: #F4F6F8; + position: absolute; + top: 0; + left: -32px; + } + } + + .ant-modal-confirm-btns { + margin: 36px 0 16px 0; + } + .ant-modal-confirm-title { font-family: var(--sq-font-family); } diff --git a/src/pages/bridge/index.tsx b/src/pages/bridge/index.tsx index 1a507f34c..442b4cd17 100644 --- a/src/pages/bridge/index.tsx +++ b/src/pages/bridge/index.tsx @@ -4,19 +4,24 @@ import React, { FC, useEffect, useState } from 'react'; import { BsArrowDownSquareFill, BsLifePreserver } from 'react-icons/bs'; import { useNavigate } from 'react-router'; +import { gql, useQuery } from '@apollo/client'; import { WalletRoute } from '@components'; import { useSQToken } from '@containers'; import { l1Chain, l2Chain } from '@containers/Web3'; import { CrossChainMessenger } from '@eth-optimism/sdk/src/cross-chain-messenger'; +import { MessageStatus } from '@eth-optimism/sdk/src/interfaces/types'; import { publicClientToProvider, useEthersSigner } from '@hooks/useEthersProvider'; import { Footer, Modal, openNotification, Spinner, Steps, Typography } from '@subql/components'; import mainnetJSON from '@subql/contract-sdk/publish/mainnet.json'; import testnetJSON from '@subql/contract-sdk/publish/testnet.json'; -import { formatEther } from '@subql/react-hooks'; +import { formatEther, formatSQT } from '@subql/react-hooks'; +import { makeCacheKey } from '@utils/limitation'; +import { useInterval } from 'ahooks'; import { Button, InputNumber, Tabs } from 'antd'; import { clsx } from 'clsx'; +import { ethers } from 'ethers'; import { parseEther } from 'ethers/lib/utils'; -import { useNetwork, usePublicClient, useSwitchNetwork } from 'wagmi'; +import { useAccount, useNetwork, usePublicClient, useSwitchNetwork } from 'wagmi'; import styles from './index.module.less'; @@ -27,31 +32,95 @@ const l2ContractTokenAddress = ? testnetJSON.child.L2SQToken.address : mainnetJSON.child.L2SQToken.address; +export interface WithdrawsRecord { + withdraws: { + nodes: { + sender: string; + txHash: string; + nodeId: string; + id: string; + createAt: Date; + blockheight: number; + amount: string; + }[]; + }; +} + +const btnMsgs = { + [MessageStatus.READY_TO_PROVE]: 'Approve withdraw', + [MessageStatus.READY_FOR_RELAY]: 'Finalize withdraw', + [MessageStatus.STATE_ROOT_NOT_PUBLISHED]: 'State root not published', + [MessageStatus.RELAYED]: 'Finished', + + // fallback + [MessageStatus.FAILED_L1_TO_L2_MESSAGE]: 'Failed l1 to l2 message', + [MessageStatus.IN_CHALLENGE_PERIOD]: 'In challenge period', + [MessageStatus.UNCONFIRMED_L1_TO_L2_MESSAGE]: 'Unconfirmed l1 to l2 message', +}; + +const descMsgs = { + [MessageStatus.READY_TO_PROVE]: 'Ready to prove, please do it as soon as possiable', + [MessageStatus.READY_FOR_RELAY]: 'Ready to withdraw', + [MessageStatus.STATE_ROOT_NOT_PUBLISHED]: 'State root not published', + [MessageStatus.RELAYED]: 'You must wait for a 7 day withdraw period required by OP stack.', + + // fallback + [MessageStatus.FAILED_L1_TO_L2_MESSAGE]: 'Failed l1 to l2 message', + [MessageStatus.IN_CHALLENGE_PERIOD]: 'In challenge period', + [MessageStatus.UNCONFIRMED_L1_TO_L2_MESSAGE]: 'Unconfirmed l1 to l2 message', +}; + const Bridge: FC = () => { const { ethSqtBalance, balance } = useSQToken(); const { signer } = useEthersSigner(); const { chain } = useNetwork(); + const { address: account } = useAccount(); const navigate = useNavigate(); const [val, setVal] = useState('0'); const [loading, setLoading] = useState(false); + const [startL2BridgeLoading, setStartL2BridgeLoading] = useState(false); + const [withdrawLoading, setWithdrawLoading] = useState(false); const [crossChainMessengerIns, setCrossChainMessengerIns] = useState(); - const publicClient = usePublicClient({ chainId: l2Chain.id }); + const [pendingActionStatus, setPendingActionStatus] = useState<{ [key: string]: { status: MessageStatus } }>({}); const publicClientL1 = usePublicClient({ chainId: l1Chain.id }); const { switchNetwork } = useSwitchNetwork(); const [currentTab, setCurrentTab] = useState<'ethToBase' | 'baseToEth'>('ethToBase'); + const withdrawsRecord = useQuery( + gql` + query getWithdrawsRecord($sender: String!) { + withdraws(filter: { sender: { equalTo: $sender } }) { + nodes { + sender + txHash + nodeId + id + createAt + blockheight + amount + } + } + } + `, + { + variables: { + sender: account, + }, + fetchPolicy: 'network-only', + }, + ); + const initCrossChainMessenger = async () => { if (!signer) return; - + const l2Provider = new ethers.providers.JsonRpcProvider(l2Chain.rpcUrls.public.http[0]); const newCrossChainMessenger = new CrossChainMessenger({ l1ChainId: l1Chain.id, l2ChainId: l2Chain.id, l1SignerOrProvider: signer.provider.network.chainId === l1Chain.id ? signer : publicClientToProvider(publicClientL1), - l2SignerOrProvider: - signer.provider.network.chainId === l2Chain.id ? signer : publicClientToProvider(publicClient), + l2SignerOrProvider: signer.provider.network.chainId === l2Chain.id ? signer : l2Provider, }); setCrossChainMessengerIns(newCrossChainMessenger); @@ -102,7 +171,35 @@ const Bridge: FC = () => { const withdrawStart = async () => { if (!crossChainMessengerIns) return; - await Modal.confirm({ + + const _withdrawStart = async () => { + try { + setStartL2BridgeLoading(true); + const amount = parseEther(val); + const withdrawTx = await crossChainMessengerIns.withdrawERC20( + l1ContractTokenAddress, + l2ContractTokenAddress, + amount, + ); + await withdrawTx.wait(); + openNotification({ + type: 'success', + description: + 'Withdraw request success, please wait L1 status changed, you can check the status at below list.', + duration: 5, + }); + } catch (e: any) { + console.error(e); + openNotification({ + type: 'error', + description: e.message, + }); + } finally { + setStartL2BridgeLoading(false); + } + }; + + Modal.confirm({ width: 572, className: styles.confirmModal, title: 'Confirm Bridge', @@ -152,18 +249,64 @@ const Bridge: FC = () => { okButtonProps: { shape: 'round', }, + onOk: async () => { + await _withdrawStart(); + }, }); + }; + + const fetchPendingActionStatus = async () => { + if (!crossChainMessengerIns || !account) return; + + const pendingActionStatus: { [key: string]: { status: MessageStatus } } = {}; + for (const item of withdrawsRecord.data?.withdraws.nodes || []) { + const status = await crossChainMessengerIns.getMessageStatus(item.txHash); + pendingActionStatus[item.txHash] = { status }; + } + setPendingActionStatus(pendingActionStatus); + }; + + const withdrawApproveOrFinalize = async (txHash: string) => { + if (!crossChainMessengerIns) return; try { - setLoading(true); - const amount = parseEther(val); - } catch (e: any) { - console.error(e); - openNotification({ - type: 'error', - description: e.message, - }); + setWithdrawLoading(true); + if (pendingActionStatus[txHash]?.status === MessageStatus.READY_TO_PROVE) { + try { + const approveTx = await crossChainMessengerIns.proveMessage(txHash); + await approveTx.wait(); + openNotification({ + type: 'success', + description: 'Approve success, please wait...', + duration: 3, + }); + } catch (e: any) { + console.error(e); + openNotification({ + type: 'error', + description: e.message, + }); + } + } + + if (pendingActionStatus[txHash]?.status === MessageStatus.READY_FOR_RELAY) { + try { + const finalizeTx = await crossChainMessengerIns.finalizeMessage(txHash); + await finalizeTx.wait(); + openNotification({ + type: 'success', + description: 'Finalize success, You must wait for a 7 day withdraw period required by OP stack.', + duration: 3, + }); + } catch (e: any) { + console.error(e); + openNotification({ + type: 'error', + description: e.message, + }); + } + } } finally { - setLoading(false); + setWithdrawLoading(false); } }; @@ -171,6 +314,19 @@ const Bridge: FC = () => { initCrossChainMessenger(); }, [signer]); + useEffect(() => { + fetchPendingActionStatus(); + }, [withdrawsRecord.data?.withdraws.nodes, crossChainMessengerIns]); + + useEffect(() => { + fetchPendingActionStatus(); + }, [chain?.id]); + + useInterval(async () => { + await withdrawsRecord.refetch(); + fetchPendingActionStatus(); + }, 10000); + return ( { )} {currentTab === 'baseToEth' && ( -
-
- - OP stack and Base requires that any bridging to Ethereum requires a 7 day withdraw period. If you do - not want to wait for the required 7 days, please consider a{' '} - - third party bridge - - . - + <> +
+
+ + OP stack and Base requires that any bridging to Ethereum requires a 7 day withdraw period. If you + do not want to wait for the required 7 days, please consider a{' '} + + third party bridge + + . + - + - - FREE SQT - - - {balance.result.loading ? : formatEther(balance.result.data || 0, 4)}{' '} - SQT - -
-
-
- - SQT + + FREE SQT + + + {balance.result.loading ? ( + + ) : ( + formatEther(balance.result.data || 0, 4) + )}{' '} + SQT +
+
+
+ + SQT +
-
- { - setVal(newVal?.toString() || ''); - }} - > -
-
- -
-
- - SQT +
+ { + setVal(newVal?.toString() || ''); + }} + > +
+ +
+
+ + SQT +
-
- - {val || '0'} - +
+ + {val || '0'} + +
+ + + + + +
+ Need help? please message #network-bridge-support on + Discord +
+
- + {withdrawsRecord.data?.withdraws.nodes.length ? ( +
+ + Pending Bridge Actions + - - -
- Need help? please message #network-bridge-support on - Discord + {withdrawsRecord.data?.withdraws.nodes + .filter((i) => pendingActionStatus[i.txHash]?.status !== MessageStatus.RELAYED) + .map((item) => { + const status = pendingActionStatus[item.txHash]?.status; + const btnMsg = btnMsgs[status] || 'Unknown'; + const desc = descMsgs[status] || 'Unknown'; + const isL1Chain = chain?.id === l1Chain.id; + const disable = + isL1Chain && + status !== MessageStatus.READY_TO_PROVE && + status !== MessageStatus.READY_FOR_RELAY; + return ( +
+ + Bridge for {Number(formatSQT(item.amount)).toLocaleString()} SQT from Base {'->'} Ethereum{' '} + + + {desc} + + + +
+ ); + })}
-
-
+ ) : ( + '' + )} + )}
diff --git a/src/utils/parseError.ts b/src/utils/parseError.ts index 358337421..f3b9a5b55 100644 --- a/src/utils/parseError.ts +++ b/src/utils/parseError.ts @@ -98,7 +98,15 @@ export function parseError( const revertCode = Object.keys(contractErrorCodes).find((key) => rawErrorMsg.toString().match(`reverted: ${key}`), ) as keyof typeof contractErrorCodes; - return revertCode ? contractErrorCodes[revertCode] : undefined; + try { + captureException('Call contract error revert, need review', { + extra: { + error: rawErrorMsg, + }, + }); + } finally { + return revertCode ? contractErrorCodes[revertCode] : undefined; + } }; // https://github.com/ethers-io/ethers.js/discussions/1856 diff --git a/yarn.lock b/yarn.lock index 408d8c7c6..bd14a36c2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,6 +12,11 @@ resolved "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.9.4.tgz#aae21cb858bbb0411949d5b7b3051f4209043f62" integrity sha512-UK0bHA7hh9cR39V+4gl2/NnBBjoXIxkuWAPCaY4X7fbH4L/azIi7ilWOCjMUYfpJgraLUAqkRi2BqrjME8Rynw== +"@adraffy/ens-normalize@^1.8.8": + version "1.10.1" + resolved "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz#63430d04bd8c5e74f8d7d049338f1cd9d4f02069" + integrity sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw== + "@ampproject/remapping@^2.2.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" @@ -5131,6 +5136,13 @@ "@types/workbox-strategies" "^4.3.1" "@types/workbox-streams" "^4.3.0" +"@types/ws@8.5.3": + version "8.5.3" + resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" + integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== + dependencies: + "@types/node" "*" + "@types/ws@^7.4.4": version "7.4.7" resolved "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" @@ -5770,6 +5782,11 @@ JSONStream@^1.3.5: jsonparse "^1.2.0" through ">=2.2.7 <3" +abitype@0.7.1: + version "0.7.1" + resolved "https://registry.npmjs.org/abitype/-/abitype-0.7.1.tgz#16db20abe67de80f6183cf75f3de1ff86453b745" + integrity sha512-VBkRHTDZf9Myaek/dO3yMmOzB/y2s3Zo6nVU7yaw1G+TvCHAjwaJzNGN9yo4K5D8bU/VZXKP1EJpRhFr862PlQ== + abitype@0.8.7: version "0.8.7" resolved "https://registry.npmjs.org/abitype/-/abitype-0.8.7.tgz#e4b3f051febd08111f486c0cc6a98fa72d033622" @@ -7434,7 +7451,7 @@ cosmiconfig@^7.0.0, cosmiconfig@^7.0.1: path-type "^4.0.0" yaml "^1.10.0" -crc-32@^1.2.0: +crc-32@^1.2.0, crc-32@^1.2.2: version "1.2.2" resolved "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== @@ -10175,6 +10192,11 @@ isomorphic-ws@^4.0.1: resolved "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== +isomorphic-ws@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" + integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== + isows@1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/isows/-/isows-1.0.3.tgz#93c1cf0575daf56e7120bab5c8c448b0809d0d74" @@ -13682,7 +13704,7 @@ set-value@^4.1.0: is-plain-object "^2.0.4" is-primitive "^3.0.1" -setimmediate@^1.0.4: +setimmediate@^1.0.4, setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== @@ -14945,7 +14967,7 @@ util@^0.11.0: dependencies: inherits "2.0.3" -util@^0.12.4: +util@^0.12.4, util@^0.12.5: version "0.12.5" resolved "https://registry.npmjs.org/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== @@ -15131,6 +15153,175 @@ warning@^4.0.3: dependencies: loose-envify "^1.0.0" +web3-core@^4.3.0, web3-core@^4.3.2: + version "4.3.2" + resolved "https://registry.npmjs.org/web3-core/-/web3-core-4.3.2.tgz#f24b11d6a57dee527de8d42c89de2a439f0c4bed" + integrity sha512-uIMVd/j4BgOnwfpY8ZT+QKubOyM4xohEhFZXz9xB8wimXWMMlYVlIK/TbfHqFolS9uOerdSGhsMbcK9lETae8g== + dependencies: + web3-errors "^1.1.4" + web3-eth-accounts "^4.1.0" + web3-eth-iban "^4.0.7" + web3-providers-http "^4.1.0" + web3-providers-ws "^4.0.7" + web3-types "^1.3.1" + web3-utils "^4.1.0" + web3-validator "^2.0.3" + optionalDependencies: + web3-providers-ipc "^4.0.7" + +web3-errors@^1.1.3, web3-errors@^1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/web3-errors/-/web3-errors-1.1.4.tgz#5667a0a5f66fc936e101ef32032ccc1e8ca4d5a1" + integrity sha512-WahtszSqILez+83AxGecVroyZsMuuRT+KmQp4Si5P4Rnqbczno1k748PCrZTS1J4UCPmXMG2/Vt+0Bz2zwXkwQ== + dependencies: + web3-types "^1.3.1" + +web3-eth-abi@^4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-4.2.0.tgz#398d415e7783442d06fb7939e40ce3de7a3f04e9" + integrity sha512-x7dUCmk6th+5N63s5kUusoNtsDJKUUQgl9+jECvGTBOTiyHe/V6aOY0120FUjaAGaapOnR7BImQdhqHv6yT2YQ== + dependencies: + abitype "0.7.1" + web3-errors "^1.1.4" + web3-types "^1.3.1" + web3-utils "^4.1.1" + web3-validator "^2.0.4" + +web3-eth-accounts@^4.1.0, web3-eth-accounts@^4.1.1: + version "4.1.1" + resolved "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-4.1.1.tgz#55225e5510b961e1cacb4eccc996544998e907fc" + integrity sha512-9JqhRi1YhO1hQOEmmBHgEGsME/B1FHMxpA/AK3vhpvQ8QeP6KbJW+cForTLfPpUbkmPxnRunG4PNNaETNlZfrA== + dependencies: + "@ethereumjs/rlp" "^4.0.1" + crc-32 "^1.2.2" + ethereum-cryptography "^2.0.0" + web3-errors "^1.1.4" + web3-types "^1.3.1" + web3-utils "^4.1.1" + web3-validator "^2.0.4" + +web3-eth-contract@^4.1.2, web3-eth-contract@^4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-4.2.0.tgz#73f70b19217cd4854211c05846f0c841763b3b29" + integrity sha512-K7bUypsomTs8/Oa0Lgvq5plsSB5afgKJ79NMuXxvC5jfV+AxNrQyKcr5Vd5yEGNqrdQuIPduGQa8DpuY+rMe1g== + dependencies: + web3-core "^4.3.2" + web3-errors "^1.1.4" + web3-eth "^4.4.0" + web3-eth-abi "^4.2.0" + web3-types "^1.3.1" + web3-utils "^4.1.1" + web3-validator "^2.0.4" + +web3-eth-ens@^4.0.8: + version "4.0.8" + resolved "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-4.0.8.tgz#f4e0a018ce6cc69e37007ee92063867feb5994f0" + integrity sha512-nj0JfeD45BbzVJcVYpUJnSo8iwDcY9CQ7CZhhIVVOFjvpMAPw0zEwjTvZEIQyCW61OoDG9xcBzwxe2tZoYhMRw== + dependencies: + "@adraffy/ens-normalize" "^1.8.8" + web3-core "^4.3.0" + web3-errors "^1.1.3" + web3-eth "^4.3.1" + web3-eth-contract "^4.1.2" + web3-net "^4.0.7" + web3-types "^1.3.0" + web3-utils "^4.0.7" + web3-validator "^2.0.3" + +web3-eth-iban@^4.0.7: + version "4.0.7" + resolved "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-4.0.7.tgz#ee504f845d7b6315f0be78fcf070ccd5d38e4aaf" + integrity sha512-8weKLa9KuKRzibC87vNLdkinpUE30gn0IGY027F8doeJdcPUfsa4IlBgNC4k4HLBembBB2CTU0Kr/HAOqMeYVQ== + dependencies: + web3-errors "^1.1.3" + web3-types "^1.3.0" + web3-utils "^4.0.7" + web3-validator "^2.0.3" + +web3-eth-personal@^4.0.8: + version "4.0.8" + resolved "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-4.0.8.tgz#b51628c560de550ca8b354fa784f9556aae6065c" + integrity sha512-sXeyLKJ7ddQdMxz1BZkAwImjqh7OmKxhXoBNF3isDmD4QDpMIwv/t237S3q4Z0sZQamPa/pHebJRWVuvP8jZdw== + dependencies: + web3-core "^4.3.0" + web3-eth "^4.3.1" + web3-rpc-methods "^1.1.3" + web3-types "^1.3.0" + web3-utils "^4.0.7" + web3-validator "^2.0.3" + +web3-eth@^4.3.1, web3-eth@^4.4.0: + version "4.4.0" + resolved "https://registry.npmjs.org/web3-eth/-/web3-eth-4.4.0.tgz#755c34a769109836d122a53b33814d63f9ec5a65" + integrity sha512-HswKdzF44wUrciRAtEJaml9O7rDYDxElHmFs+27WcO3nel2zku+n0xs4e2ZAehfrCZ+05/y7TgnOZnaDU8Fb/A== + dependencies: + setimmediate "^1.0.5" + web3-core "^4.3.2" + web3-errors "^1.1.4" + web3-eth-abi "^4.2.0" + web3-eth-accounts "^4.1.1" + web3-net "^4.0.7" + web3-providers-ws "^4.0.7" + web3-rpc-methods "^1.1.4" + web3-types "^1.3.1" + web3-utils "^4.1.1" + web3-validator "^2.0.4" + +web3-net@^4.0.7: + version "4.0.7" + resolved "https://registry.npmjs.org/web3-net/-/web3-net-4.0.7.tgz#ed2c1bd700cf94be93a6dbd8bd8aa413d8681942" + integrity sha512-SzEaXFrBjY25iQGk5myaOfO9ZyfTwQEa4l4Ps4HDNVMibgZji3WPzpjq8zomVHMwi8bRp6VV7YS71eEsX7zLow== + dependencies: + web3-core "^4.3.0" + web3-rpc-methods "^1.1.3" + web3-types "^1.3.0" + web3-utils "^4.0.7" + +web3-providers-http@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-4.1.0.tgz#8d7afda67d1d8542ca85b30f60a3d1fe1993b561" + integrity sha512-6qRUGAhJfVQM41E5t+re5IHYmb5hSaLc02BE2MaRQsz2xKA6RjmHpOA5h/+ojJxEpI9NI2CrfDKOAgtJfoUJQg== + dependencies: + cross-fetch "^4.0.0" + web3-errors "^1.1.3" + web3-types "^1.3.0" + web3-utils "^4.0.7" + +web3-providers-ipc@^4.0.7: + version "4.0.7" + resolved "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-4.0.7.tgz#9ec4c8565053af005a5170ba80cddeb40ff3e3d3" + integrity sha512-YbNqY4zUvIaK2MHr1lQFE53/8t/ejHtJchrWn9zVbFMGXlTsOAbNoIoZWROrg1v+hCBvT2c9z8xt7e/+uz5p1g== + dependencies: + web3-errors "^1.1.3" + web3-types "^1.3.0" + web3-utils "^4.0.7" + +web3-providers-ws@^4.0.7: + version "4.0.7" + resolved "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-4.0.7.tgz#7a78a0dcf077e0e802da524fbb37d080b356c14b" + integrity sha512-n4Dal9/rQWjS7d6LjyEPM2R458V8blRm0eLJupDEJOOIBhGYlxw5/4FthZZ/cqB7y/sLVi7K09DdYx2MeRtU5w== + dependencies: + "@types/ws" "8.5.3" + isomorphic-ws "^5.0.0" + web3-errors "^1.1.3" + web3-types "^1.3.0" + web3-utils "^4.0.7" + ws "^8.8.1" + +web3-rpc-methods@^1.1.3, web3-rpc-methods@^1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/web3-rpc-methods/-/web3-rpc-methods-1.1.4.tgz#0b478e38231d3f3260ac504307c6dc4059af6fda" + integrity sha512-LTFNg4LFaeU8K9ecuT8fHDp/LOXyxCneeZjCrRYIW1u82Ly52SrY55FIzMIISGoG/iT5Wh7UiHOB3CQsWLBmbQ== + dependencies: + web3-core "^4.3.2" + web3-types "^1.3.1" + web3-validator "^2.0.3" + +web3-types@^1.3.0, web3-types@^1.3.1, web3-types@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/web3-types/-/web3-types-1.4.0.tgz#b79a0206f230594d7d9e141fbbc0b119a0ab7031" + integrity sha512-QnGDNredYqtZ49YD1pIPhsQTJJTOnYPCOnvrUs4/3XzeQLuDM+bAJ8fZ6U2nGEV77h81z2Ins6RE/f40yltvww== + web3-utils@^1.3.4: version "1.10.4" resolved "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.4.tgz#0daee7d6841641655d8b3726baf33b08eda1cbec" @@ -15145,6 +15336,49 @@ web3-utils@^1.3.4: randombytes "^2.1.0" utf8 "3.0.0" +web3-utils@^4.0.7, web3-utils@^4.1.0, web3-utils@^4.1.1, web3-utils@^4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/web3-utils/-/web3-utils-4.2.0.tgz#5beeb5610b9902527584beb31f88c64b08ddd6bc" + integrity sha512-UE7tmqPnC6sD0kpHhZiO9Zu8q7hiBItCQhnmxoMxk8OI91qlBWw6L7w1VNZo7TMBWH1Qe4R5l8h2vaoQCizVyA== + dependencies: + ethereum-cryptography "^2.0.0" + web3-errors "^1.1.4" + web3-types "^1.4.0" + web3-validator "^2.0.4" + +web3-validator@^2.0.3, web3-validator@^2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/web3-validator/-/web3-validator-2.0.4.tgz#66f34c94f21a3c94d0dc2a2d30deb8a379825d38" + integrity sha512-qRxVePwdW+SByOmTpDZFWHIUAa7PswvxNszrOua6BoGqAhERo5oJZBN+EbWtK/+O+ApNxt5FR3nCPmiZldiOQA== + dependencies: + ethereum-cryptography "^2.0.0" + util "^0.12.5" + web3-errors "^1.1.4" + web3-types "^1.3.1" + zod "^3.21.4" + +web3@^4.5.0: + version "4.5.0" + resolved "https://registry.npmjs.org/web3/-/web3-4.5.0.tgz#dd8472de86824106101386f903b23431c2af1a63" + integrity sha512-qWvmuFwmu1b4IVZz1/vahEP1VrRlnXLJJO6s88oRcOgOf21Q26rIyxqIDtKgKe7a4X29TqBocC1eP4CtZulAGA== + dependencies: + web3-core "^4.3.2" + web3-errors "^1.1.4" + web3-eth "^4.4.0" + web3-eth-abi "^4.2.0" + web3-eth-accounts "^4.1.1" + web3-eth-contract "^4.2.0" + web3-eth-ens "^4.0.8" + web3-eth-iban "^4.0.7" + web3-eth-personal "^4.0.8" + web3-net "^4.0.7" + web3-providers-http "^4.1.0" + web3-providers-ws "^4.0.7" + web3-rpc-methods "^1.1.4" + web3-types "^1.4.0" + web3-utils "^4.2.0" + web3-validator "^2.0.4" + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" @@ -15456,6 +15690,11 @@ ws@^8.5.0: resolved "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f" integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g== +ws@^8.8.1: + version "8.16.0" + resolved "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4" + integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ== + xtend@^4.0.0, xtend@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" @@ -15599,6 +15838,11 @@ zen-observable@0.8.15, zen-observable@^0.8.0: resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15" integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ== +zod@^3.21.4: + version "3.22.4" + resolved "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz#f31c3a9386f61b1f228af56faa9255e845cf3fff" + integrity sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg== + zrender@5.4.4: version "5.4.4" resolved "https://registry.yarnpkg.com/zrender/-/zrender-5.4.4.tgz#8854f1d95ecc82cf8912f5a11f86657cb8c9e261" From 8a599d9278a1b3b863e8f4a2a5734766174b2ada Mon Sep 17 00:00:00 2001 From: cyrbuzz Date: Wed, 28 Feb 2024 17:29:25 +0800 Subject: [PATCH 4/6] feat: msg --- src/pages/bridge/index.tsx | 630 +++++++++++++++++++++---------------- 1 file changed, 352 insertions(+), 278 deletions(-) diff --git a/src/pages/bridge/index.tsx b/src/pages/bridge/index.tsx index 442b4cd17..651b5eb57 100644 --- a/src/pages/bridge/index.tsx +++ b/src/pages/bridge/index.tsx @@ -1,7 +1,7 @@ // Copyright 2020-2022 SubQuery Pte Ltd authors & contributors // SPDX-License-Identifier: Apache-2.0 -import React, { FC, useEffect, useState } from 'react'; +import React, { FC, useEffect, useMemo, useState } from 'react'; import { BsArrowDownSquareFill, BsLifePreserver } from 'react-icons/bs'; import { useNavigate } from 'react-router'; import { gql, useQuery } from '@apollo/client'; @@ -19,8 +19,10 @@ import { makeCacheKey } from '@utils/limitation'; import { useInterval } from 'ahooks'; import { Button, InputNumber, Tabs } from 'antd'; import { clsx } from 'clsx'; +import dayjs from 'dayjs'; import { ethers } from 'ethers'; import { parseEther } from 'ethers/lib/utils'; +import localforage from 'localforage'; import { useAccount, useNetwork, usePublicClient, useSwitchNetwork } from 'wagmi'; import styles from './index.module.less'; @@ -48,9 +50,9 @@ export interface WithdrawsRecord { const btnMsgs = { [MessageStatus.READY_TO_PROVE]: 'Approve withdraw', - [MessageStatus.READY_FOR_RELAY]: 'Finalize withdraw', + [MessageStatus.READY_FOR_RELAY]: 'Withdraw SQT', [MessageStatus.STATE_ROOT_NOT_PUBLISHED]: 'State root not published', - [MessageStatus.RELAYED]: 'Finished', + [MessageStatus.RELAYED]: 'Finished, please wait at most 7 days and check in your wallet', // fallback [MessageStatus.FAILED_L1_TO_L2_MESSAGE]: 'Failed l1 to l2 message', @@ -61,8 +63,8 @@ const btnMsgs = { const descMsgs = { [MessageStatus.READY_TO_PROVE]: 'Ready to prove, please do it as soon as possiable', [MessageStatus.READY_FOR_RELAY]: 'Ready to withdraw', - [MessageStatus.STATE_ROOT_NOT_PUBLISHED]: 'State root not published', - [MessageStatus.RELAYED]: 'You must wait for a 7 day withdraw period required by OP stack.', + [MessageStatus.STATE_ROOT_NOT_PUBLISHED]: 'State root not published, please wait...', + [MessageStatus.RELAYED]: 'You must wait for a 7 days withdraw period required by OP stack.', // fallback [MessageStatus.FAILED_L1_TO_L2_MESSAGE]: 'Failed l1 to l2 message', @@ -70,28 +72,19 @@ const descMsgs = { [MessageStatus.UNCONFIRMED_L1_TO_L2_MESSAGE]: 'Unconfirmed l1 to l2 message', }; -const Bridge: FC = () => { +const BridgeInner: FC = () => { const { ethSqtBalance, balance } = useSQToken(); const { signer } = useEthersSigner(); const { chain } = useNetwork(); const { address: account } = useAccount(); - const navigate = useNavigate(); - const [val, setVal] = useState('0'); - const [loading, setLoading] = useState(false); - const [startL2BridgeLoading, setStartL2BridgeLoading] = useState(false); - const [withdrawLoading, setWithdrawLoading] = useState(false); - const [crossChainMessengerIns, setCrossChainMessengerIns] = useState(); - const [pendingActionStatus, setPendingActionStatus] = useState<{ [key: string]: { status: MessageStatus } }>({}); const publicClientL1 = usePublicClient({ chainId: l1Chain.id }); const { switchNetwork } = useSwitchNetwork(); - - const [currentTab, setCurrentTab] = useState<'ethToBase' | 'baseToEth'>('ethToBase'); - + const navigate = useNavigate(); const withdrawsRecord = useQuery( gql` query getWithdrawsRecord($sender: String!) { - withdraws(filter: { sender: { equalTo: $sender } }) { + withdraws(filter: { sender: { equalTo: $sender } }, orderBy: CREATE_AT_DESC) { nodes { sender txHash @@ -111,6 +104,39 @@ const Bridge: FC = () => { fetchPolicy: 'network-only', }, ); + const [val, setVal] = useState('0'); + const [loading, setLoading] = useState(false); + const [startL2BridgeLoading, setStartL2BridgeLoading] = useState(false); + const [withdrawLoading, setWithdrawLoading] = useState(false); + const [crossChainMessengerIns, setCrossChainMessengerIns] = useState(); + const [pendingActionStatus, setPendingActionStatus] = useState<{ + [key: string]: { status: MessageStatus; startTime?: number }; + }>({}); + const [currentTab, setCurrentTab] = useState<'ethToBase' | 'baseToEth'>('ethToBase'); + + const cacheKey = useMemo(() => makeCacheKey(account || '', { prefix: 'pendingActionStatus' }), [account]); + + const sortedWithdrawRecords = useMemo(() => { + return ( + withdrawsRecord.data?.withdraws.nodes.filter(({ txHash }) => { + const status = pendingActionStatus[txHash].status; + if (status === MessageStatus.RELAYED) { + if (pendingActionStatus[txHash].startTime) { + const durationTime = +dayjs() - (pendingActionStatus[txHash].startTime as number); + const duration = dayjs.duration(durationTime); + const maxPeiod = dayjs.duration(7, 'day'); + const leftTime = maxPeiod.subtract(duration); + + if (leftTime.days() === 0 && leftTime.hours() === 0) { + return false; + } + } + } + + return true; + }) || [] + ); + }, [pendingActionStatus, withdrawsRecord.data?.withdraws.nodes]); const initCrossChainMessenger = async () => { if (!signer) return; @@ -258,12 +284,40 @@ const Bridge: FC = () => { const fetchPendingActionStatus = async () => { if (!crossChainMessengerIns || !account) return; - const pendingActionStatus: { [key: string]: { status: MessageStatus } } = {}; - for (const item of withdrawsRecord.data?.withdraws.nodes || []) { + const cachedStorage = await localforage.getItem<{ [key: string]: { status: MessageStatus; startTime: Date } }>( + cacheKey, + ); + const filterStatus = (tx: string) => { + if (!cachedStorage) return true; + try { + if (cachedStorage[tx].status === MessageStatus.RELAYED) return false; + return true; + } catch (e) { + return true; + } + }; + const sortedWithdrawsRecord = withdrawsRecord.data?.withdraws.nodes.filter((i) => filterStatus(i.txHash)); + + const innerPendingActionStatus: { [key: string]: { status: MessageStatus } } = {}; + for (const item of sortedWithdrawsRecord || []) { const status = await crossChainMessengerIns.getMessageStatus(item.txHash); - pendingActionStatus[item.txHash] = { status }; + innerPendingActionStatus[item.txHash] = { status }; } - setPendingActionStatus(pendingActionStatus); + + const mergeFetchStatus = () => { + if (!cachedStorage) return innerPendingActionStatus; + + try { + return { + ...cachedStorage, + ...innerPendingActionStatus, + }; + } catch (e) { + return innerPendingActionStatus; + } + }; + setPendingActionStatus(mergeFetchStatus()); + await localforage.setItem(cacheKey, mergeFetchStatus()); }; const withdrawApproveOrFinalize = async (txHash: string) => { @@ -297,6 +351,13 @@ const Bridge: FC = () => { description: 'Finalize success, You must wait for a 7 day withdraw period required by OP stack.', duration: 3, }); + await localforage.setItem(cacheKey, { + ...pendingActionStatus, + [txHash]: { + status: MessageStatus.RELAYED, + startTime: +dayjs(), + }, + }); } catch (e: any) { console.error(e); openNotification({ @@ -328,280 +389,293 @@ const Bridge: FC = () => { }, 10000); return ( - -
- - Bridge - +
+
+ + Bridge + + + + SubQuery mainnet has launched, you can now bridge your SQT from Ethereum to Base to access the SubQuery + Network. + + + { + setCurrentTab(key as 'ethToBase' | 'baseToEth'); + setVal('0'); + }} + items={[ + { + label: 'Ethereum -> Base', + key: 'ethToBase', + }, + { + label: 'Base -> Ethereum', + key: 'baseToEth', + }, + ]} + > + + {currentTab === 'ethToBase' && ( +
+
+ + FREE SQT + + + {ethSqtBalance.result.loading ? ( + + ) : ( + formatEther(ethSqtBalance.result.data || 0, 4) + )}{' '} + SQT + +
+
+
+ + SQT +
+ +
+ { + setVal(newVal?.toString() || ''); + }} + > +
+
+ +
+
+ + SQT +
- - SubQuery mainnet has launched, you can now bridge your SQT from Ethereum to Base to access the SubQuery - Network. +
+ + {val || '0'} + +
+
+ +
+ + Transfer time: A few minutes + +
+ + + + + +
+ Need help? please message #network-bridge-support on + Discord +
+
+ )} + + {currentTab === 'baseToEth' && ( + <> +
+
+ + OP stack and Base requires that any bridging to Ethereum requires a 7 day withdraw period. If you do + not want to wait for the required 7 days, please consider a{' '} + + third party bridge + + . + - { - setCurrentTab(key as 'ethToBase' | 'baseToEth'); - setVal('0'); - }} - items={[ - { - label: 'Ethereum -> Base', - key: 'ethToBase', - }, - { - label: 'Base -> Ethereum', - key: 'baseToEth', - }, - ]} - > - - {currentTab === 'ethToBase' && ( -
-
- - FREE SQT - - - {ethSqtBalance.result.loading ? ( - - ) : ( - formatEther(ethSqtBalance.result.data || 0, 4) - )}{' '} - SQT - + + + + FREE SQT + + + {balance.result.loading ? : formatEther(balance.result.data || 0, 4)}{' '} + SQT + +
+
+
+ + SQT
-
-
- - SQT -
- -
- { - setVal(newVal?.toString() || ''); - }} - > -
+ +
+ { + setVal(newVal?.toString() || ''); + }} + >
- -
-
- - SQT -
- -
- - {val || '0'} - -
+
+ +
+
+ + SQT
-
- - Transfer time: A few minutes +
+ + {val || '0'}
+
- - - - -
- Need help? please message #network-bridge-support on - Discord -
+ + + + +
+ Need help? please message #network-bridge-support on + Discord +
+
+
+ + {sortedWithdrawRecords.length ? ( +
+ + Pending Bridge Actions -
- )} - {currentTab === 'baseToEth' && ( - <> -
-
- - OP stack and Base requires that any bridging to Ethereum requires a 7 day withdraw period. If you - do not want to wait for the required 7 days, please consider a{' '} - - third party bridge - - . - - - - - - FREE SQT - - - {balance.result.loading ? ( - - ) : ( - formatEther(balance.result.data || 0, 4) - )}{' '} - SQT - -
-
-
- - SQT -
+ {sortedWithdrawRecords.map((item) => { + const status = pendingActionStatus[item.txHash]?.status; -
- { - setVal(newVal?.toString() || ''); - }} - > -
-
- -
-
- - SQT -
+ const btnMsgFunc = () => { + if (status === MessageStatus.RELAYED) { + if (pendingActionStatus[item.txHash].startTime) { + const durationTime = +dayjs() - (pendingActionStatus[item.txHash].startTime as number); + const duration = dayjs.duration(durationTime); + const maxPeiod = dayjs.duration(7, 'day'); + const leftTime = maxPeiod.subtract(duration); -
- - {val || '0'} - -
-
- - - - - -
- Need help? please message #network-bridge-support on - Discord -
-
-
- {withdrawsRecord.data?.withdraws.nodes.length ? ( -
- - Pending Bridge Actions - - - {withdrawsRecord.data?.withdraws.nodes - .filter((i) => pendingActionStatus[i.txHash]?.status !== MessageStatus.RELAYED) - .map((item) => { - const status = pendingActionStatus[item.txHash]?.status; - const btnMsg = btnMsgs[status] || 'Unknown'; - const desc = descMsgs[status] || 'Unknown'; - const isL1Chain = chain?.id === l1Chain.id; - const disable = - isL1Chain && - status !== MessageStatus.READY_TO_PROVE && - status !== MessageStatus.READY_FOR_RELAY; - return ( -
- - Bridge for {Number(formatSQT(item.amount)).toLocaleString()} SQT from Base {'->'} Ethereum{' '} - - - {desc} - - - -
- ); - })} -
- ) : ( - '' - )} - + return ( + btnMsgs[status] || `${Object.keys(pendingActionStatus).length === 0 ? 'Fetching status...' : ''}` + ); + }; + + const desc = descMsgs[status] || 'Unknown'; + const isL1Chain = chain?.id === l1Chain.id; + const disable = + isL1Chain && status !== MessageStatus.READY_TO_PROVE && status !== MessageStatus.READY_FOR_RELAY; + + return ( +
+ + Bridge for {Number(formatSQT(item.amount)).toLocaleString()} SQT from Base{' '} + {'->'} Ethereum{' '} + + + {desc} + + + { + + } +
+ ); + })} +
+ ) : ( + '' )} -
-
-
- } - > + + )} +
+
+
); }; + +const Bridge: FC = () => { + return }>; +}; export default Bridge; From f2e0fb30a26371522a7d0a483efc13fabe0071e6 Mon Sep 17 00:00:00 2001 From: cyrbuzz Date: Wed, 28 Feb 2024 18:15:49 +0800 Subject: [PATCH 5/6] feat: base to eth --- .../ProjectHeader/ProjectHeader.tsx | 4 +- src/pages/bridge/index.tsx | 47 +++++++++++++------ .../indexer/MyDelegators/OwnDelegator.tsx | 2 +- src/utils/constants.ts | 4 +- 4 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/components/ProjectHeader/ProjectHeader.tsx b/src/components/ProjectHeader/ProjectHeader.tsx index 3d698396e..343278c8a 100644 --- a/src/components/ProjectHeader/ProjectHeader.tsx +++ b/src/components/ProjectHeader/ProjectHeader.tsx @@ -37,8 +37,8 @@ const ProjectHeader: React.FC = ({ }) => { const { t } = useTranslation(); - const createdAtStr = React.useMemo(() => dayjs(project.createdTimestamp).fromNow(), [project]); - const updatedAtStr = React.useMemo(() => dayjs(project.updatedTimestamp).fromNow(), [project]); + const createdAtStr = React.useMemo(() => dayjs(project.createdTimestamp).utc(true).fromNow(), [project]); + const updatedAtStr = React.useMemo(() => dayjs(project.updatedTimestamp).utc(true).fromNow(), [project]); const VersionDropdown = () => { if (!versions) return <>; diff --git a/src/pages/bridge/index.tsx b/src/pages/bridge/index.tsx index 651b5eb57..d8ef58534 100644 --- a/src/pages/bridge/index.tsx +++ b/src/pages/bridge/index.tsx @@ -1,7 +1,7 @@ // Copyright 2020-2022 SubQuery Pte Ltd authors & contributors // SPDX-License-Identifier: Apache-2.0 -import React, { FC, useEffect, useMemo, useState } from 'react'; +import React, { FC, useEffect, useMemo, useRef, useState } from 'react'; import { BsArrowDownSquareFill, BsLifePreserver } from 'react-icons/bs'; import { useNavigate } from 'react-router'; import { gql, useQuery } from '@apollo/client'; @@ -15,6 +15,7 @@ import { Footer, Modal, openNotification, Spinner, Steps, Typography } from '@su import mainnetJSON from '@subql/contract-sdk/publish/mainnet.json'; import testnetJSON from '@subql/contract-sdk/publish/testnet.json'; import { formatEther, formatSQT } from '@subql/react-hooks'; +import { parseError } from '@utils'; import { makeCacheKey } from '@utils/limitation'; import { useInterval } from 'ahooks'; import { Button, InputNumber, Tabs } from 'antd'; @@ -113,13 +114,15 @@ const BridgeInner: FC = () => { [key: string]: { status: MessageStatus; startTime?: number }; }>({}); const [currentTab, setCurrentTab] = useState<'ethToBase' | 'baseToEth'>('ethToBase'); + // This state is used to prevent the fetchPendingActionStatus function from being called when finalizeMessage is called. + const shouldFetch = useRef(true); const cacheKey = useMemo(() => makeCacheKey(account || '', { prefix: 'pendingActionStatus' }), [account]); const sortedWithdrawRecords = useMemo(() => { return ( withdrawsRecord.data?.withdraws.nodes.filter(({ txHash }) => { - const status = pendingActionStatus[txHash].status; + const status = pendingActionStatus[txHash]?.status; if (status === MessageStatus.RELAYED) { if (pendingActionStatus[txHash].startTime) { const durationTime = +dayjs() - (pendingActionStatus[txHash].startTime as number); @@ -185,10 +188,9 @@ const BridgeInner: FC = () => { await ethSqtBalance.refetch(); navigate('/bridge/success'); } catch (e: any) { - console.error(e); openNotification({ type: 'error', - description: e.message, + description: parseError(e.message), }); } finally { setLoading(false); @@ -215,10 +217,9 @@ const BridgeInner: FC = () => { duration: 5, }); } catch (e: any) { - console.error(e); openNotification({ type: 'error', - description: e.message, + description: parseError(e.message), }); } finally { setStartL2BridgeLoading(false); @@ -284,7 +285,7 @@ const BridgeInner: FC = () => { const fetchPendingActionStatus = async () => { if (!crossChainMessengerIns || !account) return; - const cachedStorage = await localforage.getItem<{ [key: string]: { status: MessageStatus; startTime: Date } }>( + const cachedStorage = await localforage.getItem<{ [key: string]: { status: MessageStatus; startTime?: number } }>( cacheKey, ); const filterStatus = (tx: string) => { @@ -298,10 +299,13 @@ const BridgeInner: FC = () => { }; const sortedWithdrawsRecord = withdrawsRecord.data?.withdraws.nodes.filter((i) => filterStatus(i.txHash)); - const innerPendingActionStatus: { [key: string]: { status: MessageStatus } } = {}; + const innerPendingActionStatus: { [key: string]: { status: MessageStatus; startTime?: number } } = {}; for (const item of sortedWithdrawsRecord || []) { const status = await crossChainMessengerIns.getMessageStatus(item.txHash); innerPendingActionStatus[item.txHash] = { status }; + if (pendingActionStatus[item.txHash]?.startTime) { + innerPendingActionStatus[item.txHash]['startTime'] = pendingActionStatus[item.txHash].startTime; + } } const mergeFetchStatus = () => { @@ -313,11 +317,17 @@ const BridgeInner: FC = () => { ...innerPendingActionStatus, }; } catch (e) { + console.warn(e); return innerPendingActionStatus; } }; - setPendingActionStatus(mergeFetchStatus()); - await localforage.setItem(cacheKey, mergeFetchStatus()); + if (shouldFetch.current) { + setPendingActionStatus(mergeFetchStatus()); + await localforage.setItem(cacheKey, mergeFetchStatus()); + // for next interval + } else { + shouldFetch.current = true; + } }; const withdrawApproveOrFinalize = async (txHash: string) => { @@ -334,10 +344,9 @@ const BridgeInner: FC = () => { duration: 3, }); } catch (e: any) { - console.error(e); openNotification({ type: 'error', - description: e.message, + description: parseError(e.message), }); } } @@ -358,11 +367,18 @@ const BridgeInner: FC = () => { startTime: +dayjs(), }, }); + setPendingActionStatus({ + ...pendingActionStatus, + [txHash]: { + status: MessageStatus.RELAYED, + startTime: +dayjs(), + }, + }); + shouldFetch.current = false; } catch (e: any) { - console.error(e); openNotification({ type: 'error', - description: e.message, + description: parseError(e.message), }); } } @@ -622,7 +638,8 @@ const BridgeInner: FC = () => { } return ( - btnMsgs[status] || `${Object.keys(pendingActionStatus).length === 0 ? 'Fetching status...' : ''}` + btnMsgs[status] || + `${Object.keys(pendingActionStatus).length === 0 ? 'Fetching status...' : 'Unknown'}` ); }; diff --git a/src/pages/indexer/MyDelegators/OwnDelegator.tsx b/src/pages/indexer/MyDelegators/OwnDelegator.tsx index 173ee6110..d575517a3 100644 --- a/src/pages/indexer/MyDelegators/OwnDelegator.tsx +++ b/src/pages/indexer/MyDelegators/OwnDelegator.tsx @@ -101,7 +101,7 @@ export const OwnDelegator: React.FC = ({ indexer, showEmpty, hideCard, sh
- Capcity + Capacity {formatNumber(sortedIndexer.data?.capacity.current || '0')} {TOKEN} diff --git a/src/utils/constants.ts b/src/utils/constants.ts index aa508018c..65f50152d 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -85,8 +85,8 @@ export const rpcCategoriesOptions = [ value: 'EVM', }, { - label: 'Polkdot', - value: 'Polkdot', + label: 'Polkadot', + value: 'Polkadot', }, { label: 'Cosmos', From 2519a28df3b6261c4fa5201f99fcfb7e775d9113 Mon Sep 17 00:00:00 2001 From: cyrbuzz Date: Wed, 28 Feb 2024 18:20:06 +0800 Subject: [PATCH 6/6] fix: remove unless --- package.json | 1 - yarn.lock | 250 +-------------------------------------------------- 2 files changed, 3 insertions(+), 248 deletions(-) diff --git a/package.json b/package.json index 8c793e9d4..ed1412a6d 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,6 @@ "vite": "^4.4.8", "vite-tsconfig-paths": "^4.0.5", "wagmi": "^1.4.6", - "web3": "^4.5.0", "yup": "^0.32.9", "zustand": "^4.1.5" }, diff --git a/yarn.lock b/yarn.lock index bd14a36c2..408d8c7c6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,11 +12,6 @@ resolved "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.9.4.tgz#aae21cb858bbb0411949d5b7b3051f4209043f62" integrity sha512-UK0bHA7hh9cR39V+4gl2/NnBBjoXIxkuWAPCaY4X7fbH4L/azIi7ilWOCjMUYfpJgraLUAqkRi2BqrjME8Rynw== -"@adraffy/ens-normalize@^1.8.8": - version "1.10.1" - resolved "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz#63430d04bd8c5e74f8d7d049338f1cd9d4f02069" - integrity sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw== - "@ampproject/remapping@^2.2.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" @@ -5136,13 +5131,6 @@ "@types/workbox-strategies" "^4.3.1" "@types/workbox-streams" "^4.3.0" -"@types/ws@8.5.3": - version "8.5.3" - resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" - integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== - dependencies: - "@types/node" "*" - "@types/ws@^7.4.4": version "7.4.7" resolved "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" @@ -5782,11 +5770,6 @@ JSONStream@^1.3.5: jsonparse "^1.2.0" through ">=2.2.7 <3" -abitype@0.7.1: - version "0.7.1" - resolved "https://registry.npmjs.org/abitype/-/abitype-0.7.1.tgz#16db20abe67de80f6183cf75f3de1ff86453b745" - integrity sha512-VBkRHTDZf9Myaek/dO3yMmOzB/y2s3Zo6nVU7yaw1G+TvCHAjwaJzNGN9yo4K5D8bU/VZXKP1EJpRhFr862PlQ== - abitype@0.8.7: version "0.8.7" resolved "https://registry.npmjs.org/abitype/-/abitype-0.8.7.tgz#e4b3f051febd08111f486c0cc6a98fa72d033622" @@ -7451,7 +7434,7 @@ cosmiconfig@^7.0.0, cosmiconfig@^7.0.1: path-type "^4.0.0" yaml "^1.10.0" -crc-32@^1.2.0, crc-32@^1.2.2: +crc-32@^1.2.0: version "1.2.2" resolved "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== @@ -10192,11 +10175,6 @@ isomorphic-ws@^4.0.1: resolved "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== -isomorphic-ws@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" - integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== - isows@1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/isows/-/isows-1.0.3.tgz#93c1cf0575daf56e7120bab5c8c448b0809d0d74" @@ -13704,7 +13682,7 @@ set-value@^4.1.0: is-plain-object "^2.0.4" is-primitive "^3.0.1" -setimmediate@^1.0.4, setimmediate@^1.0.5: +setimmediate@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== @@ -14967,7 +14945,7 @@ util@^0.11.0: dependencies: inherits "2.0.3" -util@^0.12.4, util@^0.12.5: +util@^0.12.4: version "0.12.5" resolved "https://registry.npmjs.org/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== @@ -15153,175 +15131,6 @@ warning@^4.0.3: dependencies: loose-envify "^1.0.0" -web3-core@^4.3.0, web3-core@^4.3.2: - version "4.3.2" - resolved "https://registry.npmjs.org/web3-core/-/web3-core-4.3.2.tgz#f24b11d6a57dee527de8d42c89de2a439f0c4bed" - integrity sha512-uIMVd/j4BgOnwfpY8ZT+QKubOyM4xohEhFZXz9xB8wimXWMMlYVlIK/TbfHqFolS9uOerdSGhsMbcK9lETae8g== - dependencies: - web3-errors "^1.1.4" - web3-eth-accounts "^4.1.0" - web3-eth-iban "^4.0.7" - web3-providers-http "^4.1.0" - web3-providers-ws "^4.0.7" - web3-types "^1.3.1" - web3-utils "^4.1.0" - web3-validator "^2.0.3" - optionalDependencies: - web3-providers-ipc "^4.0.7" - -web3-errors@^1.1.3, web3-errors@^1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/web3-errors/-/web3-errors-1.1.4.tgz#5667a0a5f66fc936e101ef32032ccc1e8ca4d5a1" - integrity sha512-WahtszSqILez+83AxGecVroyZsMuuRT+KmQp4Si5P4Rnqbczno1k748PCrZTS1J4UCPmXMG2/Vt+0Bz2zwXkwQ== - dependencies: - web3-types "^1.3.1" - -web3-eth-abi@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-4.2.0.tgz#398d415e7783442d06fb7939e40ce3de7a3f04e9" - integrity sha512-x7dUCmk6th+5N63s5kUusoNtsDJKUUQgl9+jECvGTBOTiyHe/V6aOY0120FUjaAGaapOnR7BImQdhqHv6yT2YQ== - dependencies: - abitype "0.7.1" - web3-errors "^1.1.4" - web3-types "^1.3.1" - web3-utils "^4.1.1" - web3-validator "^2.0.4" - -web3-eth-accounts@^4.1.0, web3-eth-accounts@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-4.1.1.tgz#55225e5510b961e1cacb4eccc996544998e907fc" - integrity sha512-9JqhRi1YhO1hQOEmmBHgEGsME/B1FHMxpA/AK3vhpvQ8QeP6KbJW+cForTLfPpUbkmPxnRunG4PNNaETNlZfrA== - dependencies: - "@ethereumjs/rlp" "^4.0.1" - crc-32 "^1.2.2" - ethereum-cryptography "^2.0.0" - web3-errors "^1.1.4" - web3-types "^1.3.1" - web3-utils "^4.1.1" - web3-validator "^2.0.4" - -web3-eth-contract@^4.1.2, web3-eth-contract@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-4.2.0.tgz#73f70b19217cd4854211c05846f0c841763b3b29" - integrity sha512-K7bUypsomTs8/Oa0Lgvq5plsSB5afgKJ79NMuXxvC5jfV+AxNrQyKcr5Vd5yEGNqrdQuIPduGQa8DpuY+rMe1g== - dependencies: - web3-core "^4.3.2" - web3-errors "^1.1.4" - web3-eth "^4.4.0" - web3-eth-abi "^4.2.0" - web3-types "^1.3.1" - web3-utils "^4.1.1" - web3-validator "^2.0.4" - -web3-eth-ens@^4.0.8: - version "4.0.8" - resolved "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-4.0.8.tgz#f4e0a018ce6cc69e37007ee92063867feb5994f0" - integrity sha512-nj0JfeD45BbzVJcVYpUJnSo8iwDcY9CQ7CZhhIVVOFjvpMAPw0zEwjTvZEIQyCW61OoDG9xcBzwxe2tZoYhMRw== - dependencies: - "@adraffy/ens-normalize" "^1.8.8" - web3-core "^4.3.0" - web3-errors "^1.1.3" - web3-eth "^4.3.1" - web3-eth-contract "^4.1.2" - web3-net "^4.0.7" - web3-types "^1.3.0" - web3-utils "^4.0.7" - web3-validator "^2.0.3" - -web3-eth-iban@^4.0.7: - version "4.0.7" - resolved "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-4.0.7.tgz#ee504f845d7b6315f0be78fcf070ccd5d38e4aaf" - integrity sha512-8weKLa9KuKRzibC87vNLdkinpUE30gn0IGY027F8doeJdcPUfsa4IlBgNC4k4HLBembBB2CTU0Kr/HAOqMeYVQ== - dependencies: - web3-errors "^1.1.3" - web3-types "^1.3.0" - web3-utils "^4.0.7" - web3-validator "^2.0.3" - -web3-eth-personal@^4.0.8: - version "4.0.8" - resolved "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-4.0.8.tgz#b51628c560de550ca8b354fa784f9556aae6065c" - integrity sha512-sXeyLKJ7ddQdMxz1BZkAwImjqh7OmKxhXoBNF3isDmD4QDpMIwv/t237S3q4Z0sZQamPa/pHebJRWVuvP8jZdw== - dependencies: - web3-core "^4.3.0" - web3-eth "^4.3.1" - web3-rpc-methods "^1.1.3" - web3-types "^1.3.0" - web3-utils "^4.0.7" - web3-validator "^2.0.3" - -web3-eth@^4.3.1, web3-eth@^4.4.0: - version "4.4.0" - resolved "https://registry.npmjs.org/web3-eth/-/web3-eth-4.4.0.tgz#755c34a769109836d122a53b33814d63f9ec5a65" - integrity sha512-HswKdzF44wUrciRAtEJaml9O7rDYDxElHmFs+27WcO3nel2zku+n0xs4e2ZAehfrCZ+05/y7TgnOZnaDU8Fb/A== - dependencies: - setimmediate "^1.0.5" - web3-core "^4.3.2" - web3-errors "^1.1.4" - web3-eth-abi "^4.2.0" - web3-eth-accounts "^4.1.1" - web3-net "^4.0.7" - web3-providers-ws "^4.0.7" - web3-rpc-methods "^1.1.4" - web3-types "^1.3.1" - web3-utils "^4.1.1" - web3-validator "^2.0.4" - -web3-net@^4.0.7: - version "4.0.7" - resolved "https://registry.npmjs.org/web3-net/-/web3-net-4.0.7.tgz#ed2c1bd700cf94be93a6dbd8bd8aa413d8681942" - integrity sha512-SzEaXFrBjY25iQGk5myaOfO9ZyfTwQEa4l4Ps4HDNVMibgZji3WPzpjq8zomVHMwi8bRp6VV7YS71eEsX7zLow== - dependencies: - web3-core "^4.3.0" - web3-rpc-methods "^1.1.3" - web3-types "^1.3.0" - web3-utils "^4.0.7" - -web3-providers-http@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-4.1.0.tgz#8d7afda67d1d8542ca85b30f60a3d1fe1993b561" - integrity sha512-6qRUGAhJfVQM41E5t+re5IHYmb5hSaLc02BE2MaRQsz2xKA6RjmHpOA5h/+ojJxEpI9NI2CrfDKOAgtJfoUJQg== - dependencies: - cross-fetch "^4.0.0" - web3-errors "^1.1.3" - web3-types "^1.3.0" - web3-utils "^4.0.7" - -web3-providers-ipc@^4.0.7: - version "4.0.7" - resolved "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-4.0.7.tgz#9ec4c8565053af005a5170ba80cddeb40ff3e3d3" - integrity sha512-YbNqY4zUvIaK2MHr1lQFE53/8t/ejHtJchrWn9zVbFMGXlTsOAbNoIoZWROrg1v+hCBvT2c9z8xt7e/+uz5p1g== - dependencies: - web3-errors "^1.1.3" - web3-types "^1.3.0" - web3-utils "^4.0.7" - -web3-providers-ws@^4.0.7: - version "4.0.7" - resolved "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-4.0.7.tgz#7a78a0dcf077e0e802da524fbb37d080b356c14b" - integrity sha512-n4Dal9/rQWjS7d6LjyEPM2R458V8blRm0eLJupDEJOOIBhGYlxw5/4FthZZ/cqB7y/sLVi7K09DdYx2MeRtU5w== - dependencies: - "@types/ws" "8.5.3" - isomorphic-ws "^5.0.0" - web3-errors "^1.1.3" - web3-types "^1.3.0" - web3-utils "^4.0.7" - ws "^8.8.1" - -web3-rpc-methods@^1.1.3, web3-rpc-methods@^1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/web3-rpc-methods/-/web3-rpc-methods-1.1.4.tgz#0b478e38231d3f3260ac504307c6dc4059af6fda" - integrity sha512-LTFNg4LFaeU8K9ecuT8fHDp/LOXyxCneeZjCrRYIW1u82Ly52SrY55FIzMIISGoG/iT5Wh7UiHOB3CQsWLBmbQ== - dependencies: - web3-core "^4.3.2" - web3-types "^1.3.1" - web3-validator "^2.0.3" - -web3-types@^1.3.0, web3-types@^1.3.1, web3-types@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/web3-types/-/web3-types-1.4.0.tgz#b79a0206f230594d7d9e141fbbc0b119a0ab7031" - integrity sha512-QnGDNredYqtZ49YD1pIPhsQTJJTOnYPCOnvrUs4/3XzeQLuDM+bAJ8fZ6U2nGEV77h81z2Ins6RE/f40yltvww== - web3-utils@^1.3.4: version "1.10.4" resolved "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.4.tgz#0daee7d6841641655d8b3726baf33b08eda1cbec" @@ -15336,49 +15145,6 @@ web3-utils@^1.3.4: randombytes "^2.1.0" utf8 "3.0.0" -web3-utils@^4.0.7, web3-utils@^4.1.0, web3-utils@^4.1.1, web3-utils@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/web3-utils/-/web3-utils-4.2.0.tgz#5beeb5610b9902527584beb31f88c64b08ddd6bc" - integrity sha512-UE7tmqPnC6sD0kpHhZiO9Zu8q7hiBItCQhnmxoMxk8OI91qlBWw6L7w1VNZo7TMBWH1Qe4R5l8h2vaoQCizVyA== - dependencies: - ethereum-cryptography "^2.0.0" - web3-errors "^1.1.4" - web3-types "^1.4.0" - web3-validator "^2.0.4" - -web3-validator@^2.0.3, web3-validator@^2.0.4: - version "2.0.4" - resolved "https://registry.npmjs.org/web3-validator/-/web3-validator-2.0.4.tgz#66f34c94f21a3c94d0dc2a2d30deb8a379825d38" - integrity sha512-qRxVePwdW+SByOmTpDZFWHIUAa7PswvxNszrOua6BoGqAhERo5oJZBN+EbWtK/+O+ApNxt5FR3nCPmiZldiOQA== - dependencies: - ethereum-cryptography "^2.0.0" - util "^0.12.5" - web3-errors "^1.1.4" - web3-types "^1.3.1" - zod "^3.21.4" - -web3@^4.5.0: - version "4.5.0" - resolved "https://registry.npmjs.org/web3/-/web3-4.5.0.tgz#dd8472de86824106101386f903b23431c2af1a63" - integrity sha512-qWvmuFwmu1b4IVZz1/vahEP1VrRlnXLJJO6s88oRcOgOf21Q26rIyxqIDtKgKe7a4X29TqBocC1eP4CtZulAGA== - dependencies: - web3-core "^4.3.2" - web3-errors "^1.1.4" - web3-eth "^4.4.0" - web3-eth-abi "^4.2.0" - web3-eth-accounts "^4.1.1" - web3-eth-contract "^4.2.0" - web3-eth-ens "^4.0.8" - web3-eth-iban "^4.0.7" - web3-eth-personal "^4.0.8" - web3-net "^4.0.7" - web3-providers-http "^4.1.0" - web3-providers-ws "^4.0.7" - web3-rpc-methods "^1.1.4" - web3-types "^1.4.0" - web3-utils "^4.2.0" - web3-validator "^2.0.4" - webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" @@ -15690,11 +15456,6 @@ ws@^8.5.0: resolved "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f" integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g== -ws@^8.8.1: - version "8.16.0" - resolved "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4" - integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ== - xtend@^4.0.0, xtend@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" @@ -15838,11 +15599,6 @@ zen-observable@0.8.15, zen-observable@^0.8.0: resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15" integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ== -zod@^3.21.4: - version "3.22.4" - resolved "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz#f31c3a9386f61b1f228af56faa9255e845cf3fff" - integrity sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg== - zrender@5.4.4: version "5.4.4" resolved "https://registry.yarnpkg.com/zrender/-/zrender-5.4.4.tgz#8854f1d95ecc82cf8912f5a11f86657cb8c9e261"