# Scaffold UI > React components and hooks for Ethereum dApps import React, { useMemo } from "react"; import { Address } from "@scaffold-ui/components"; import { DocsProvider } from "../../components/DocsProvider"; ## Address Component The `Address` component displays Ethereum addresses with automatic ENS resolution, avatar display, and block explorer linking. ### Import ```tsx import { Address } from "@scaffold-ui/components"; ``` ### Props | Prop | Type | Default | Description | | -------------------- | ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------------------- | | `address` | `Address` | - | The Ethereum address to display | | `disableAddressLink` | `boolean` | `false` | Disable linking to block explorer | | `format` | `"short" \| "long"` | `"short"` | Display format for the address | | `size` | `"xs" \| "sm" \| "base" \| "lg" \| "xl" \| "2xl" \| "3xl"` | `"base"` | Size of the component | | `onlyEnsOrAddress` | `boolean` | `false` | Show only ENS name or address (not both) | | `chain` | `Chain` | First chain from [WagmiProvider](https://wagmi.sh/react/api/WagmiProvider) config or `mainnet` | Blockchain network for resolution | | `style` | `CSSProperties` | - | Custom CSS styles (memoize to prevent re-renders) | ### Live Examples #### Basic Usage
```tsx twoslash import React from "react"; import { Address } from "@scaffold-ui/components";
; ``` #### Different Sizes
```tsx twoslash import React from "react"; import { Address } from "@scaffold-ui/components";
;
; ``` #### Long Format
```tsx twoslash import React from "react"; import { Address } from "@scaffold-ui/components";
; ``` #### Disable Block Explorer Link
```tsx twoslash import React from "react"; import { Address } from "@scaffold-ui/components";
; ``` #### ENS or Address Only
```tsx twoslash import React from "react"; import { Address } from "@scaffold-ui/components";
; ``` #### Custom Chain import { polygon } from "viem/chains";
```tsx twoslash import React from "react"; import { polygon } from "viem/chains"; import { Address } from "@scaffold-ui/components";
; ``` #### Invalid Address Handling When an invalid Ethereum address is provided, the component displays an error message with "Invalid address" text.
```tsx twoslash import React from "react"; import { Address } from "@scaffold-ui/components"; // Invalid address - shows error message
; ``` import React, { useMemo } from "react"; import { AddressInput } from "@scaffold-ui/components"; import { DocsProvider } from "../../components/DocsProvider"; import { AddressInputExample } from "../../components/AddressInputExample"; ## AddressInput Component The `AddressInput` component is an enhanced input for Ethereum addresses and ENS names. It automatically resolves ENS names to addresses (and vice versa), shows ENS avatars when available, displays loading and error states, and renders a deterministic identicon for addresses. ### Import ```tsx import { AddressInput } from "@scaffold-ui/components"; ``` ### Props | Prop | Type | Default | Description | | ------------- | ------------------------------------ | ------- | ------------------------------------------------------------------------------------- | | `value` | `Address \| string` | - | Current input value. Accepts an Ethereum address or an ENS name. | | `onChange` | `(value: Address \| string) => void` | - | Called when the input changes. After ENS resolution, it emits the resolved `Address`. | | `name` | `string` | - | Name attribute of the input element. | | `placeholder` | `string` | - | Placeholder text for the input. | | `disabled` | `boolean` | `false` | Disables the input. While resolving ENS, the input is temporarily disabled. | | `style` | `CSSProperties` | - | Custom CSS styles (memoize to prevent re-renders) | ### Live Examples #### Placeholder ```tsx import React, { useState } from "react"; import { AddressInput } from "@scaffold-ui/components"; function ParentComponent() { const [value, setValue] = useState(""); return ( ); } ``` #### Default value (ENS Name) ```tsx import React, { useState } from "react"; import { AddressInput } from "@scaffold-ui/components"; function ParentComponent() { const [value, setValue] = useState("vitalik.eth"); return ( ); } ``` #### Default value (Ethereum Address) ```tsx import React, { useState } from "react"; import { AddressInput } from "@scaffold-ui/components"; function ParentComponent() { const [value, setValue] = useState("0xd8da6bf26964af9d7eed9e03e53415d37aa96045"); return ( ); } ``` #### Disabled State ```tsx import React, { useState } from "react"; import { AddressInput } from "@scaffold-ui/components"; function ParentComponent() { const [value, setValue] = useState("0x1234567890123456789012345678901234567890"); return ( ); } ``` import React, { useMemo } from "react"; import { Balance } from "@scaffold-ui/components"; import { DocsProvider } from "../../components/DocsProvider"; ## Balance Component The `Balance` component displays the native token balance (e.g., ETH, MATIC) for Ethereum addresses with support for USD conversion and interactive toggling. ### Import ```tsx import { Balance } from "@scaffold-ui/components"; ``` ### Props | Prop | Type | Default | Description | | ---------------- | --------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------------------------ | | `address` | `Address` | - | **Required.** The Ethereum address to show balance for | | `chain` | `Chain` | First chain from [WagmiProvider](https://wagmi.sh/react/api/WagmiProvider) config or `mainnet` | Blockchain network to query | | `defaultUsdMode` | `boolean` | `false` | Start in USD display mode | | `style` | `CSSProperties` | - | Custom CSS styles (memoize to prevent re-renders) | ### Live Examples #### Basic Usage ```tsx ``` #### Default USD Mode ```tsx ``` #### Custom Chain import { polygon } from "viem/chains"; ```tsx import { polygon } from "viem/chains"; ; ``` import React from "react"; import { BaseInput } from "@scaffold-ui/components"; import { DocsProvider } from "../../components/DocsProvider"; import { BaseInputExample } from "../../components/BaseInputExample"; ## BaseInput Component The `BaseInput` component is a styled input used as the foundation for custom inputs like `AddressInput` and `EtherInput`. It supports prefix and suffix elements, and handles error and disabled states. ### Import ```tsx import { BaseInput } from "@scaffold-ui/components"; ``` ### Props | Prop | Type | Default | Description | | ------------- | ------------------------- | ----------- | --------------------------------------------------------------------------------------------------- | | `value` | `string` | `undefined` | The current input value. | | `onChange` | `(value: string) => void` | - | Callback fired when the input value changes. | | `name` | `string` | - | Name attribute for the input element. | | `placeholder` | `string` | - | Placeholder text displayed when the input is empty. | | `error` | `boolean` | `false` | When `true`, applies error styling to the input border. | | `disabled` | `boolean` | `false` | When `true`, disables the input and applies disabled styling. | | `prefix` | `ReactNode` | - | Element rendered before the input (e.g., an icon). | | `suffix` | `ReactNode` | - | Element rendered after the input (e.g., a button or icon). | | `reFocus` | `boolean` | - | When `true`, auto-focuses the input and positions cursor at the end. Useful for programmatic focus. | | `style` | `CSSProperties` | - | Custom inline styles for the input container. | ### Live Examples #### Basic Usage ```tsx import React, { useState } from "react"; import { BaseInput } from "@scaffold-ui/components"; function BasicInput() { const [value, setValue] = useState(""); return ( ); } ``` #### With Prefix and Suffix $} suffix={USD} /> ```tsx import React, { useState } from "react"; import { BaseInput } from "@scaffold-ui/components"; function CurrencyInput() { const [value, setValue] = useState(""); return ( $} suffix={USD} /> ); } ``` #### Error State ```tsx import React, { useState } from "react"; import { BaseInput } from "@scaffold-ui/components"; function InputWithValidation() { const [value, setValue] = useState("invalid-email"); const hasError = value.length > 0 && !value.includes("@"); return (
{hasError &&

Please enter a valid email

}
); } ``` #### Disabled State ```tsx import React from "react"; import { BaseInput } from "@scaffold-ui/components"; function DisabledInput() { return ( {}} disabled={true} /> ); } ``` :::info `BaseInput` is designed as a building block. For common use cases like Ethereum addresses or ETH/USD amounts, consider using the specialized [`AddressInput`](/components/AddressInput) or [`EtherInput`](/components/EtherInput) components instead. ::: import React, { useMemo } from "react"; import { EtherInput } from "@scaffold-ui/components"; import { DocsProvider } from "../../components/DocsProvider"; ## EtherInput Component The `EtherInput` component provides an input for entering values in ETH or USD with a toggle to switch modes, automatic conversion based on the current native currency price, and a callback that reports both values. ### Import ```tsx import { EtherInput } from "@scaffold-ui/components"; ``` ### Props | Prop | Type | Default | Description | | ---------------- | -------------------------------------------------------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------- | | `name` | `string` | - | Name attribute for the input element | | `placeholder` | `string` | - | Placeholder text for the input | | `defaultValue` | `string` | - | Initial value for the input | | `defaultUsdMode` | `boolean` | `false` | Start with the input in USD mode instead of ETH | | `disabled` | `boolean` | `false` | Disables the input and toggle button | | `onValueChange` | `(value: { valueInEth: string; valueInUsd: string; displayUsdMode: boolean }) => void` | - | Called when the value or display mode changes. Provides both ETH and USD values and current display mode | | `style` | `CSSProperties` | - | Custom CSS styles (memoize to prevent re-renders) | ### Live Examples #### Basic Usage
```tsx twoslash import React from "react"; import { EtherInput } from "@scaffold-ui/components"; ; ``` #### Default USD Mode ```tsx twoslash import React from "react"; import { EtherInput } from "@scaffold-ui/components"; ; ``` #### Default Value ```tsx twoslash import React from "react"; import { EtherInput } from "@scaffold-ui/components"; ; ``` #### Disabled State ```tsx twoslash import React from "react"; import { EtherInput } from "@scaffold-ui/components"; ; ``` #### onValueChange Callback { console.log({ valueInEth, valueInUsd, displayUsdMode }); }} /> ```tsx twoslash import React from "react"; import { EtherInput } from "@scaffold-ui/components"; { console.log({ valueInEth, valueInUsd, displayUsdMode }); }} />; ``` import React, { useMemo } from "react"; import { Address } from "@scaffold-ui/components"; import { DocsProvider } from "../../components/DocsProvider"; ## Styling components ### Style Prop Every component has a `style` prop that you can use to pass custom styles to the top-level element of the component. | Prop | Type | Default | Description | | ------- | --------------- | ------- | ------------------------------------------------- | | `style` | `CSSProperties` | - | Custom CSS styles (memoize to prevent re-renders) | ⚠️ **Performance Warning**: Always memoize style objects to prevent unnecessary re-renders. Example:
({ padding: "16px", borderRadius: "8px", backgroundColor: "rgba(34, 197, 94, 0.1)", }), [], )} /> ```tsx twoslash import React, { useMemo } from "react"; import { Address } from "@scaffold-ui/components"; import type { CSSProperties } from "react"; function MyComponent() { // Memoized style object const customStyle = useMemo( () => ({ padding: "16px", borderRadius: "8px", backgroundColor: "rgba(34, 197, 94, 0.1)", }) as CSSProperties, [], ); return (
); } ``` ### Redefining Inner Styles All Scaffold-UI component styles rely on the default [tailwindcss theme variables](https://tailwindcss.com/docs/theme#what-are-theme-variables) defined in [styles.css](https://github.com/scaffold-eth/scaffold-ui/blob/main/packages/components/src/styles.css). To change the inner styles of components, you need to: * Check the source code of the component to identify which variable is used for the desired style * Redefine the variable, and all dependent styles will update accordingly For example, if you want to change the text color of the Address component, you can check the [source code](https://github.com/scaffold-eth/scaffold-ui/blob/ea325159a4f733d79c99c7805fb50e4945e96873/packages/components/src/Address/Address.tsx#L82) and see that the `Address` component has the class `text-sui-primary-content`, which uses the `--color-sui-primary-content` variable for the text color. Let's redefine it:
({ "--color-sui-primary-content": "green", padding: "16px", borderRadius: "8px", backgroundColor: "rgba(34, 197, 94, 0.1)", }), [], )} /> ```tsx twoslash import React, { useMemo } from "react"; import { Address } from "@scaffold-ui/components"; import type { CSSProperties } from "react"; function MyComponent() { // Memoized style object const customStyle = useMemo( () => ({ "--color-sui-primary-content": "green", padding: "16px", borderRadius: "8px", backgroundColor: "rgba(34, 197, 94, 0.1)", }) as CSSProperties, [], ); return (
); } ``` import React, { useMemo } from "react"; import { DocsProvider } from "../../components/DocsProvider"; import { EtherInput } from "@scaffold-ui/components"; ## Theming :::info Before reading this page, we recommend checking out the [Styling](/components/Styling) page to understand the basics of styling Scaffold-UI components. ::: ### Dark Theme All Scaffold-UI component styles use the default [Tailwind CSS theme variables](https://tailwindcss.com/docs/theme#what-are-theme-variables) defined in [styles.css](https://github.com/scaffold-eth/scaffold-ui/blob/main/packages/components/src/styles.css). The stylesheet includes dark theme styles that automatically apply based on your theme configuration. ```css @import "tailwindcss"; @custom-variant dark (&:where(.dark, .dark *, [data-theme=dark], [data-theme=dark] *)); ... @variant dark { --color-sui-primary: #212638; ... } ``` To enable dark mode, add either a `.dark` class or a `[data-theme=dark]` attribute to a parent element (typically the `` or `` tag). This will automatically apply the dark variant colors to all child components. #### Setup * **Next.js apps**: We recommend using the `next-themes` library. See example implementations of [SwitchTheme](https://github.com/scaffold-eth/scaffold-ui/blob/main/example/app/components/SwitchTheme.tsx) and [ThemeProvider](https://github.com/scaffold-eth/scaffold-ui/blob/main/example/app/components/ThemeProvider.tsx). * **create-eth apps**: These components are already included and configured. * **Vite apps**: You'll need to implement theme switching manually. #### Live Example Use the theme switcher in the bottom left corner to see how the component colors change between light and dark modes. ```tsx twoslash import React from "react"; import { EtherInput } from "@scaffold-ui/components"; ; ``` ### Customizing Theme Colors Globally You can override the default theme colors by redefining CSS variables in your global stylesheet. ```css /* Override Scaffold UI theme colors */ :root { --color-sui-primary: #ff4444; --color-sui-primary-subtle: #ff9999; ... } /* Dark mode - explicit selectors matching the custom-variant definition */ .dark { --color-sui-primary: #654321; --color-sui-primary-subtle: #987654; ... } ``` ## Components Pre-built React components for common Ethereum UI patterns. ### Installation #### Peer Dependencies Install the required peer dependencies using your preferred package manager: :::code-group ```bash [npm] npm install react react-dom @types/react viem wagmi @tanstack/react-query ``` ```bash [pnpm] pnpm add react react-dom @types/react viem wagmi @tanstack/react-query ``` ```bash [yarn] yarn add react react-dom @types/react viem wagmi @tanstack/react-query ``` ::: #### Package Installation Install Scaffold UI components and hooks using your preferred package manager: :::code-group ```bash [npm] npm install @scaffold-ui/components @scaffold-ui/hooks ``` ```bash [pnpm] pnpm add @scaffold-ui/components @scaffold-ui/hooks ``` ```bash [yarn] yarn add @scaffold-ui/components @scaffold-ui/hooks ``` ::: #### Import Styles Import the styles in your root component file (`app.tsx` for React or `layout.tsx` for Next.js): ```typescript import "@scaffold-ui/components/styles.css"; ``` #### Create wagmi config and setup Tanstack query [https://wagmi.sh/react/getting-started#create-config](https://wagmi.sh/react/getting-started#create-config) import React, { useMemo } from "react"; import { ContractExample } from "../../components/ContractExample"; import { DocsProvider } from "../../components/DocsProvider"; ## Contract Component The `Contract` is a UI component for debugging deployed contracts. ### Import ```tsx import { Contract } from "@scaffold-ui/debug-contracts"; ``` ### Props | Prop | Type | Default | Description | | ---------------------- | -------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `contractName` | `string` | - | The name of the contract to display | | `contract` | `{ address: Address, abi: Abi }` | - | The abi and address of the contract to display | | `chainId` | `number` | - | The chain ID where the contract is deployed | | `blockExplorerBaseUrl` | `string` | `undefined` | Base URL of the block explorer. The component appends `/address/{addr}` per rendered address. Defaults to `/blockexplorer` for local chain (31337) and to the chain's configured explorer otherwise. | ### Live Example: ##### Code ```tsx twoslash import React from "react"; import { Contract } from "@scaffold-ui/debug-contracts"; import { deployedContracts } from "./components/ContractExample/deployedContracts"; import { sepolia } from "viem/chains"; ; ``` ##### Example import React from "react"; import { IntegerInput, IntegerVariant } from "@scaffold-ui/debug-contracts"; import { DocsProvider } from "../../components/DocsProvider"; import { IntegerInputExample } from "../../components/IntegerInputExample"; ## IntegerInput Component The `IntegerInput` component provides validation and UX helpers for Solidity integer parameters. It supports all `int` and `uint` bit-sizes, validates signed/unsigned ranges, and includes a quick `× 1e18` helper for working with wei values. ### Import ```tsx import { IntegerInput, IntegerVariant } from "@scaffold-ui/debug-contracts"; ``` ### Props | Prop | Type | Default | Description | | ----------------------- | ------------------------- | ------------------------ | --------------------------------------------------------------------------- | | `value` | `string` | - | Current input value (decimal string). | | `onChange` | `(value: string) => void` | - | Called whenever the input changes. | | `name` | `string` | `undefined` | Name attribute for the input element. | | `placeholder` | `string` | `undefined` | Placeholder text. | | `variant` | `IntegerVariant` | `IntegerVariant.UINT256` | Solidity integer type used for validation (signed/unsigned & bit length). | | `disableMultiplyBy1e18` | `boolean` | `false` | Hide the `× 1e18` helper button (useful when the value is not ETH-denoted). | | `disabled` | `boolean` | `undefined` | Disables the input. | ### Live Examples #### Basic `uint256` with helper ```tsx twoslash import React, { useState } from "react"; import { IntegerInput } from "@scaffold-ui/debug-contracts"; function BasicUint256() { const [value, setValue] = useState(""); return ( ); } ``` #### Signed integers ```tsx twoslash import React, { useState } from "react"; import { IntegerInput, IntegerVariant } from "@scaffold-ui/debug-contracts"; function SignedInput() { const [value, setValue] = useState("-42"); return ( ); } ``` #### Hide the multiply helper ```tsx twoslash import React, { useState } from "react"; import { IntegerInput } from "@scaffold-ui/debug-contracts"; function NoHelper() { const [value, setValue] = useState(""); return ( ); } ``` #### Disabled state ```tsx twoslash import React from "react"; import { IntegerInput } from "@scaffold-ui/debug-contracts"; function DisabledInteger() { return ( {}} disabled={true} /> ); } ``` ## Hooks Our components are built on top of these React hooks, which you can use directly to create your own custom Ethereum components, or even combine them to build more complex ones. ### Installation #### Peer Dependencies Install the required peer dependencies using your preferred package manager: :::code-group ```bash [npm] npm install react react-dom @types/react viem wagmi @tanstack/react-query ``` ```bash [pnpm] pnpm add react react-dom @types/react viem wagmi @tanstack/react-query ``` ```bash [yarn] yarn add react react-dom @types/react viem wagmi @tanstack/react-query ``` ::: #### Package Installation Install Scaffold UI hooks using your preferred package manager: :::code-group ```bash [npm] npm install @scaffold-ui/hooks ``` ```bash [pnpm] pnpm add @scaffold-ui/hooks ``` ```bash [yarn] yarn add @scaffold-ui/hooks ``` ::: #### Create wagmi config and setup Tanstack query [https://wagmi.sh/react/getting-started#create-config](https://wagmi.sh/react/getting-started#create-config) import React from "react"; import { useAddress } from "@scaffold-ui/hooks"; import { DocsProvider } from "../../components/DocsProvider"; ## useAddress Hook The `useAddress` hook provides utilities for working with Ethereum addresses, including ENS name resolution, ENS avatar fetching, checksum formatting, shortened display formats, block explorer links, and blockie image generation. ### Import ```tsx import { useAddress } from "@scaffold-ui/hooks"; ``` ### Usage ```tsx const { checkSumAddress, ens, ensAvatar, isEnsNameLoading, blockExplorerAddressLink, isValidAddress, shortAddress, blockieUrl, } = useAddress({ address: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045", }); ``` ### Parameters | Parameter | Type | Default | Description | | --------- | ---------------------- | --------- | ---------------------------------------------------- | | `address` | `Address` *(optional)* | - | The Ethereum address to process and fetch data for. | | `chain` | `Chain` *(optional)* | `mainnet` | The blockchain network for ENS resolution and links. | ### Return Values | Property | Type | Description | | -------------------------- | ----------------------------- | ----------------------------------------------------------- | | `checkSumAddress` | `Address \| undefined` | The checksummed version of the provided address. | | `ens` | `string \| null \| undefined` | The resolved ENS name for the address (if available). | | `ensAvatar` | `string \| null \| undefined` | The ENS avatar URL (if available). | | `isEnsNameLoading` | `boolean` | Loading state for ENS name resolution. | | `blockExplorerAddressLink` | `string` | Full URL to view the address on the chain's block explorer. | | `isValidAddress` | `boolean` | Whether the provided address is a valid Ethereum address. | | `shortAddress` | `string \| undefined` | Shortened address format (first 6 and last 4 characters). | | `blockieUrl` | `string \| undefined` | Data URL for a deterministic blockie image of the address. | :::info `ens` and `ensAvatar` fields are tri-state: `undefined` (not requested, still resolving, or error), `null` (no record), or a value (resolved). ::: ### Live Examples #### Basic Usage export function UseAddressBasicExample() { const address = "0xd8da6bf26964af9d7eed9e03e53415d37aa96045"; const { checkSumAddress, shortAddress, blockExplorerAddressLink } = useAddress({ address }); return (

Short: {shortAddress}

Full with blockexplorer link:{" "} {checkSumAddress}

); } ```tsx import React from "react"; import { useAddress } from "@scaffold-ui/hooks"; function AddressDisplay() { const address = "0xd8da6bf26964af9d7eed9e03e53415d37aa96045"; const { checkSumAddress, shortAddress, blockExplorerAddressLink } = useAddress({ address }); return (

Short: {shortAddress}

Full with blockexplorer link:{" "} {checkSumAddress}

); } ``` #### With ENS and Avatar export function UseAddressWithAvatarExample() { const address = "0xd8da6bf26964af9d7eed9e03e53415d37aa96045"; const { ens, ensAvatar, blockieUrl, shortAddress } = useAddress({ address }); return (
Avatar {ens ?? shortAddress}
); } ```tsx import React from "react"; import { useAddress } from "@scaffold-ui/hooks"; function AddressWithENS() { const address = "0xd8da6bf26964af9d7eed9e03e53415d37aa96045"; const { ens, ensAvatar, blockieUrl, shortAddress } = useAddress({ address }); return (
Avatar {ens ?? shortAddress}
); } ``` #### Loading State export function UseAddressLoadingExample() { const address = "0xd8da6bf26964af9d7eed9e03e53415d37aa96045"; const { ens, shortAddress, isEnsNameLoading } = useAddress({ address }); return
{isEnsNameLoading ? Loading ENS name... : {ens ?? shortAddress}}
; } ```tsx import React from "react"; import { useAddress } from "@scaffold-ui/hooks"; function AddressWithLoading() { const address = "0xd8da6bf26964af9d7eed9e03e53415d37aa96045"; const { ens, shortAddress, isEnsNameLoading } = useAddress({ address }); return
{isEnsNameLoading ? Loading ENS name... : {ens ?? shortAddress}}
; } ``` import React from "react"; import { DocsProvider } from "../../components/DocsProvider"; import { UseAddressInputBasicExample, UseAddressInputWithResolutionExample, UseAddressInputErrorExample, } from "../../components/UseAddressInputExamples"; ## useAddressInput Hook The `useAddressInput` hook handles address input with debouncing, ENS name resolution (both directions), and ENS avatar fetching. It's designed for building custom address input components with real-time ENS lookups. ### Import ```tsx import { useAddressInput } from "@scaffold-ui/hooks"; ``` ### Usage ```tsx const { ensAddress, ensName, ensAvatar, isEnsAddressLoading, isEnsNameLoading, isEnsAvatarLoading, settledValue, debouncedValue, } = useAddressInput({ value: inputValue, debounceDelay: 500, }); ``` ### Parameters | Parameter | Type | Default | Description | | --------------- | --------------------- | ------- | --------------------------------------------------------- | | `value` | `string` | - | The input value (can be an Ethereum address or ENS name). | | `debounceDelay` | `number` *(optional)* | `500` | Debounce delay in milliseconds for ENS resolution. | ### Return Values | Property | Type | Description | | --------------------- | ------------------------------ | --------------------------------------------------------------------- | | `ensAddress` | `Address \| null \| undefined` | The resolved Ethereum address from an ENS name input. | | `isEnsAddressLoading` | `boolean` | Loading state for ENS address resolution. | | `isEnsAddressError` | `boolean` | Error state for ENS address resolution. | | `isEnsAddressSuccess` | `boolean` | Success state for ENS address resolution. | | `ensName` | `string \| null \| undefined` | The resolved ENS name from an address input. | | `isEnsNameLoading` | `boolean` | Loading state for ENS name resolution. | | `isEnsNameError` | `boolean` | Error state for ENS name resolution. | | `isEnsNameSuccess` | `boolean` | Success state for ENS name resolution. | | `ensAvatar` | `string \| null \| undefined` | The ENS avatar URL for the resolved ENS name. | | `isEnsAvatarLoading` | `boolean` | Loading state for ENS avatar fetching. | | `isEnsAvatarError` | `boolean` | Error state for ENS avatar fetching. | | `isEnsAvatarSuccess` | `boolean` | Success state for ENS avatar fetching. | | `settledValue` | `string \| undefined` | The debounced and validated input value (undefined while debouncing). | | `debouncedValue` | `string` | The debounced input value. | :::info `ensAddress`, `ensName`, and `ensAvatar` fields are tri-state: `undefined` (not requested, still resolving, or error), `null` (no record), or a value (resolved). ::: ### Live Examples #### Basic Usage Simple ENS name to address resolution. ```tsx import React, { useState } from "react"; import { useAddressInput } from "@scaffold-ui/hooks"; function BasicAddressInput() { const [value, setValue] = useState(""); const { ensAddress, isEnsAddressLoading } = useAddressInput({ value }); return (
setValue(e.target.value)} placeholder="Enter ENS name (e.g., vitalik.eth)" /> {isEnsAddressLoading &&

Resolving...

} {ensAddress && (

Address: {ensAddress}

)}
); } ``` #### Bidirectional Resolution Resolves both ENS names to addresses and addresses to ENS names, with avatar display. ```tsx import React, { useState } from "react"; import { useAddressInput } from "@scaffold-ui/hooks"; function BidirectionalResolution() { const [value, setValue] = useState(""); const { ensAddress, ensName, ensAvatar, isEnsAddressLoading, isEnsNameLoading } = useAddressInput({ value }); return (
setValue(e.target.value)} placeholder="Try: vitalik.eth or 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" disabled={isEnsAddressLoading || isEnsNameLoading} /> {(isEnsAddressLoading || isEnsNameLoading) &&

Resolving...

} {ensAddress && (

Resolved Address: {ensAddress}

)} {ensName && (
{ensAvatar && ( {ensName} )} Resolved ENS: {ensName}
)}
); } ``` #### With Error Handling ```tsx import React, { useState } from "react"; import { useAddressInput } from "@scaffold-ui/hooks"; function AddressInputWithErrors() { const [value, setValue] = useState(""); const { ensAddress, isEnsAddressLoading, isEnsAddressError, isEnsAddressSuccess } = useAddressInput({ value }); const showError = !isEnsAddressLoading && value && (isEnsAddressError || (isEnsAddressSuccess && ensAddress === null)); return (
setValue(e.target.value)} placeholder="Enter ENS name (try: invalidensname.eth)" /> {isEnsAddressLoading &&

Resolving...

} {showError &&

✗ Could not resolve ENS name

} {ensAddress &&

✓ Resolved: {ensAddress}

}
); } ``` import React, { useState } from "react"; import { useBalance } from "@scaffold-ui/hooks"; import { DocsProvider } from "../../components/DocsProvider"; import { mainnet } from "viem/chains"; ## useBalance Hook The `useBalance` hook fetches and watches an address balance on a given chain, pairing live USD conversion. ### Import ```tsx import { useBalance } from "@scaffold-ui/hooks"; ``` ### Usage ```tsx const { displayUsdMode, toggleDisplayUsdMode, formattedBalance, balanceInUsd, balance, isBalanceLoading, isBalanceError, isNativeCurrencyPriceLoading, isNativeCurrencyPriceError, isLoading, isError, } = useBalance({ address: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045", chain: mainnet, defaultUsdMode: true, }); ``` ### Parameters | Parameter | Type | Default | Description | | ---------------- | ---------------------- | ------- | --------------------------------------------------------------------------- | | `address` | `Address` *(optional)* | - | The address to watch. When omitted, the hook returns zeroed balance values. | | `chain` | `Chain` | - | The **viem** chain configuration used for fetching balances and USD prices. | | `defaultUsdMode` | `boolean` *(optional)* | `false` | If `true` and price data is available, show USD values by default. | ### Return Values | Property | Type | Description | | ------------------------------ | ----------------------------------- | --------------------------------------------------------------------------- | | `displayUsdMode` | `boolean` | Whether the display is currently set to USD. | | `toggleDisplayUsdMode` | `() => void` | Toggle between native and USD display (only active when price data exists). | | `formattedBalance` | `number` | Native balance normalized with `formatEther`. | | `balanceInUsd` | `number` | USD value derived from `formattedBalance * nativeCurrencyPrice`. | | `balance` | `GetBalanceReturnType \| undefined` | Raw wagmi balance payload containing value, decimals, and symbol. | | `isBalanceLoading` | `boolean` | Loading state for the balance fetch. | | `isBalanceError` | `boolean` | Error state for the balance fetch. | | `isNativeCurrencyPriceLoading` | `boolean` | Loading state for fetching the native currency price. | | `isNativeCurrencyPriceError` | `boolean` | Error state for fetching the native currency price. | | `isLoading` | `boolean` | Combined loading state: balance data or price is still loading. | | `isError` | `boolean` | Combined error state: balance data or price failed to load. | :::info USD display is enabled only after the native currency price has been fetched. If the price is not available, toggling to USD is disabled and native balance is shown. ::: ### Live Examples #### Basic Usage Display a live balance with an inline USD toggle. export function UseBalanceBasicExample() { const address = "0xd8da6bf26964af9d7eed9e03e53415d37aa96045"; const { formattedBalance, balanceInUsd, displayUsdMode, toggleDisplayUsdMode, isLoading, } = useBalance({ address, chain: mainnet, }); return (

Balance: {displayUsdMode ? `$${balanceInUsd.toLocaleString()}` : `${formattedBalance.toLocaleString()} ETH`}

); }
```tsx import React from "react"; import { useBalance } from "@scaffold-ui/hooks"; import { mainnet } from "viem/chains"; function BalanceWithToggle() { const address = "0xd8da6bf26964af9d7eed9e03e53415d37aa96045"; const { formattedBalance, balanceInUsd, displayUsdMode, toggleDisplayUsdMode, isLoading, } = useBalance({ address, chain: mainnet, }); return (

Balance: {displayUsdMode ? `$${balanceInUsd.toLocaleString()}` : `${formattedBalance.toLocaleString()} ETH`}

); } ``` #### Loading and Error States Handle asynchronous fetch states while keeping the toggle experience consistent. export function UseBalanceLoadingErrorExample() { const [isValidAddress, setIsValidAddress] = useState(true); const validAddress = "0xd8da6bf26964af9d7eed9e03e53415d37aa96045"; const brokenAddress = "0x"; const { formattedBalance, balanceInUsd, displayUsdMode, toggleDisplayUsdMode, isLoading, isError, } = useBalance({ address: isValidAddress ? validAddress : brokenAddress, chain: mainnet, defaultUsdMode: true, }); if (isLoading) return

Fetching balance…

; if (isError) return (

Could not fetch balance

); return (

Balance: {displayUsdMode ? `$${balanceInUsd.toLocaleString()}` : `${formattedBalance.toLocaleString()} ETH`}

); } ```tsx import React, { useState } from "react"; import { useBalance } from "@scaffold-ui/hooks"; import { mainnet } from "viem/chains"; function BalanceWithLoadingStates() { const [isValidAddress, setIsValidAddress] = useState(true); const validAddress = "0xd8da6bf26964af9d7eed9e03e53415d37aa96045"; const brokenAddress = "0x"; const { formattedBalance, balanceInUsd, displayUsdMode, toggleDisplayUsdMode, isLoading, isError, } = useBalance({ address: isValidAddress ? validAddress : brokenAddress, chain: mainnet, defaultUsdMode: true, }); if (isLoading) return

Fetching balance…

; if (isError) return (

Could not fetch balance

); return (

Balance: {displayUsdMode ? `$${balanceInUsd.toLocaleString()}` : `${formattedBalance.toLocaleString()} ETH`}

); } ``` import React, { useState } from "react"; import { useEtherInput } from "@scaffold-ui/hooks"; import { DocsProvider } from "../../components/DocsProvider"; ## useEtherInput Hook The `useEtherInput` hook converts between ETH and USD for a given input and display mode. It returns both values, the current native currency price, and loading/error flags so you can build responsive inputs. ### Import ```tsx import { useEtherInput } from "@scaffold-ui/hooks"; ``` ### Usage ```tsx const { valueInEth, valueInUsd, nativeCurrencyPrice, isNativeCurrencyPriceLoading, isNativeCurrencyPriceError, } = useEtherInput({ value, usdMode }); ``` ### Parameters | Parameter | Type | Default | Description | | --------- | --------- | ------- | --------------------------------------------------------------------------------------- | | `value` | `string` | - | The current input value. Interpreted as ETH when `usdMode` is `false`, USD when `true`. | | `usdMode` | `boolean` | - | If `true`, `value` is USD; if `false`, `value` is ETH. | ### Return Values | Property | Type | Description | | ------------------------------ | --------- | ------------------------------------------------------------------------------- | | `valueInEth` | `string` | The input value expressed in ETH. Empty string while conversion is unavailable. | | `valueInUsd` | `string` | The input value expressed in USD. Empty string while conversion is unavailable. | | `nativeCurrencyPrice` | `number` | The fetched native currency price in USD. `0` when not yet available. | | `isNativeCurrencyPriceLoading` | `boolean` | Loading state for fetching the native currency price. | | `isNativeCurrencyPriceError` | `boolean` | Error state for fetching the native currency price. | :::info This hook fetches price data using mainnet under the hood. When the price is not yet available, conversion outputs may be empty strings—keep showing the raw input in your UI. ::: ### Live Examples #### Basic Usage export function UseEtherInputBasicExample() { const [value, setValue] = useState(""); const [usdMode, setUsdMode] = useState(false); const { valueInEth, valueInUsd, isNativeCurrencyPriceLoading } = useEtherInput({ value, usdMode }); return (
setValue(e.target.value)} placeholder={usdMode ? "Enter amount in USD" : "Enter amount in ETH"} />
{isNativeCurrencyPriceLoading ? (

Fetching price...

) : (

ETH: {valueInEth || "–"} | USD: {valueInUsd || "–"}

)}
); } ```tsx import React, { useState } from "react"; import { useEtherInput } from "@scaffold-ui/hooks"; function EtherUsdConverter() { const [value, setValue] = useState(""); const [usdMode, setUsdMode] = useState(false); const { valueInEth, valueInUsd, isNativeCurrencyPriceLoading } = useEtherInput({ value, usdMode }); return (
setValue(e.target.value)} placeholder={usdMode ? "Enter amount in USD" : "Enter amount in ETH"} />
{isNativeCurrencyPriceLoading ? (

Fetching price...

) : (

ETH: {valueInEth || "–"} | USD: {valueInUsd || "–"}

)}
); } ``` #### With Error Handling export function UseEtherInputErrorHint() { const [value, setValue] = useState("1000"); const [usdMode] = useState(true); const { valueInEth, valueInUsd, isNativeCurrencyPriceError } = useEtherInput({ value, usdMode }); if (isNativeCurrencyPriceError) { return

Price feed unavailable. Showing entered value: ${valueInUsd}

; } return

ETH: {valueInEth || "–"} | USD: {valueInUsd || "–"}

; } ```tsx import React, { useState } from "react"; import { useEtherInput } from "@scaffold-ui/hooks"; function ConverterWithErrors() { const [value, setValue] = useState("1000"); const [usdMode] = useState(true); const { valueInEth, valueInUsd, isNativeCurrencyPriceError } = useEtherInput({ value, usdMode }); if (isNativeCurrencyPriceError) { return

Price feed unavailable. Showing entered value: ${valueInUsd}

; } return

ETH: {valueInEth || "–"} | USD: {valueInUsd || "–"}

; } ```