diff --git a/src/components/animations/Spinner.module.css b/src/components/animations/Spinner.module.css deleted file mode 100644 index 45e5181..0000000 --- a/src/components/animations/Spinner.module.css +++ /dev/null @@ -1,81 +0,0 @@ -.spinner { - color: official; - display: inline-block; - position: relative; - width: 80px; - height: 80px; -} -.spinner div { - transform-origin: 40px 40px; - animation: spinner 1.2s linear infinite; -} -.spinner div:after { - content: ' '; - display: block; - position: absolute; - top: 3px; - left: 37px; - width: 6px; - height: 18px; - border-radius: 20%; - background: #010101; -} -.spinner.white div:after { - background: #ffffff; -} -.spinner div:nth-child(1) { - transform: rotate(0deg); - animation-delay: -1.1s; -} -.spinner div:nth-child(2) { - transform: rotate(30deg); - animation-delay: -1s; -} -.spinner div:nth-child(3) { - transform: rotate(60deg); - animation-delay: -0.9s; -} -.spinner div:nth-child(4) { - transform: rotate(90deg); - animation-delay: -0.8s; -} -.spinner div:nth-child(5) { - transform: rotate(120deg); - animation-delay: -0.7s; -} -.spinner div:nth-child(6) { - transform: rotate(150deg); - animation-delay: -0.6s; -} -.spinner div:nth-child(7) { - transform: rotate(180deg); - animation-delay: -0.5s; -} -.spinner div:nth-child(8) { - transform: rotate(210deg); - animation-delay: -0.4s; -} -.spinner div:nth-child(9) { - transform: rotate(240deg); - animation-delay: -0.3s; -} -.spinner div:nth-child(10) { - transform: rotate(270deg); - animation-delay: -0.2s; -} -.spinner div:nth-child(11) { - transform: rotate(300deg); - animation-delay: -0.1s; -} -.spinner div:nth-child(12) { - transform: rotate(330deg); - animation-delay: 0s; -} -@keyframes spinner { - 0% { - opacity: 1; - } - 100% { - opacity: 0; - } -} diff --git a/src/components/animations/Spinner.tsx b/src/components/animations/Spinner.tsx deleted file mode 100644 index d6b58fe..0000000 --- a/src/components/animations/Spinner.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { memo } from 'react'; - -import styles from './Spinner.module.css'; - -// From https://loading.io/css/ -function _Spinner({ white, classes }: { white?: boolean; classes?: string }) { - return ( -
-
-
-
-
-
-
-
-
-
-
-
-
-
- ); -} - -export const Spinner = memo(_Spinner); diff --git a/src/components/buttons/CopyButton.tsx b/src/components/buttons/CopyButton.tsx deleted file mode 100644 index efb486a..0000000 --- a/src/components/buttons/CopyButton.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import Image from 'next/image'; -import { useState } from 'react'; - -import CheckmarkIcon from '../../images/icons/checkmark.svg'; -import CopyIcon from '../../images/icons/copy-stack.svg'; -import { tryClipboardSet } from '../../utils/clipboard'; - -interface Props { - width: number; - height: number; - copyValue: string; - classes: string; -} - -export function CopyButton({ width, height, copyValue, classes }: Props) { - const [showCheckmark, setShowCheckmark] = useState(false); - - const onClick = async () => { - const result = await tryClipboardSet(copyValue); - if (result) { - setShowCheckmark(true); - setTimeout(() => setShowCheckmark(false), 2000); - } - }; - - return ( - - ); -} diff --git a/src/components/buttons/SwitchButton.module.css b/src/components/buttons/SwitchButton.module.css deleted file mode 100644 index b12025c..0000000 --- a/src/components/buttons/SwitchButton.module.css +++ /dev/null @@ -1,56 +0,0 @@ -/* The switch - the box around the slider */ -.switch { - position: relative; - display: inline-block; - width: 32px; - height: 18px; -} - -/* Hide default HTML checkbox */ -.switch input { - opacity: 0; - width: 0; - height: 0; -} - -/* The slider */ -.slider { - position: absolute; - cursor: pointer; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: #ccc; - -webkit-transition: 0.4s; - transition: 0.4s; -} - -.slider:before { - position: absolute; - content: ''; - height: 14px; - width: 14px; - left: 2px; - bottom: 2px; - background-color: white; - -webkit-transition: 0.4s; - transition: 0.4s; -} - -input:checked + .slider { - background-color: #45cd85; -} - -input:checked + .slider:before { - transform: translateX(13px); -} - -/* Rounded sliders */ -.slider.round { - border-radius: 24px; -} - -.slider.round:before { - border-radius: 50%; -} diff --git a/src/components/buttons/SwitchButton.tsx b/src/components/buttons/SwitchButton.tsx deleted file mode 100644 index ecf7224..0000000 --- a/src/components/buttons/SwitchButton.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { ChangeEvent } from 'react'; -import styles from 'src/components/buttons/SwitchButton.module.css'; - -interface Props { - checked: boolean; - onChange: (checked: boolean) => void; -} - -export function SwitchButton({ checked, onChange }: Props) { - const handleChange = (event: ChangeEvent) => { - const target = event.target; - onChange(target.checked); - }; - - return ( - - ); -} diff --git a/src/components/errors/ErrorBoundary.tsx b/src/components/errors/ErrorBoundary.tsx index 0e8b9a7..357ef02 100644 --- a/src/components/errors/ErrorBoundary.tsx +++ b/src/components/errors/ErrorBoundary.tsx @@ -1,52 +1,15 @@ -import Image from 'next/image'; -import { Component } from 'react'; - +import { ErrorBoundary as ErrorBoundaryInner } from '@hyperlane-xyz/widgets'; +import { PropsWithChildren } from 'react'; import { links } from '../../consts/links'; -import ErrorIcon from '../../images/icons/error-circle.svg'; -import { logger } from '../../utils/logger'; -interface ErrorBoundaryState { - error: any; - errorInfo: any; +export function ErrorBoundary({ children }: PropsWithChildren) { + return }>{children}; } -export class ErrorBoundary extends Component { - constructor(props: any) { - super(props); - this.state = { error: null, errorInfo: null }; - } - - componentDidCatch(error: any, errorInfo: any) { - this.setState({ - error, - errorInfo, - }); - logger.error('Error caught by error boundary', error, errorInfo); - } - - render() { - const errorInfo = this.state.error || this.state.errorInfo; - if (errorInfo) { - const details = errorInfo.message || JSON.stringify(errorInfo); - return ( -
-
- -

Fatal Error Occurred

-
{details}
- - For support, join the{' '} - Hyperlane Discord{' '} - -
-
- ); - } - return this.props.children; - } +function SupportLink() { + return ( + + For support, join the Hyperlane Discord{' '} + + ); } diff --git a/src/components/layout/HrDivider.tsx b/src/components/layout/HrDivider.tsx deleted file mode 100644 index c020cc8..0000000 --- a/src/components/layout/HrDivider.tsx +++ /dev/null @@ -1,8 +0,0 @@ -interface Props { - classes?: string; -} - -export function HrDivider(props: Props) { - const { classes } = props; - return
; -} diff --git a/src/components/search/SearchBar.tsx b/src/components/search/SearchBar.tsx index 18aeb9a..d79aecd 100644 --- a/src/components/search/SearchBar.tsx +++ b/src/components/search/SearchBar.tsx @@ -1,10 +1,10 @@ import Image from 'next/image'; import { ChangeEvent } from 'react'; -import { IconButton, XIcon } from '@hyperlane-xyz/widgets'; +import { IconButton, SpinnerIcon, XIcon } from '@hyperlane-xyz/widgets'; import SearchIcon from '../../images/icons/search.svg'; -import { Spinner } from '../animations/Spinner'; +import { Color } from '../../styles/Color'; interface Props { value: string; @@ -29,11 +29,7 @@ export function SearchBar({ value, placeholder, onChangeValue, isFetching }: Pro className="h-10 flex-1 rounded-full p-1 font-light placeholder:text-gray-600 focus:outline-none sm:h-12 sm:px-4 md:px-5" />
- {isFetching && ( -
- -
- )} + {isFetching && } {!isFetching && !value && } {!isFetching && value && ( onChange(null)}> diff --git a/src/components/search/SearchStates.tsx b/src/components/search/SearchStates.tsx index 0320897..2da819d 100644 --- a/src/components/search/SearchStates.tsx +++ b/src/components/search/SearchStates.tsx @@ -1,12 +1,11 @@ import Image from 'next/image'; -import { Fade } from '@hyperlane-xyz/widgets'; +import { Fade, SpinnerIcon } from '@hyperlane-xyz/widgets'; import BugIcon from '../../images/icons/bug.svg'; import ErrorIcon from '../../images/icons/error-circle.svg'; import SearchOffIcon from '../../images/icons/search-off.svg'; import ShrugIcon from '../../images/icons/shrug.svg'; -import { Spinner } from '../animations/Spinner'; export function SearchFetching({ show, isPiFetching }: { show: boolean; isPiFetching?: boolean }) { return ( @@ -15,8 +14,8 @@ export function SearchFetching({ show, isPiFetching }: { show: boolean; isPiFetc
-
- +
+
{isPiFetching ? 'Searching override chains for messages' : 'Searching for messages'} diff --git a/src/consts/values.ts b/src/consts/values.ts index d073d2f..b934df2 100644 --- a/src/consts/values.ts +++ b/src/consts/values.ts @@ -1,4 +1,2 @@ -export const MIN_ROUNDED_VALUE = 0.00001; -export const DISPLAY_DECIMALS = 5; export const DELIVERY_LOG_CHECK_BLOCK_RANGE = 1_000; export const PI_MESSAGE_LOG_CHECK_BLOCK_RANGE = 5_000; diff --git a/src/features/messages/MessageDetails.tsx b/src/features/messages/MessageDetails.tsx index 0113e9f..90823c7 100644 --- a/src/features/messages/MessageDetails.tsx +++ b/src/features/messages/MessageDetails.tsx @@ -4,7 +4,6 @@ import { toast } from 'react-toastify'; import { toTitleCase, trimToLength } from '@hyperlane-xyz/utils'; -import { Spinner } from '../../components/animations/Spinner'; import { Card } from '../../components/layout/Card'; import CheckmarkIcon from '../../images/icons/checkmark-circle.svg'; import { useMultiProvider, useStore } from '../../store'; @@ -14,6 +13,7 @@ import { getHumanReadableDuration } from '../../utils/time'; import { getChainDisplayName, isEvmChain } from '../chains/utils'; import { useMessageDeliveryStatus } from '../deliveryStatus/useMessageDeliveryStatus'; +import { SpinnerIcon } from '@hyperlane-xyz/widgets'; import { ContentDetailsCard } from './cards/ContentDetailsCard'; import { GasDetailsCard } from './cards/GasDetailsCard'; import { IcaDetailsCard } from './cards/IcaDetailsCard'; @@ -164,10 +164,8 @@ function StatusHeader({ let icon: React.ReactNode; if (isFetching) { icon = ( -
-
- -
+
+
); } else if (isMessageFound && messageStatus === MessageStatus.Delivered) { diff --git a/src/features/messages/MessageSearch.tsx b/src/features/messages/MessageSearch.tsx index a891c0f..4b47353 100644 --- a/src/features/messages/MessageSearch.tsx +++ b/src/features/messages/MessageSearch.tsx @@ -1,6 +1,6 @@ import { useState } from 'react'; -import { Fade } from '@hyperlane-xyz/widgets'; +import { Fade, useDebounce } from '@hyperlane-xyz/widgets'; import { Card } from '../../components/layout/Card'; import { SearchBar } from '../../components/search/SearchBar'; @@ -12,7 +12,6 @@ import { SearchUnknownError, } from '../../components/search/SearchStates'; import { useReadyMultiProvider } from '../../store'; -import useDebounce from '../../utils/debounce'; import { useQueryParam, useSyncQueryParam } from '../../utils/queryParams'; import { sanitizeString } from '../../utils/string'; diff --git a/src/features/messages/cards/CodeBlock.tsx b/src/features/messages/cards/CodeBlock.tsx index 4a5ee1f..f33a5b5 100644 --- a/src/features/messages/cards/CodeBlock.tsx +++ b/src/features/messages/cards/CodeBlock.tsx @@ -1,4 +1,4 @@ -import { CopyButton } from '../../../components/buttons/CopyButton'; +import { CopyButton } from '@hyperlane-xyz/widgets'; export function LabelAndCodeBlock({ label, value }: { label: string; value: string }) { return ( @@ -17,7 +17,7 @@ export function CodeBlock({ value }: { value: string }) { copyValue={value} width={13} height={13} - classes="absolute top-2 right-2 opacity-70" + className="absolute right-2 top-2 opacity-50" />
); diff --git a/src/features/messages/cards/GasDetailsCard.tsx b/src/features/messages/cards/GasDetailsCard.tsx index 1c102c6..54b5691 100644 --- a/src/features/messages/cards/GasDetailsCard.tsx +++ b/src/features/messages/cards/GasDetailsCard.tsx @@ -3,7 +3,7 @@ import { utils } from 'ethers'; import Image from 'next/image'; import { useMemo, useState } from 'react'; -import { fromWei, toTitleCase } from '@hyperlane-xyz/utils'; +import { BigNumberMax, fromWei, toTitleCase } from '@hyperlane-xyz/utils'; import { Tooltip } from '@hyperlane-xyz/widgets'; import { RadioButtons } from '../../../components/buttons/RadioButtons'; @@ -12,7 +12,6 @@ import { docLinks } from '../../../consts/links'; import FuelPump from '../../../images/icons/fuel-pump.svg'; import { useMultiProvider } from '../../../store'; import { Message } from '../../../types'; -import { BigNumberMax } from '../../../utils/big-number'; import { logger } from '../../../utils/logger'; import { GasPayment } from '../../debugger/types'; @@ -61,8 +60,12 @@ export function GasDetailsCard({ message, blur, igpPayments = {} }: Props) { ); let numPayments = paymentsWithAddr.length; - totalGasAmount = BigNumberMax(totalGasAmount, new BigNumber(message.totalGasAmount || 0)); - totalPaymentWei = BigNumberMax(totalPaymentWei, new BigNumber(message.totalPayment || 0)); + totalGasAmount = new BigNumber( + BigNumberMax(totalGasAmount, new BigNumber(message.totalGasAmount || 0)), + ); + totalPaymentWei = new BigNumber( + BigNumberMax(totalPaymentWei, new BigNumber(message.totalPayment || 0)), + ); numPayments = Math.max(numPayments, message.numPayments || 0); const paymentFormatted = fromWei(totalPaymentWei.toString(), decimals).toString(); diff --git a/src/features/messages/cards/KeyValueRow.tsx b/src/features/messages/cards/KeyValueRow.tsx index eecc33a..5bd9321 100644 --- a/src/features/messages/cards/KeyValueRow.tsx +++ b/src/features/messages/cards/KeyValueRow.tsx @@ -1,6 +1,5 @@ import { isZeroish } from '@hyperlane-xyz/utils'; - -import { CopyButton } from '../../../components/buttons/CopyButton'; +import { CopyButton } from '@hyperlane-xyz/widgets'; interface Props { label: string; @@ -34,7 +33,7 @@ export function KeyValueRow({ {subDisplay && !useFallbackVal && {subDisplay}}
{showCopy && !useFallbackVal && ( - + )}
); diff --git a/src/features/messages/cards/TransactionCard.tsx b/src/features/messages/cards/TransactionCard.tsx index 5dd076a..628f62f 100644 --- a/src/features/messages/cards/TransactionCard.tsx +++ b/src/features/messages/cards/TransactionCard.tsx @@ -3,9 +3,8 @@ import { PropsWithChildren, ReactNode, useState } from 'react'; import { MultiProvider } from '@hyperlane-xyz/sdk'; import { ProtocolType, isAddress, isZeroish, strip0x } from '@hyperlane-xyz/utils'; -import { Modal, Tooltip, useModal } from '@hyperlane-xyz/widgets'; +import { Modal, SpinnerIcon, Tooltip, useModal } from '@hyperlane-xyz/widgets'; -import { Spinner } from '../../../components/animations/Spinner'; import { ChainLogo } from '../../../components/icons/ChainLogo'; import { Card } from '../../../components/layout/Card'; import { links } from '../../../consts/links'; @@ -86,7 +85,9 @@ export function DestinationTransactionCard({ content = (
Checking delivery status and inspecting message
- +
+ +
); } else if (status === MessageStatus.Failing) { @@ -136,7 +137,9 @@ export function DestinationTransactionCard({ Please ensure a relayer is running for this chain.
)} - +
+ +
diff --git a/src/features/messages/queries/useMessageQuery.ts b/src/features/messages/queries/useMessageQuery.ts index 1e09470..62be9d6 100644 --- a/src/features/messages/queries/useMessageQuery.ts +++ b/src/features/messages/queries/useMessageQuery.ts @@ -3,9 +3,9 @@ import { useQuery } from 'urql'; import { useMultiProvider } from '../../../store'; import { MessageStatus } from '../../../types'; -import { useInterval } from '../../../utils/useInterval'; import { useScrapedDomains } from '../../chains/queries/useScrapedChains'; +import { useInterval } from '@hyperlane-xyz/widgets'; import { MessageIdentifierType, buildMessageQuery, buildMessageSearchQuery } from './build'; import { searchValueToPostgresBytea } from './encoding'; import { MessagesQueryResult, MessagesStubQueryResult } from './fragments'; diff --git a/src/images/icons/chevron-compact-left.svg b/src/images/icons/chevron-compact-left.svg deleted file mode 100644 index ea287cf..0000000 --- a/src/images/icons/chevron-compact-left.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/images/icons/chevron-compact-right.svg b/src/images/icons/chevron-compact-right.svg deleted file mode 100644 index 4933b1c..0000000 --- a/src/images/icons/chevron-compact-right.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/images/icons/chevron-down.svg b/src/images/icons/chevron-down.svg deleted file mode 100644 index 7ce35e5..0000000 --- a/src/images/icons/chevron-down.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/images/icons/clipboard-plus.svg b/src/images/icons/clipboard-plus.svg deleted file mode 100644 index 8a79efc..0000000 --- a/src/images/icons/clipboard-plus.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/images/icons/copy-stack.svg b/src/images/icons/copy-stack.svg deleted file mode 100644 index 140da76..0000000 --- a/src/images/icons/copy-stack.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/images/icons/cube.svg b/src/images/icons/cube.svg deleted file mode 100644 index b5a077d..0000000 --- a/src/images/icons/cube.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/images/icons/database.svg b/src/images/icons/database.svg deleted file mode 100644 index 1a382c8..0000000 --- a/src/images/icons/database.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/images/icons/gear.svg b/src/images/icons/gear.svg deleted file mode 100644 index 988f77e..0000000 --- a/src/images/icons/gear.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/images/icons/question-circle.svg b/src/images/icons/question-circle.svg deleted file mode 100644 index 951ea09..0000000 --- a/src/images/icons/question-circle.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/images/icons/question-mark.svg b/src/images/icons/question-mark.svg deleted file mode 100644 index c5921de..0000000 --- a/src/images/icons/question-mark.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/images/icons/wallet.svg b/src/images/icons/wallet.svg deleted file mode 100644 index 351b497..0000000 --- a/src/images/icons/wallet.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/images/icons/x-circle.svg b/src/images/icons/x-circle.svg deleted file mode 100644 index b34fb64..0000000 --- a/src/images/icons/x-circle.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/images/icons/x.svg b/src/images/icons/x.svg deleted file mode 100644 index ea0b542..0000000 --- a/src/images/icons/x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/images/logos/discord-alt.svg b/src/images/logos/discord-alt.svg deleted file mode 100644 index 69b452f..0000000 --- a/src/images/logos/discord-alt.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/images/logos/discord.svg b/src/images/logos/discord.svg deleted file mode 100644 index 1ff21c4..0000000 --- a/src/images/logos/discord.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/images/logos/github.svg b/src/images/logos/github.svg deleted file mode 100644 index bb4e45c..0000000 --- a/src/images/logos/github.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/images/logos/hyperlane-chevron-single-blue.svg b/src/images/logos/hyperlane-chevron-single-blue.svg deleted file mode 100644 index 49e5f23..0000000 --- a/src/images/logos/hyperlane-chevron-single-blue.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/images/logos/hyperlane-chevron.svg b/src/images/logos/hyperlane-chevron.svg deleted file mode 100644 index 048e7d8..0000000 --- a/src/images/logos/hyperlane-chevron.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/images/logos/medium.svg b/src/images/logos/medium.svg deleted file mode 100644 index 11be42c..0000000 --- a/src/images/logos/medium.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/images/logos/metamask.svg b/src/images/logos/metamask.svg deleted file mode 100644 index 9da6a50..0000000 --- a/src/images/logos/metamask.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/images/logos/twitter.svg b/src/images/logos/twitter.svg deleted file mode 100644 index 8a83fa6..0000000 --- a/src/images/logos/twitter.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/images/logos/wallet-connect.svg b/src/images/logos/wallet-connect.svg deleted file mode 100644 index 9560102..0000000 --- a/src/images/logos/wallet-connect.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 1f3f9f0..7fd4243 100755 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -7,13 +7,13 @@ import { Provider as UrqlProvider, createClient as createUrqlClient } from 'urql import '@hyperlane-xyz/widgets/styles.css'; +import { useIsSsr } from '@hyperlane-xyz/widgets'; import { AppLayout } from '../AppLayout'; import { ErrorBoundary } from '../components/errors/ErrorBoundary'; import { config } from '../consts/config'; import { ChainConfigSyncer } from '../features/chains/ChainConfigSyncer'; import { MAIN_FONT } from '../styles/fonts'; import '../styles/global.css'; -import { useIsSsr } from '../utils/ssr'; const urqlClient = createUrqlClient({ url: config.apiUrl, diff --git a/src/utils/big-number.ts b/src/utils/big-number.ts deleted file mode 100644 index c158928..0000000 --- a/src/utils/big-number.ts +++ /dev/null @@ -1,9 +0,0 @@ -import BigNumber from 'bignumber.js'; - -export function BigNumberMin(bn1: BigNumber, bn2: BigNumber) { - return bn1.gte(bn2) ? bn2 : bn1; -} - -export function BigNumberMax(bn1: BigNumber, bn2: BigNumber) { - return bn1.lte(bn2) ? bn2 : bn1; -} diff --git a/src/utils/clipboard.ts b/src/utils/clipboard.ts deleted file mode 100644 index 04b7c39..0000000 --- a/src/utils/clipboard.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { logger } from './logger'; - -export function isClipboardReadSupported() { - return !!navigator?.clipboard?.readText; -} - -export async function tryClipboardSet(value: string) { - try { - await navigator.clipboard.writeText(value); - return true; - } catch (error) { - logger.error('Failed to set clipboard', error); - return false; - } -} - -export async function tryClipboardGet() { - try { - // Note: doesn't work in firefox, which only allows extensions to read clipboard - return await navigator.clipboard.readText(); - } catch (error) { - logger.error('Failed to read from clipboard', error); - return null; - } -} diff --git a/src/utils/debounce.ts b/src/utils/debounce.ts deleted file mode 100644 index f0a528b..0000000 --- a/src/utils/debounce.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { useEffect, useState } from 'react'; - -// Based on https://usehooks.com/useDebounce -export default function useDebounce(value: T, delayMs = 500): T { - const [debouncedValue, setDebouncedValue] = useState(value); - - useEffect(() => { - const handler = setTimeout(() => { - setDebouncedValue(value); - }, delayMs); - - return () => { - clearTimeout(handler); - }; - }, [value, delayMs]); - - return debouncedValue; -} diff --git a/src/utils/explorers.ts b/src/utils/explorers.ts index d50d999..cdf791a 100644 --- a/src/utils/explorers.ts +++ b/src/utils/explorers.ts @@ -1,14 +1,15 @@ +// TODO de-dupe this file with widgets lib's utils/explorers.ts +// The widgets lib doesn't export those yet, need to fix that first. import { BigNumber, providers } from 'ethers'; import { MultiProvider } from '@hyperlane-xyz/sdk'; -import { sleep } from '@hyperlane-xyz/utils'; +import { fetchWithTimeout, sleep } from '@hyperlane-xyz/utils'; import { config } from '../consts/config'; import type { ExtendedLog } from '../types'; import { logger } from './logger'; import { toDecimalNumber, tryToDecimalNumber } from './number'; -import { fetchWithTimeout } from './timeout'; const BLOCK_EXPLORER_RATE_LIMIT = 6000; // once every 6 seconds // Used for crude rate-limiting of explorer queries without API keys @@ -53,7 +54,7 @@ async function executeQuery

(url: URL) { if (waitTime > 0) await sleep(waitTime); } - const response = await fetchWithTimeout(url); + const response = await fetchWithTimeout(url.toString()); if (!response.ok) { throw new Error(`Fetch response not okay: ${response.status}`); } diff --git a/src/utils/ssr.ts b/src/utils/ssr.ts deleted file mode 100644 index 897d2c6..0000000 --- a/src/utils/ssr.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { useEffect, useState } from 'react'; - -// Is the component server-side rendering or not -export function useIsSsr() { - const [isSsr, setIsSsr] = useState(true); - useEffect(() => { - setIsSsr(false); - }, []); - return isSsr; -} diff --git a/src/utils/timeout.ts b/src/utils/timeout.ts deleted file mode 100644 index a0b66db..0000000 --- a/src/utils/timeout.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { useCallback, useEffect, useRef } from 'react'; - -// https://medium.com/javascript-in-plain-english/usetimeout-react-hook-3cc58b94af1f -export const useTimeout = ( - callback: () => void, - delay = 0, // in ms (default: immediately put into JS Event Queue) -): (() => void) => { - const timeoutIdRef = useRef(); - - const cancel = useCallback(() => { - const timeoutId = timeoutIdRef.current; - if (timeoutId) { - timeoutIdRef.current = undefined; - clearTimeout(timeoutId); - } - }, [timeoutIdRef]); - - useEffect(() => { - if (delay >= 0) { - timeoutIdRef.current = setTimeout(callback, delay); - } - return cancel; - }, [callback, delay, cancel]); - - return cancel; -}; - -export async function fetchWithTimeout( - resource: RequestInfo | URL, - options?: RequestInit, - timeout = 10000, -) { - const controller = new AbortController(); - const id = setTimeout(() => controller.abort(), timeout); - const response = await fetch(resource, { - ...options, - signal: controller.signal, - }); - clearTimeout(id); - return response; -} diff --git a/src/utils/url.ts b/src/utils/url.ts deleted file mode 100644 index fa62b4c..0000000 --- a/src/utils/url.ts +++ /dev/null @@ -1,9 +0,0 @@ -export function isValidHttpUrl(string) { - let url; - try { - url = new URL(string); - } catch (_) { - return false; - } - return url.protocol === 'http:' || url.protocol === 'https:'; -} diff --git a/src/utils/useInterval.ts b/src/utils/useInterval.ts deleted file mode 100644 index f0759e2..0000000 --- a/src/utils/useInterval.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { useEffect, useLayoutEffect, useRef } from 'react'; - -const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect; - -// https://usehooks-typescript.com/react-hook/use-interval -export function useInterval(callback: () => void, delay: number | null) { - const savedCallback = useRef(callback); - - // Remember the latest callback if it changes. - useIsomorphicLayoutEffect(() => { - savedCallback.current = callback; - }, [callback]); - - // Set up the interval. - useEffect(() => { - // Don't schedule if no delay is specified. - // Note: 0 is a valid value for delay. - if (!delay && delay !== 0) { - return; - } - - const id = setInterval(() => savedCallback.current(), delay); - - return () => clearInterval(id); - }, [delay]); -}