Skip to content
wyllet
  • Docs
  • Features
  • Playground
  • Blog
  • Docs
  • Features
  • Playground
  • Blog
  • Compare
  • Changelog
GitHub @wylletdevnpm Support
esc
  • IntroductionWhat Wyllet is, what it includes, and how it fits into a wagmi + viem dApp.
  • InstallationInstall Wyllet and its peer dependencies, and enable WalletConnect.
  • Quick startAdd a working connect button to a React dApp in a few minutes.
  • Next.jsUse Wyllet with the Next.js App Router, server components and SSR.
  • Build with AI assistantsGive Cursor, Claude Code, Copilot or ChatGPT the Wyllet docs and the rules for a correct integration.
  • ConfigurationCreate a wagmi config with getDefaultConfig: app info, chains, transports and wallets.
  • WylletProviderEvery WylletProvider prop: theme, appearance, tokens, auth, messages and callbacks.
  • WylletButtonThe Island button, its display options, and building your own trigger with useWylletButton.
Overview

Getting started

  • Introduction
  • Installation
  • Quick start
  • Next.js
  • Build with AI assistants

Core concepts

  • Configuration
  • WylletProvider
  • WylletButton
  • Presentations

Customization

  • Theming
  • Class names
  • Translations

Wallets

  • Wallets
  • All wallets
  • WalletConnect

Chains and tokens

  • Chains
  • Tokens

Features

  • Account panel
  • Activity and transactions
  • Toasts
  • Sign-In With Ethereum
  • ConnectGate

Reference

  • Hooks
  • Components
  • Utilities and types

Guides

  • Security
  • Migrate from RainbowKit
  • FAQ
wyllet

The open-source wallet connector for React dApps. Built on wagmi and viem.

MIT licensed. v1.1.0 on npm with provenance.

Product

  • Features
  • Compare
  • Playground
  • Changelog
  • Blog

Docs

  • Quick start
  • Next.js
  • Build with AI
  • Theming
  • Migrate from RainbowKit

Community

  • GitHub
  • X @wylletdev
  • npm
  • Releases
  • Report an issue

Support

  • support@wyllet.dev
  • FAQ
  • Security
  • Report a vulnerability
  • MIT License

For AI agents

  • llms.txt
  • llms-full.txt
  • RSS feed
  • Sitemap

Wallet, network and token names and logos are trademarks of their respective owners and are used only to identify them.

Docs/Reference

Hooks

API reference for every Wyllet hook: useWyllet, useWylletButton, useWylletToast, useWylletActivity, useWylletAuth and more.

View .mdReport a problem

Wyllet exports nine hooks. All of them except useCopyToClipboard read Wyllet's context, so they must be called from a component rendered inside WylletProvider (which itself sits inside wagmi's WagmiProvider and react-query's QueryClientProvider). Calling one outside the provider throws an error that names WylletProvider.

import {
  useCopyToClipboard,
  useWalletOptions,
  useWyllet,
  useWylletActivity,
  useWylletAuth,
  useWylletButton,
  useWylletChains,
  useWylletToast,
  useWylletTokens,
} from 'wyllet'

useWyllet

Controls the Wyllet panel from anywhere in your app.

function useWyllet(): {
  open(view?: PanelView, options?: OpenOptions): void
  close(): void
  openConnect(options?: OpenOptions): void
  openAccount(options?: OpenOptions): void
  openTab(tab: AccountTab, options?: OpenOptions): void
  view: PanelView | null
  isConnected: boolean
  address: Address | undefined
  chainId: number | undefined
  authStatus: AuthStatus | undefined
}
FieldTypeDescription
open(view?, options?) => voidOpens a view. Without a view it opens 'account' when connected and 'connect' otherwise.
close() => voidCloses the panel.
openConnect(options?) => voidOpens the connect view.
openAccount(options?) => voidOpens the account panel.
openTab(tab, options?) => voidOpens the account panel on a tab: 'tokens', 'activity' or 'networks'.
viewPanelView | nullThe open view ('connect' or 'account'), or null when closed.
isConnectedbooleantrue when wagmi reports a connected account.
addressAddress | undefinedThe connected address.
chainIdnumber | undefinedThe connected chain id.
authStatusAuthStatus | undefinedSign-in status for the connected account, or undefined when no auth adapter is set.

OpenOptions has two optional fields: anchor (an Element the popover presentation anchors to) and tab (an AccountTab).

function Toolbar() {
  const { openConnect, openTab, isConnected } = useWyllet()
  return isConnected ? (
    <button onClick={(e) => openTab('activity', { anchor: e.currentTarget })}>Activity</button>
  ) : (
    <button onClick={() => openConnect()}>Connect</button>
  )
}

useWylletButton

Headless state for building your own trigger. It powers WylletButton. See WylletButton for a full walkthrough.

function useWylletButton(): WylletButtonState
FieldTypeDescription
mountedbooleanfalse during server rendering and the first client render. Render a placeholder until it is true to avoid hydration mismatches.
status'disconnected' | 'connecting' | 'reconnecting' | 'connected'wagmi's connection status.
accountobject | undefinedPresent when connected: address, displayName (ENS name or shortened address), ensName, and balance (formatted, symbol, value, decimals).
chainobject | undefinedPresent when connected: id, name, and unsupported (true when the wallet is on a chain your config does not include).
authStatusAuthStatus | undefinedundefined when no auth adapter is configured.
open(anchor?: Element | null) => voidOpens the connect view when disconnected or not yet signed in, otherwise the account panel.
openConnect(anchor?: Element | null) => voidOpens the connect view.
openAccount(anchor?: Element | null, tab?: AccountTab) => voidOpens the account panel, optionally on a tab.

Pass the clicked element as anchor so the popover presentation can position itself next to it.

function MyButton() {
  const { mounted, account, chain, open } = useWylletButton()
  if (!mounted) return <button disabled>Connect</button>
  return (
    <button onClick={(e) => open(e.currentTarget)}>
      {account ? `${account.displayName} on ${chain?.name}` : 'Connect'}
    </button>
  )
}

useWylletToast

Returns the toast API. See Toasts.

function useWylletToast(): ToastApi
MemberTypeDescription
call(options: ToastOptions) => stringShows a toast and returns its id. Pass an existing id to update that toast in place.
success(title, options?) => stringShows a success toast.
error(title, options?) => stringShows an error toast.
loading(title, options?) => stringShows a loading toast. Loading toasts never auto-dismiss.
update(id: string, options: Partial<ToastOptions>) => voidUpdates an existing toast. Does nothing if the id is unknown.
dismiss(id?: string) => voidDismisses one toast, or all of them when called without an id.
promise(promise, messages) => Promise<T>Shows a loading toast that becomes success or error when the promise settles. Returns the original result and rethrows on failure.

ToastOptions fields: title (ReactNode), description, status ('info' | 'success' | 'error' | 'loading'), duration in milliseconds (Infinity keeps the toast open), action (label plus href or onClick) and id. Without a duration, error toasts stay for 7 seconds and other toasts for 4.5 seconds.

const toast = useWylletToast()
 
toast.success('Saved')
 
await toast.promise(bridge(), {
  loading: 'Bridging…',
  success: 'Bridged',
  error: (e) => `Bridge failed: ${String(e)}`,
})

useWylletActivity

The connected account's activity timeline, plus transaction tracking. See Activity and transactions.

function useWylletActivity(): {
  activity: ActivityItem[]
  addTransaction(tx: {
    hash: Hash
    description?: string
    chainId?: number
    account?: Address
    toast?: boolean
  }): boolean
  log(entry: {
    title: string
    description?: string
    status?: ActivityStatus
    account?: Address
  }): boolean
  clearActivity(): void
}
FieldTypeDescription
activityActivityItem[]Entries for the connected account, newest first. Empty when disconnected.
addTransaction(tx) => booleanAdds a pending transaction, watches for its receipt and shows pending and confirmed toasts (set toast: false to skip them). Defaults to the connected account and chain. Returns false if no account or chain is known.
log(entry) => booleanAdds a custom entry. status defaults to 'info'. Returns false if no account is known.
clearActivity() => voidClears the connected account's entries.

Activity is stored in localStorage (up to 50 entries per account). Transactions still pending when the page reloads are watched again if they are less than 24 hours old. A transaction that is not mined within 30 minutes stays pending rather than being marked as failed.

const { writeContractAsync } = useWriteContract()
const { addTransaction, log } = useWylletActivity()
 
const hash = await writeContractAsync({ /* ... */ })
addTransaction({ hash, description: 'Mint 1 NFT' })
 
log({ title: 'Staked 10 ETH', status: 'success' })

useWylletAuth

Sign-In With Ethereum state. Requires the auth prop on WylletProvider. See Sign-In With Ethereum.

function useWylletAuth(): {
  enabled: boolean
  status: AuthStatus
  signIn(options?: OpenOptions): void
  signOut(): Promise<void>
}
FieldTypeDescription
enabledbooleantrue when an auth adapter is configured.
status'loading' | 'unauthenticated' | 'authenticated'Per connected account: a session for a different address reads as 'unauthenticated'.
signIn(options?) => voidOpens the panel at the sign-in step, connecting first if needed.
signOut() => Promise<void>Clears the local session and calls your adapter's signOut. Errors from the adapter are swallowed.
function Session() {
  const { status, signIn, signOut } = useWylletAuth()
  if (status === 'loading') return null
  return status === 'authenticated' ? (
    <button onClick={() => signOut()}>Sign out</button>
  ) : (
    <button onClick={(e) => signIn({ anchor: e.currentTarget })}>Sign in</button>
  )
}

useWylletTokens

The token list for a chain: your configured tokens, plus tokens the user imported when allowTokenImport is on. See Tokens.

function useWylletTokens(chainId?: number): {
  tokens: ListedToken[]
  importToken(token: Token, chainId?: number): void
  removeToken(address: string, chainId?: number): void
  canImport: boolean
}
FieldTypeDescription
tokensListedToken[]Configured tokens in list order, followed by imported ones. Imported tokens have custom: true. Empty when no chain id is known.
importToken(token, chainId?) => voidSaves a token for the user in this browser. Defaults to the hook's chain.
removeToken(address, chainId?) => voidRemoves an imported token. Address matching is case-insensitive.
canImportbooleanThe provider's allowTokenImport value.

chainId defaults to the connected chain. Imported tokens are only included in tokens when allowTokenImport is true.

function TokenList() {
  const { tokens } = useWylletTokens(8453)
  return (
    <ul>
      {tokens.map((t) => (
        <li key={t.address}>{t.symbol}</li>
      ))}
    </ul>
  )
}

useWylletChains

Your configured chains, ordered by the provider's chainOrder. Chains not listed in chainOrder follow in config order. See Chains.

function useWylletChains(): { chains: Chain[] }
const { chains } = useWylletChains()
// With chainOrder={[8453]}: Base first, then the rest of your config

chainOrder only affects display. The default chain is still the first chain in your wagmi config.

useCopyToClipboard

Copies text and exposes a copied flag that resets after a delay. It does not need WylletProvider.

function useCopyToClipboard(resetMs?: number): {
  copied: boolean
  copy(text: string): Promise<boolean>
}
FieldTypeDescription
copiedbooleantrue for resetMs milliseconds (default 1600) after a successful copy.
copy(text: string) => Promise<boolean>Writes to navigator.clipboard. Resolves false if the clipboard is unavailable or the write fails.
function CopyAddress({ address }: { address: string }) {
  const { copied, copy } = useCopyToClipboard()
  return <button onClick={() => copy(address)}>{copied ? 'Copied' : 'Copy'}</button>
}

useWalletOptions

The wallet list Wyllet's connect view uses: your configured wallets merged with what is actually available in the browser. Use it to build a fully custom wallet picker.

function useWalletOptions(): {
  groups: WalletGroup[]
  all: WalletOption[]
  walletConnectConnector?: Connector
}
FieldTypeDescription
groupsWalletGroup[]Non-empty groups in order: 'installed' (detected or recently used), 'popular', and 'more' (wallets with featured: false).
allWalletOption[]Every option, in the same order as the groups.
walletConnectConnectorConnector | undefinedThe WalletConnect connector, if your config has one.

Each WalletOption has:

FieldTypeDescription
walletWalletThe wallet. Installed extensions use the icon they announce.
connectorConnector | undefinedThe connector used for a direct connection.
installedbooleanAn EIP-6963 provider matching the wallet's rdns was announced.
recentbooleanThe user connected with this wallet recently.
action'connect' | 'walletConnect' | 'get'What picking it does: connect directly, start WalletConnect, or show install links.

Installed EIP-6963 wallets you did not list still appear in the 'installed' group. Wallets that can neither connect nor use WalletConnect, and have no downloadUrls, are left out.

import { useConnect } from 'wagmi'
 
function Picker() {
  const { all } = useWalletOptions()
  const { connect } = useConnect()
  return all
    .filter((o) => o.action === 'connect' && o.connector)
    .map((o) => (
      <button key={o.wallet.id} onClick={() => connect({ connector: o.connector! })}>
        {o.wallet.name}
      </button>
    ))
}
PreviousConnectGateNextComponents

On this page

  • useWyllet
  • useWylletButton
  • useWylletToast
  • useWylletActivity
  • useWylletAuth
  • useWylletTokens
  • useWylletChains
  • useCopyToClipboard
  • useWalletOptions