From 68d5e7d84e1d867ab08a74858650e3a1e3b68fbd Mon Sep 17 00:00:00 2001 From: Greg Skriloff <35093316+gskril@users.noreply.github.com> Date: Tue, 10 Oct 2023 10:52:46 -0400 Subject: [PATCH 1/2] Remove hardcoded TLDs and debounce name input --- .../scaffold-eth/Input/AddressInput.tsx | 38 +++++++++++-------- .../components/scaffold-eth/Input/utils.ts | 4 ++ 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/packages/nextjs/components/scaffold-eth/Input/AddressInput.tsx b/packages/nextjs/components/scaffold-eth/Input/AddressInput.tsx index d623caba0..6b7ba0fac 100644 --- a/packages/nextjs/components/scaffold-eth/Input/AddressInput.tsx +++ b/packages/nextjs/components/scaffold-eth/Input/AddressInput.tsx @@ -1,28 +1,34 @@ import { useCallback, useEffect, useState } from "react"; import { blo } from "blo"; -import { isAddress } from "viem"; -import { Address } from "viem"; +import { useDebounce } from "usehooks-ts"; +import { Address, isAddress } from "viem"; import { useEnsAddress, useEnsAvatar, useEnsName } from "wagmi"; -import { CommonInputProps, InputBase } from "~~/components/scaffold-eth"; - -// ToDo: move this function to an utility file -const isENS = (address = "") => address.endsWith(".eth") || address.endsWith(".xyz"); +import { CommonInputProps, InputBase, isENS } from "~~/components/scaffold-eth"; /** * Address input with ENS name resolution */ export const AddressInput = ({ value, name, placeholder, onChange, disabled }: CommonInputProps
) => { + // Debounce the input to keep clean RPC calls when resolving ENS names + // If the input is an address, we don't need to debounce it + const _debouncedValue = useDebounce(value, 500); + const debouncedValue = isAddress(value) ? value : _debouncedValue; + const isDebouncedValueLive = debouncedValue === value; + + // If the user changes the input after an ENS name is already resolved, we want to remove the stale result + const settledValue = isDebouncedValueLive ? debouncedValue : undefined; + const { data: ensAddress, isLoading: isEnsAddressLoading } = useEnsAddress({ - name: value, - enabled: isENS(value), + name: settledValue, + enabled: isENS(debouncedValue), chainId: 1, cacheTime: 30_000, }); const [enteredEnsName, setEnteredEnsName] = useState(); const { data: ensName, isLoading: isEnsNameLoading } = useEnsName({ - address: value, - enabled: isAddress(value), + address: settledValue, + enabled: isAddress(debouncedValue), chainId: 1, cacheTime: 30_000, }); @@ -39,9 +45,9 @@ export const AddressInput = ({ value, name, placeholder, onChange, disabled }: C if (!ensAddress) return; // ENS resolved successfully - setEnteredEnsName(value); + setEnteredEnsName(debouncedValue); onChange(ensAddress); - }, [ensAddress, onChange, value]); + }, [ensAddress, onChange, debouncedValue]); const handleChange = useCallback( (newValue: Address) => { @@ -75,9 +81,11 @@ export const AddressInput = ({ value, name, placeholder, onChange, disabled }: C ) } suffix={ - // Don't want to use nextJS Image here (and adding remote patterns for the URL) - // eslint-disable-next-line @next/next/no-img-element - value && + debouncedValue && ( + // Don't want to use nextJS Image here (and adding remote patterns for the URL) + // eslint-disable-next-line @next/next/no-img-element + + ) } /> ); diff --git a/packages/nextjs/components/scaffold-eth/Input/utils.ts b/packages/nextjs/components/scaffold-eth/Input/utils.ts index f0655aa7f..764ec34b8 100644 --- a/packages/nextjs/components/scaffold-eth/Input/utils.ts +++ b/packages/nextjs/components/scaffold-eth/Input/utils.ts @@ -105,3 +105,7 @@ export const isValidInteger = (dataType: IntegerVariant, value: bigint | string, } return true; }; + +// Treat any dot-separated string as a potential ENS name +const ensRegex = /.+\..+/; +export const isENS = (address = "") => ensRegex.test(address); From c3fd04b384eedcbac4a0889b6b2df6a36a4cef30 Mon Sep 17 00:00:00 2001 From: Greg Skriloff <35093316+gskril@users.noreply.github.com> Date: Tue, 10 Oct 2023 14:18:22 -0400 Subject: [PATCH 2/2] Show a new blockie on each keystroke --- .../nextjs/components/scaffold-eth/Input/AddressInput.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/nextjs/components/scaffold-eth/Input/AddressInput.tsx b/packages/nextjs/components/scaffold-eth/Input/AddressInput.tsx index 6b7ba0fac..7bfcd1680 100644 --- a/packages/nextjs/components/scaffold-eth/Input/AddressInput.tsx +++ b/packages/nextjs/components/scaffold-eth/Input/AddressInput.tsx @@ -81,11 +81,9 @@ export const AddressInput = ({ value, name, placeholder, onChange, disabled }: C ) } suffix={ - debouncedValue && ( - // Don't want to use nextJS Image here (and adding remote patterns for the URL) - // eslint-disable-next-line @next/next/no-img-element - - ) + // Don't want to use nextJS Image here (and adding remote patterns for the URL) + // eslint-disable-next-line @next/next/no-img-element + value && } /> );