From 7c34f62bfccc3ad4be95c1c82dfb680e2b7d4f19 Mon Sep 17 00:00:00 2001 From: "Shiv Bhonde | shivbhonde.eth" Date: Thu, 15 Feb 2024 23:54:48 +0530 Subject: [PATCH 1/8] add basic example to show connected address (#721) --- packages/nextjs/app/page.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/nextjs/app/page.tsx b/packages/nextjs/app/page.tsx index 035b3314c..2a84037f9 100644 --- a/packages/nextjs/app/page.tsx +++ b/packages/nextjs/app/page.tsx @@ -1,16 +1,26 @@ +"use client"; + import Link from "next/link"; import type { NextPage } from "next"; +import { useAccount } from "wagmi"; import { BugAntIcon, MagnifyingGlassIcon } from "@heroicons/react/24/outline"; +import { Address } from "~~/components/scaffold-eth"; const Home: NextPage = () => { + const { address: connectedAddress } = useAccount(); + return ( <>
-

+

Welcome to Scaffold-ETH 2

+
+

Connected Address:

+
+

Get started by editing{" "} From edb6c108d243db6bfdc398209e9e0956665360bb Mon Sep 17 00:00:00 2001 From: Thomas Jay Rush Date: Tue, 20 Feb 2024 10:16:24 -0500 Subject: [PATCH 2/8] Standardize displaying of address and follow ERC-55 (#734) Co-authored-by: Shiv Bhonde --- .../components/scaffold-eth/Address.tsx | 23 +++++++++++-------- .../AddressInfoDropdown.tsx | 12 ++++++---- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/packages/nextjs/components/scaffold-eth/Address.tsx b/packages/nextjs/components/scaffold-eth/Address.tsx index bc8bfffa2..1c1ad600a 100644 --- a/packages/nextjs/components/scaffold-eth/Address.tsx +++ b/packages/nextjs/components/scaffold-eth/Address.tsx @@ -3,7 +3,7 @@ import { useEffect, useState } from "react"; import Link from "next/link"; import { CopyToClipboard } from "react-copy-to-clipboard"; -import { Address as AddressType, isAddress } from "viem"; +import { Address as AddressType, getAddress, isAddress } from "viem"; import { hardhat } from "viem/chains"; import { useEnsAvatar, useEnsName } from "wagmi"; import { CheckCircleIcon, DocumentDuplicateIcon } from "@heroicons/react/24/outline"; @@ -35,10 +35,15 @@ export const Address = ({ address, disableAddressLink, format, size = "base" }: const [ens, setEns] = useState(); const [ensAvatar, setEnsAvatar] = useState(); const [addressCopied, setAddressCopied] = useState(false); + const checkSumAddress = address ? getAddress(address) : undefined; const { targetNetwork } = useTargetNetwork(); - const { data: fetchedEns } = useEnsName({ address, enabled: isAddress(address ?? ""), chainId: 1 }); + const { data: fetchedEns } = useEnsName({ + address: checkSumAddress, + enabled: isAddress(checkSumAddress ?? ""), + chainId: 1, + }); const { data: fetchedEnsAvatar } = useEnsAvatar({ name: fetchedEns, enabled: Boolean(fetchedEns), @@ -56,7 +61,7 @@ export const Address = ({ address, disableAddressLink, format, size = "base" }: }, [fetchedEnsAvatar]); // Skeleton UI - if (!address) { + if (!checkSumAddress) { return (

@@ -67,24 +72,24 @@ export const Address = ({ address, disableAddressLink, format, size = "base" }: ); } - if (!isAddress(address)) { + if (!isAddress(checkSumAddress)) { return Wrong address; } - const blockExplorerAddressLink = getBlockExplorerAddressLink(targetNetwork, address); - let displayAddress = address?.slice(0, 5) + "..." + address?.slice(-4); + const blockExplorerAddressLink = getBlockExplorerAddressLink(targetNetwork, checkSumAddress); + let displayAddress = checkSumAddress?.slice(0, 6) + "..." + checkSumAddress?.slice(-4); if (ens) { displayAddress = ens; } else if (format === "long") { - displayAddress = address; + displayAddress = checkSumAddress; } return (
@@ -112,7 +117,7 @@ export const Address = ({ address, disableAddressLink, format, size = "base" }: /> ) : ( { setAddressCopied(true); setTimeout(() => { diff --git a/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/AddressInfoDropdown.tsx b/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/AddressInfoDropdown.tsx index 9112d93e3..b86128c9b 100644 --- a/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/AddressInfoDropdown.tsx +++ b/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/AddressInfoDropdown.tsx @@ -1,6 +1,7 @@ import { useRef, useState } from "react"; import { NetworkOptions } from "./NetworkOptions"; import CopyToClipboard from "react-copy-to-clipboard"; +import { getAddress } from "viem"; import { Address, useDisconnect } from "wagmi"; import { ArrowLeftOnRectangleIcon, @@ -11,7 +12,7 @@ import { DocumentDuplicateIcon, QrCodeIcon, } from "@heroicons/react/24/outline"; -import { BlockieAvatar } from "~~/components/scaffold-eth"; +import { BlockieAvatar, isENS } from "~~/components/scaffold-eth"; import { useOutsideClick } from "~~/hooks/scaffold-eth"; import { getTargetNetworks } from "~~/utils/scaffold-eth"; @@ -31,6 +32,7 @@ export const AddressInfoDropdown = ({ blockExplorerAddressLink, }: AddressInfoDropdownProps) => { const { disconnect } = useDisconnect(); + const checkSumAddress = getAddress(address); const [addressCopied, setAddressCopied] = useState(false); @@ -46,8 +48,10 @@ export const AddressInfoDropdown = ({ <>
- - {displayName} + + + {isENS(displayName) ? displayName : checkSumAddress?.slice(0, 6) + "..." + checkSumAddress?.slice(-4)} +
    ) : ( { setAddressCopied(true); setTimeout(() => { From 16e650808d8fd1d7421c12363dc260aeb75af6a3 Mon Sep 17 00:00:00 2001 From: "Shiv Bhonde | shivbhonde.eth" Date: Fri, 23 Feb 2024 21:51:00 +0530 Subject: [PATCH 3/8] add refresh reset at ContractUI (#739) Co-authored-by: Carlos --- packages/nextjs/app/debug/_components/contract/ContractUI.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/nextjs/app/debug/_components/contract/ContractUI.tsx b/packages/nextjs/app/debug/_components/contract/ContractUI.tsx index 49f0f2ee1..31fcc7faa 100644 --- a/packages/nextjs/app/debug/_components/contract/ContractUI.tsx +++ b/packages/nextjs/app/debug/_components/contract/ContractUI.tsx @@ -1,5 +1,6 @@ "use client"; +// @refresh reset import { useReducer } from "react"; import { ContractReadMethods } from "./ContractReadMethods"; import { ContractVariables } from "./ContractVariables"; From a482feb7af081c3346b8169190f9be3e0cc2ec59 Mon Sep 17 00:00:00 2001 From: "Shiv Bhonde | shivbhonde.eth" Date: Sun, 25 Feb 2024 16:48:05 +0530 Subject: [PATCH 4/8] Fix cursor stealing & display loading for AddressInput (#738) --- .../scaffold-eth/Input/AddressInput.tsx | 41 +++++++++++++++---- .../scaffold-eth/Input/InputBase.tsx | 19 ++++++++- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/packages/nextjs/components/scaffold-eth/Input/AddressInput.tsx b/packages/nextjs/components/scaffold-eth/Input/AddressInput.tsx index 4f057015a..164664466 100644 --- a/packages/nextjs/components/scaffold-eth/Input/AddressInput.tsx +++ b/packages/nextjs/components/scaffold-eth/Input/AddressInput.tsx @@ -1,6 +1,6 @@ import { useCallback, useEffect, useState } from "react"; import { blo } from "blo"; -import { useDebounce } from "usehooks-ts"; +import { useDebounceValue } from "usehooks-ts"; import { Address, isAddress } from "viem"; import { useEnsAddress, useEnsAvatar, useEnsName } from "wagmi"; import { CommonInputProps, InputBase, isENS } from "~~/components/scaffold-eth"; @@ -11,29 +11,39 @@ import { CommonInputProps, InputBase, isENS } from "~~/components/scaffold-eth"; 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] = useDebounceValue(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({ + const { + data: ensAddress, + isLoading: isEnsAddressLoading, + isError: isEnsAddressError, + isSuccess: isEnsAddressSuccess, + } = useEnsAddress({ name: settledValue, - enabled: isENS(debouncedValue), + enabled: isDebouncedValueLive && isENS(debouncedValue), chainId: 1, cacheTime: 30_000, }); const [enteredEnsName, setEnteredEnsName] = useState(); - const { data: ensName, isLoading: isEnsNameLoading } = useEnsName({ + const { + data: ensName, + isLoading: isEnsNameLoading, + isError: isEnsNameError, + isSuccess: isEnsNameSuccess, + } = useEnsName({ address: settledValue as Address, enabled: isAddress(debouncedValue), chainId: 1, cacheTime: 30_000, }); - const { data: ensAvatar } = useEnsAvatar({ + const { data: ensAvatar, isLoading: isEnsAvtarLoading } = useEnsAvatar({ name: ensName, enabled: Boolean(ensName), chainId: 1, @@ -57,6 +67,14 @@ export const AddressInput = ({ value, name, placeholder, onChange, disabled }: C [onChange], ); + const reFocus = + isEnsAddressError || + isEnsNameError || + isEnsNameSuccess || + isEnsAddressSuccess || + ensName === null || + ensAddress === null; + return ( name={name} @@ -65,9 +83,11 @@ export const AddressInput = ({ value, name, placeholder, onChange, disabled }: C value={value as Address} onChange={handleChange} disabled={isEnsAddressLoading || isEnsNameLoading || disabled} + reFocus={reFocus} prefix={ - ensName && ( + ensName ? (
    + {isEnsAvtarLoading &&
    } {ensAvatar ? ( { @@ -78,6 +98,13 @@ export const AddressInput = ({ value, name, placeholder, onChange, disabled }: C ) : null} {enteredEnsName ?? ensName}
    + ) : ( + (isEnsNameLoading || isEnsAddressLoading) && ( +
    +
    +
    +
    + ) ) } suffix={ diff --git a/packages/nextjs/components/scaffold-eth/Input/InputBase.tsx b/packages/nextjs/components/scaffold-eth/Input/InputBase.tsx index 73d5a4f8a..f38bca217 100644 --- a/packages/nextjs/components/scaffold-eth/Input/InputBase.tsx +++ b/packages/nextjs/components/scaffold-eth/Input/InputBase.tsx @@ -1,10 +1,11 @@ -import { ChangeEvent, ReactNode, useCallback } from "react"; +import { ChangeEvent, FocusEvent, ReactNode, useCallback, useEffect, useRef } from "react"; import { CommonInputProps } from "~~/components/scaffold-eth"; type InputBaseProps = CommonInputProps & { error?: boolean; prefix?: ReactNode; suffix?: ReactNode; + reFocus?: boolean; }; export const InputBase = string } | undefined = string>({ @@ -16,7 +17,10 @@ export const InputBase = string } | undefined = str disabled, prefix, suffix, + reFocus, }: InputBaseProps) => { + const inputReft = useRef(null); + let modifier = ""; if (error) { modifier = "border-error"; @@ -31,6 +35,17 @@ export const InputBase = string } | undefined = str [onChange], ); + // Runs only when reFocus prop is passed, usefull for setting the cursor + // at the end of the input. Example AddressInput + const onFocus = (e: FocusEvent) => { + if (reFocus !== undefined) { + e.currentTarget.setSelectionRange(e.currentTarget.value.length, e.currentTarget.value.length); + } + }; + useEffect(() => { + if (reFocus !== undefined && reFocus === true) inputReft.current?.focus(); + }, [reFocus]); + return (
    {prefix} @@ -42,6 +57,8 @@ export const InputBase = string } | undefined = str onChange={handleChange} disabled={disabled} autoComplete="off" + ref={inputReft} + onFocus={onFocus} /> {suffix}
    From 092f2ad568e5ea18681f21268754584f2b65d975 Mon Sep 17 00:00:00 2001 From: Shiv Bhonde Date: Mon, 26 Feb 2024 19:49:05 +0530 Subject: [PATCH 5/8] add changeset --- .changeset/lucky-tigers-unite.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .changeset/lucky-tigers-unite.md diff --git a/.changeset/lucky-tigers-unite.md b/.changeset/lucky-tigers-unite.md new file mode 100644 index 000000000..7f39cbb28 --- /dev/null +++ b/.changeset/lucky-tigers-unite.md @@ -0,0 +1,8 @@ +--- +"create-eth": patch +--- + +1. basic example to show connected address (#721) +2. Standardize displaying of address and follow ERC-55 (#734) +3. fix contract balance hot reload balance issue (#739) +4. Fix cursor stealing & display loading for AddressInput (#738) From 186b2ced38fae75516059416ef0b2fd02c5b6c18 Mon Sep 17 00:00:00 2001 From: "Shiv Bhonde | shivbhonde.eth" Date: Mon, 26 Feb 2024 22:15:47 +0530 Subject: [PATCH 6/8] comparison with lowercase addresses (#741) --- packages/nextjs/app/blockexplorer/address/[address]/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nextjs/app/blockexplorer/address/[address]/page.tsx b/packages/nextjs/app/blockexplorer/address/[address]/page.tsx index c154a760a..dda48baf2 100644 --- a/packages/nextjs/app/blockexplorer/address/[address]/page.tsx +++ b/packages/nextjs/app/blockexplorer/address/[address]/page.tsx @@ -60,7 +60,7 @@ const getContractData = async (address: string) => { const deployedContractsOnChain = contracts ? contracts[chainId] : {}; for (const [contractName, contractInfo] of Object.entries(deployedContractsOnChain)) { - if (contractInfo.address.toLowerCase() === address) { + if (contractInfo.address.toLowerCase() === address.toLowerCase()) { contractPath = `contracts/${contractName}.sol`; break; } From 3921477a53b19996ddd28b32cfc261802bb846d3 Mon Sep 17 00:00:00 2001 From: port <108868128+portdeveloper@users.noreply.github.com> Date: Mon, 26 Feb 2024 21:26:57 +0300 Subject: [PATCH 7/8] Match link name with actual tab name (#743) --- packages/nextjs/app/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nextjs/app/page.tsx b/packages/nextjs/app/page.tsx index 2a84037f9..fcca994c5 100644 --- a/packages/nextjs/app/page.tsx +++ b/packages/nextjs/app/page.tsx @@ -46,7 +46,7 @@ const Home: NextPage = () => {

    Tinker with your smart contract using the{" "} - Debug Contract + Debug Contracts {" "} tab.

    From 8b55994208fda5f5245d07e60b60473ad570aa2a Mon Sep 17 00:00:00 2001 From: Shiv Bhonde Date: Tue, 27 Feb 2024 00:15:39 +0530 Subject: [PATCH 8/8] update change set --- .changeset/lucky-tigers-unite.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.changeset/lucky-tigers-unite.md b/.changeset/lucky-tigers-unite.md index 7f39cbb28..18100406f 100644 --- a/.changeset/lucky-tigers-unite.md +++ b/.changeset/lucky-tigers-unite.md @@ -6,3 +6,5 @@ 2. Standardize displaying of address and follow ERC-55 (#734) 3. fix contract balance hot reload balance issue (#739) 4. Fix cursor stealing & display loading for AddressInput (#738) +5. Fix blockexplorer code tab (#741) +6. Match link name with actual tab name for Debug Contracts (#743)