> ## Documentation Index
> Fetch the complete documentation index at: https://dynamic-docs-feat-sidebar-revamp.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Headless Wallet Management

This guide covers how to implement the wallet aspect of the Dynamic Widget UI Component but using only our SDK hooks and your own UI implementation.

## Prerequisites

Like with all this series of headless guides, "headless" is defined a way to use the Dynamic SDK without the need for Dynamic UI components (i.e. DynamicWidget, DynamicUserProfile).

You still need to add the SDK and set up the Dynamic Context Provider (complete [the quickstart](/quickstart) if you haven't done so already, or refer to [an example app](/example-apps))

## Signup/Login

### Fetch available wallets

You can find the list of available wallets in the `walletOptions` prop returned by the [useWalletOptions hook](/react-sdk/hooks/wallets/usewalletoptions).

<Tip>
  When browsing wallets in the Dynamic Widget, you might see labels beside them like "Last Used", "Multichain" or "Recommended".

  Last used comes from the "dynamic\_last\_used\_wallet" value in localstorage.
  "Multichain" comes from the `chainGroup` node in each wallet (Remember to also add [the WalletConnectors](/chains/enabling-chains#enabling-a-chain-network) for each chain).
  "Recommended" from [the Recommended Wallets feature](/wallets/advanced-wallets/recommend-wallets).
</Tip>

### Display a wallet icon

Use the `@dynamic-labs/wallet-book` library to display a wallet icon using the exported `WalletIcon` component. This component takes a `walletKey` prop, which is the key of the wallet you want to display.

```tsx
import { WalletIcon } from '@dynamic-labs/wallet-book'

const WalletIconComponent = () => {
  return <WalletIcon walletKey="metamask" />
}
```

### Connect to a wallet

[useWalletOptions](/react-sdk/hooks/wallets/usewalletoptions) allows you to prompt the user to connect using a specific wallet (by passing in the key).

```
import { useWalletOptions } from "@dynamic-labs/sdk-react-core";

// component setup etc.

const { selectWalletOption } = useWalletOptions();

const connectWithWallet = async (walletKey) => {
  return await selectWalletOption(walletKey)
}
```

### Onramp

#### Show onramp button and open flow

How: Regular button attached to useOnramp hook

Hook/Component: [useOnramp](/react-sdk/hooks/funding/useonramp)

Notes: Ensure Banxa is enabled in the Dynamic dashboard

```jsx
import { useOnramp } from '@dynamic-labs/sdk-react-core'

const Onramp = () => {
  const { enabled, open } = useOnramp()

  return (
    <div>
      {enabled && (
        <button className="onramp-button" onClick={open}>
          Onramp
        </button>
      )}
    </div>
  )
}
```

### Networks

#### Display current and available networks

How: Use evmNetworks and getNetwork to fetch, use supportsNetworkSwitching and switchNetwork to switch

Hook/Component: [useDynamicContext](/react-sdk/hooks/usedynamiccontext) & [getNetwork](/react-sdk/utilities/getnetwork)

Notes: This example is for Evm networks only

```jsx
import { useDynamicContext, getNetwork } from '@dynamic-labs/sdk-react-core'

const CustomNetworkPicker = () => {
  const [currentNetwork, setCurrentNetwork] = useState(null)
  const { primaryWallet } = useDynamicContext()

  const handleNetworkChange = async (event) => {
    const chainId = parseInt(event.target.value)

    if (primaryWallet?.connector?.supportsNetworkSwitching()) {
      try {
        return await primaryWallet?.connector?.switchNetwork({
          networkChainId: chainId,
        })
      } catch (error) {
        console.error('Error switching network', error)
      }
    }
  }

  useEffect(() => {
    if (!currentNetwork)
      getNetwork(primaryWallet?.connector).then((network) => {
        setCurrentNetwork(network)
      })
  }, [primaryWallet])

  return (
    <>
      {currentNetwork && (
        <Select defaultValue={currentNetwork} onChange={handleNetworkChange}>
          {primaryWallet?.connector?.evmNetworks?.map((network) => (
            <option key={network.chainId} value={network.chainId}>
              {network.name}
            </option>
          ))}
        </Select>
      )}
    </>
  )
}
```

### Primary Wallet

Primary wallet is the wallet that is defined as the active one of all your connected wallets. All interactions, such as signing or creating transactions, will be made with this wallet. In addition, when leveraging our multiasset functionality, this is the wallet that will be display all available tokens.

#### Display primary wallet address

How: Fetch the primary wallet info from context

Hook/Component: [useDynamicContext](/react-sdk/hooks/usedynamiccontext)

Notes: There can be a moment after logging in when it's not populated yet

```jsx
import { useDynamicContext } from '@dynamic-labs/sdk-react-core'

const { primaryWallet } = useDynamicContext()

const copyWalletAddress = () => {
  navigator.clipboard.writeText(primaryWallet?.address)
}

return (
  <button onClick={() => copyWalletAddress()}>
    <p>...{primaryWallet?.address?.slice(-6)}</p>
  </button>
)
```

#### Display primary wallet icon

How: Utilize the Walletbook library

Hook/Component: WalletIcon (not publicly documented yet)

Notes: Requires the primaryWallet.connector object.

```jsx
import { primaryWallet } from '@dynamic-labs/sdk-react-core'
import { WalletIcon } from '@dynamic-labs/wallet-book'

const WalletIconWrapped = ({ connector }) => {
  return (
    <div className="wallet-icon-container">
      <WalletIcon walletKey={primaryWallet?.connector?.key} />
    </div>
  )
}
```

#### Show balance of primary wallet

How: getBalance method from useDynamicContext wallet connector

Hook/Component: [https://docs.dynamic.xyz/react-sdk/hooks/usedynamiccontext](https://docs.dynamic.xyz/react-sdk/hooks/usedynamiccontext)

Notes: None

```jsx
import { useDynamicContext } from '@dynamic-labs/sdk-react-core'

const { primaryWallet } = useDynamicContext()

const [balance, setBalance] = useState(null)

useEffect(() => {
  const fetchBalance = async () => {
    if (primaryWallet) {
      const value = await primaryWallet.getBalance()
      setBalance(value)
    }
  }
  fetchBalance()
}, [primaryWallet])

return <p>{balance}</p>
```

#### Show all tokens and balances

How: Mapping return from usetokenbalances hook

Hook/Component: [https://docs.dynamic.xyz/react-sdk/hooks/usetokenbalances](https://docs.dynamic.xyz/react-sdk/hooks/usetokenbalances)

Notes: Multi-asset is only supported on the following networks - Ethereum, Optimism, Polygon, Arbitrum, and Base.

```jsx
import { useTokenBalances } from '@dynamic-labs/sdk-react-core'

const TokenBalances = () => {
  const tokenBalances = useTokenBalances()

  return (
    <div>
      {tokenBalances.map((token) => (
        <div key={token.address}>
          <p>{token.symbol}</p>
          <p>{token.balance}</p>
        </div>
      ))}
    </div>
  )
}
```

#### Detect Wallet Locking

The wallet object has a field called `connected` which indicates whether the wallet is locked or not, and you can use this to trigger your own workflow to warn the user.

### Multi-Wallet

#### Show all linked wallets and allow unlinking

How: Mapping return from useUserWallets hook and handleUnlinkWallet from useDynamicContext

Hook/Component: [https://docs.dynamic.xyz/react-sdk/hooks/useuserwallets](https://docs.dynamic.xyz/react-sdk/hooks/useuserwallets) & [https://docs.dynamic.xyz/react-sdk/hooks/usedynamiccontext](https://docs.dynamic.xyz/react-sdk/hooks/usedynamiccontext)

Notes: Doesn't yet show if a wallet is the primary wallet. Unlinking is also handled here.

```jsx
import { useDynamicContext, useUserWallets } from '@dynamic-labs/sdk-react-core'

import { Tooltip } from 'react-tooltip'

const LinkedWallets = () => {
  const { handleUnlinkWallet } = useDynamicContext()

  const userWallets = useUserWallets()

  return (
    <>
      {userWallets.length > 0 && (
        <div className="profile-wallets-container">
          <h2>Connected Wallets</h2>
          {userWallets.length < 2 && <Tooltip id="unlink-tooltip" />}
          <div className="profile-wallets-inner-container">
            {userWallets.map((wallet) => (
              <Flex key={wallet.address}>
                <p>{wallet.address}</p>
                <Spacer />
                <a
                  data-tooltip-id="unlink-tooltip"
                  data-tooltip-content="Can't unlink your only wallet!"
                >
                  <Button
                    size="xs"
                    onClick={() => handleUnlinkWallet(wallet.id)}
                    disabled={userWallets.length < 2}
                  >
                    Unlink
                  </Button>
                </a>
              </Flex>
            ))}
          </div>
        </div>
      )}
    </>
  )
}
```

#### Detect which wallet is primary

How: You can grab it directly from useDynamicContext

Hook/Component: [useDynamicContext](/react-sdk/hooks/usedynamiccontext)

```jsx
import { useDynamicContext, useUserWallets } from '@dynamic-labs/sdk-react-core'

const { primaryWallet } = useDynamicContext()
console.log(primaryWallet)
```

#### Allow user to link a new wallet

How: Pop up our linking modal using a hook (setShowLinkNewWalletModal)

Hook/Component: [useDynamicModals](/react-sdk/hooks/usedynamicmodals)

Notes:

* You will need to also use the DynamicMultiWalletPromptsWidget component

```jsx
import {
  useDynamicModals,
  DynamicMultiWalletPromptsWidget,
} from '@dynamic-labs/sdk-react-core'

const LinkWallet = ({ text }) => {
  const { setShowLinkNewWalletModal } = useDynamicModals()

  return (
    <>
      <div className="link-wallet-container">
        <Button
          className="profile-button"
          onClick={() => setShowLinkNewWalletModal(true)}
        >
          {text}
        </Button>
      </div>
      <DynamicMultiWalletPromptsWidget />
    </>
  )
}
```

#### Switch the primary wallet to another

How: useSwitchWallets hooks

Hook/Component: [https://docs.dynamic.xyz/react-sdk/hooks/useswitchwallet#useswitchwallet](https://docs.dynamic.xyz/react-sdk/hooks/useswitchwallet#useswitchwallet)

Notes: None

```jsx
import React from 'react'
import { useSwitchWallet, useUserWallets } from '@dynamic-labs/sdk-react-core'

const WalletSwitcher = () => {
  const switchWallet = useSwitchWallet()
  const userWallets = useUserWallets()

  return (
    <div>
      {userWallets.map((wallet) => (
        <button key={wallet.id} onClick={() => switchWallet(wallet.id)}>
          {wallet.address}
        </button>
      ))}
    </div>
  )
}
```

## Wallet Interactions

To learn how to send balance, sign messages etc., please check out [the Wallet Interaction guides](/wallets/using-wallets/interacting-with-wallets) where we split into Read actions and Write actions, and we provide per chain examples for common functionality.
