> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rhinestone.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# External wallet signers

> Use an injected or WalletConnect-compatible wallet as a Rhinestone account owner.

External wallets include MetaMask, Coinbase Wallet, Rabby, and WalletConnect-compatible mobile wallets. Connect one with wagmi, convert its active wallet client to a viem account, and use that account as the Rhinestone owner.

This creates a smart account controlled by the external wallet. To use the connected address itself without a smart account, configure a [plain EOA](/wallets/custom-signer/configuration/account-types/eoa).

## Reown AppKit example

<Steps>
  <Step title="Install the dependencies">
    ```bash theme={null}
    npm install @reown/appkit @reown/appkit-adapter-wagmi @tanstack/react-query @rhinestone/sdk viem wagmi@2
    ```
  </Step>

  <Step title="Configure AppKit">
    Get a project ID from the [Reown Dashboard](https://dashboard.reown.com/), then configure AppKit once in your client application:

    ```tsx theme={null}
    'use client'

    import { createAppKit } from '@reown/appkit/react'
    import { WagmiAdapter } from '@reown/appkit-adapter-wagmi'
    import { arbitrum, base, mainnet } from '@reown/appkit/networks'

    const projectId = process.env.NEXT_PUBLIC_REOWN_PROJECT_ID!

    export const wagmiAdapter = new WagmiAdapter({
      networks: [mainnet, arbitrum, base],
      projectId,
    })

    createAppKit({
      adapters: [wagmiAdapter],
      networks: [mainnet, arbitrum, base],
      projectId,
      metadata: {
        name: 'Your app',
        description: 'Your app description',
        url: 'https://app.example.com',
        icons: ['https://app.example.com/icon.png'],
      },
    })
    ```

    Wrap your application with wagmi's `WagmiProvider` using `wagmiAdapter.wagmiConfig`, and with TanStack Query's `QueryClientProvider`.
  </Step>

  <Step title="Configure browser authentication">
    An external wallet authenticates the user, not your app's requests to Rhinestone. Keep `RHINESTONE_API_KEY` on your server and use short-lived JWTs in the browser:

    ```ts theme={null}
    import { RhinestoneSDK } from '@rhinestone/sdk'

    export const rhinestone = new RhinestoneSDK({
      auth: {
        mode: 'experimental_jwt',
        accessToken: async () => {
          const response = await fetch('/api/auth/access-token', {
            credentials: 'include',
          })
          if (!response.ok) throw new Error('Unable to authenticate with Rhinestone')
          return ((await response.json()) as { token: string }).token
        },
      },
    })
    ```

    See [security](/wallets/custom-signer/integration/security) for server handlers and sponsored-intent extension tokens.
  </Step>

  <Step title="Create the Rhinestone account">
    `walletClientToAccount` requires a wallet client with an active account. Recreate the Rhinestone account object when the connected wallet changes.

    ```tsx theme={null}
    import { useWalletClient } from 'wagmi'
    import { walletClientToAccount } from '@rhinestone/sdk/utils'
    import { rhinestone } from './rhinestone'

    export function ConnectRhinestoneButton() {
      const { data: walletClient } = useWalletClient()

      async function connect() {
        if (!walletClient) return

        const owner = walletClientToAccount(walletClient)
        const account = await rhinestone.createAccount({
          owners: { type: 'ecdsa', accounts: [owner] },
        })

        console.log(account.getAddress())
      }

      return (
        <>
          <w3m-button />
          <button disabled={!walletClient} onClick={connect}>
            Create account
          </button>
        </>
      )
    }
    ```
  </Step>
</Steps>

<Note>
  EIP-7702 requires the signer to support EIP-7702 authorizations. Do not assume every injected or WalletConnect wallet exposes that capability; use a [plain EOA](/wallets/custom-signer/configuration/account-types/eoa) or a separate smart account when it does not.
</Note>

For sponsored transactions, follow [sponsorship setup](/transactions/sponsorship/set-up). For the transaction lifecycle, continue to [send a transaction](/transactions/multichain/send-a-transaction).
