<!--
Sitemap:
- [Tempo Accounts SDK - Getting Started](/docs/): Set up the Tempo Accounts SDK to create, manage, and interact with accounts on Tempo.
- [Deploying to Production](/docs/production): Things to consider before deploying your application with the Tempo Accounts SDK to production.
- [FAQ](/docs/faq): Frequently asked questions about the Tempo Accounts SDK.
- [Connect Accounts](/docs/guides/connect-accounts): Connect a Tempo account in your application.
- [Authentication](/docs/guides/authentication): Authenticate connected accounts against your own server with a signed SIWE challenge.
- [Identity](/docs/guides/identity): Request and verify identity claims about a connected account, starting with a verified email.
- [Transfers](/docs/guides/transfers): Send stablecoin transfers from a connected Tempo account, initiated either by the user or by your server.
- [Spend Permissions](/docs/guides/spend-permissions): Authorize spend limits, call scopes, and expiries so repeat transfers can be signed without a confirmation prompt.
- [React Native](/docs/guides/react-native): Set up Tempo Accounts in a React Native app.
- [Subscriptions](/docs/guides/subscriptions): Charge recurring payments from a connected Tempo account.
- [Fee Sponsorship](/docs/guides/fee-sponsorship): Sponsor transaction fees from a server-controlled policy.
- [Deposits](/docs/guides/deposits): Open the Tempo deposit flow from a connected account and let the user choose deposit details.
- [Swaps](/docs/guides/swaps): Open the Tempo swap flow from a connected account with optional pre-filled intent fields.
- [Theming](/docs/guides/theming): Match embedded account surfaces to your product.
- [CLI](/docs/guides/cli): Authorize and use Tempo accounts from command-line tools.
- [Adapters](/docs/adapters/): Choose the signing adapter for your Tempo Accounts SDK integration.
- [Tempo Wallet Adapter](/docs/adapters/tempo-wallet): Use Tempo Wallet as the hosted universal wallet adapter.
- [WebAuthn Adapter](/docs/adapters/webauthn): Use domain-bound passkeys as the account signing adapter.
- [Turnkey Adapter](/docs/adapters/turnkey): Use Turnkey-managed wallet accounts as the account signing adapter.
- [Privy Adapter](/docs/adapters/privy): Use Privy embedded wallets as the account signing adapter.
- [Private Key Adapter](/docs/adapters/private-key): Sign in-process with a `secp256k1` private key.
- [Custom Adapter](/docs/adapters/custom): Author your own adapter with the `Adapter.define` API.
- [Adapters](/docs/api/adapters): Pluggable adapters for the Tempo Accounts SDK Provider.
- [dialog](/docs/api/dialog): Adapter for the Tempo Wallet dialog, an embedded iframe or popup for account management.
- [local](/docs/api/local): Key-agnostic adapter for defining arbitrary account types and signing mechanisms.
- [mobileWebAuth](/docs/api/mobileWebAuth): Mobile web auth adapter for browser-session wallet requests.
- [postMessage](/docs/api/postMessage): Connect to wallet from anywhere on the web
- [privy](/docs/api/privy): React adapter backed by Privy sessions and embedded Ethereum wallets.
- [secp256k1](/docs/api/secp256k1): Adapter that signs in-process with a `secp256k1` private key.
- [turnkey](/docs/api/turnkey): Adapter backed by Turnkey client sessions.
- [webAuthn](/docs/api/webAuthn): Adapter for passkey-based accounts using WebAuthn registration and authentication.
- [Dialog](/docs/api/dialogs): Dialog modes for embedding the Tempo Wallet.
- [Dialog.iframe](/docs/api/dialog.iframe): Embed the Tempo Wallet auth UI in an iframe dialog element.
- [Dialog.popup](/docs/api/dialog.popup): Open the Tempo Wallet auth UI in a popup window.
- [Expiry](/docs/api/expiry): Utility functions for computing access key expiry timestamps.
- [Provider](/docs/api/provider): Create an EIP-1193 provider for managing accounts on Tempo.
- [Rpc](/docs/api/rpc): Per-method Zod schemas and shared building blocks for the Accounts JSON-RPC surface.
- [Schema](/docs/api/schema): Zod-based JSON-RPC schema definitions for the Accounts provider.
- [TrustedHosts](/docs/api/trustedHosts): Trusted host mappings and matching helpers for dialog adapters.
- [WebAuthnCeremony](/docs/api/webauthnceremony): Pluggable strategy for WebAuthn registration and authentication ceremonies.
- [WebAuthnCeremony.from](/docs/api/webauthnceremony.from): Create a WebAuthnCeremony from a custom implementation.
- [WebAuthnCeremony.server](/docs/api/webauthnceremony.server): Server-backed WebAuthn ceremony that delegates to a remote handler.
- [CLI](/docs/cli/provider): Create a Provider for CLI environments.
- [eth_accounts](/docs/rpc/eth_accounts): Get the addresses of the currently connected accounts.
- [eth_chainId](/docs/rpc/eth_chainId): Get the chain ID of the currently active chain.
- [eth_fillTransaction](/docs/rpc/eth_fillTransaction): Fills missing transaction fields and returns wallet-aware metadata.
- [eth_requestAccounts](/docs/rpc/eth_requestAccounts): Request access to user accounts, prompting the user to connect if needed.
- [eth_sendTransaction](/docs/rpc/eth_sendTransaction): Send a transaction from the connected account.
- [eth_sendTransactionSync](/docs/rpc/eth_sendTransactionSync): Send a transaction and wait for the receipt.
- [eth_signTransaction](/docs/rpc/eth_signTransaction): Sign a transaction without broadcasting it.
- [eth_signTypedData_v4](/docs/rpc/eth_signTypedData_v4): Sign EIP-712 typed structured data with the connected account.
- [personal_sign](/docs/rpc/personal_sign): Sign a message with the connected account.
- [wallet_authorizeAccessKey](/docs/rpc/wallet_authorizeAccessKey): Authorize an access key for delegated transaction signing.
- [wallet_connect](/docs/rpc/wallet_connect): Connect account(s) with optional capabilities like access key authorization.
- [wallet_deposit](/docs/rpc/wallet_deposit): Open the wallet deposit flow with optional pre-filled fields.
- [wallet_depositZone](/docs/rpc/wallet_depositZone): Open the wallet zone-deposit flow with optional pre-filled fields.
- [wallet_disconnect](/docs/rpc/wallet_disconnect): Disconnect the connected account(s).
- [wallet_getBalances](/docs/rpc/wallet_getBalances): Get token balances for an account.
- [wallet_getCallsStatus](/docs/rpc/wallet_getCallsStatus): Get the status of a batch of calls sent via wallet_sendCalls.
- [wallet_getCapabilities](/docs/rpc/wallet_getCapabilities): Get account capabilities for specified chains.
- [wallet_revokeAccessKey](/docs/rpc/wallet_revokeAccessKey): Revoke a previously authorized access key.
- [wallet_send](/docs/rpc/wallet_send): Open the wallet send-token flow with optional pre-filled fields.
- [wallet_sendCalls](/docs/rpc/wallet_sendCalls): Send a batch of calls from the connected account.
- [wallet_swap](/docs/rpc/wallet_swap): Open the wallet swap flow with optional pre-filled swap intent fields.
- [wallet_switchEthereumChain](/docs/rpc/wallet_switchEthereumChain): Switch the provider's active chain.
- [wallet_withdrawZone](/docs/rpc/wallet_withdrawZone): Open the wallet zone-withdraw flow with optional pre-filled fields.
- [Remote](/docs/api/remote): Bridge that runs inside the wallet's iframe/popup and serves RPC requests from the host SDK.
- [Remote.create](/docs/api/remote.create): Create a remote context bound to a Messenger and Provider.
- [Remote.useEnsureVisibility](/docs/api/remote.useEnsureVisibility): React hook that monitors iframe visibility and falls back to a popup when occluded.
- [Remote.useState](/docs/api/remote.useState): React hook to subscribe to a remote context's state store.
- [Remote.useTheme](/docs/api/remote.useTheme): React hook that applies theme overrides from URL search params and live messenger updates.
- [Remote.validateSearch](/docs/api/remote.validateSearch): Validate an RPC request payload from URL search params.
- [Tempo Accounts Server Handlers](/docs/server/): Configure server-side Tempo Accounts SDK handlers for relaying wallet RPC requests, composing backends, and managing WebAuthn ceremonies.
- [Handler.auth](/docs/server/handler.auth): Server handler that issues SIWE-based authentication challenges and sessions.
- [Handler.codeAuth](/docs/server/handler.codeAuth): Server handler for the device-code (PKCE) access-key bootstrap flow.
- [Handler.compose](/docs/server/handler.compose): Compose multiple server handlers into a single handler.
- [Handler.exchange](/docs/server/handler.exchange): Server handler that returns Stablecoin DEX quotes and ready-to-submit calls.
- [Handler.relay](/docs/server/handler.relay): Server handler that proxies certain RPC requests with wallet-aware enrichment.
- [Handler.webAuthn](/docs/server/handler.webAuthn): Server-side WebAuthn ceremony handler for registration and authentication.
- [hc](/docs/server/hc): Typed RPC client for handlers built with the Tempo Accounts SDK.
- [Identity.verify](/docs/server/identity.verify): Verify a wallet-issued identity token (verified email) against an issuer's JWKS.
- [Kv](/docs/server/kv): Key-value store adapters for server-side persistence.
- [Kv.cloudflare](/docs/server/kv.cloudflare): Kv adapter backed by a Cloudflare Workers KV namespace.
- [Kv.durableObject](/docs/server/kv.durableObject): Kv adapter backed by a Cloudflare Durable Object with atomic take and create.
- [Kv.from](/docs/server/kv.from): Wrap a custom Kv-shaped object so the SDK accepts it as a Kv.
- [Kv.memory](/docs/server/kv.memory): In-memory Kv adapter for tests and single-process deployments.
- [Keystore](/docs/api/keystore): Pluggable backends for key material.
- [Keystore.p256](/docs/api/keystore.p256): Pure-JS P-256 keystore.
- [Keystore.secp256k1](/docs/api/keystore.secp256k1): Pure-JS secp256k1 keystore.
- [Keystore.webCryptoP256](/docs/api/keystore.webCryptoP256): WebCrypto P-256 keystore.
- [Storage](/docs/api/storage): Pluggable storage adapters for persisting provider state.
- [Storage.combine](/docs/api/storage.combine): Combine multiple Storage adapters into one.
- [Storage.cookie](/docs/api/storage.cookie): Cookie-backed Storage adapter.
- [Storage.from](/docs/api/storage.from): Create a Storage adapter from a custom implementation.
- [Storage.idb](/docs/api/storage.idb): IndexedDB-backed Storage adapter.
- [Storage.localStorage](/docs/api/storage.localStorage): localStorage-backed Storage adapter.
- [Storage.memory](/docs/api/storage.memory): In-memory Storage adapter.
- [asyncStorage](/docs/api/storage.asyncStorage): React Native Storage adapter backed by AsyncStorage.
- [secureMmkv](/docs/api/storage.secureMmkv): Encrypted React Native Storage adapter backed by MMKV.
- [Tempo Accounts SDK](/index): The fastest way to add stablecoins to your application.
- [Secp256k1 Adapter](/docs/adapters/secp256k1): Sign in-process with a `secp256k1` private key.
- [Bring Your Auth](/docs/enterprise/bring-your-auth/): Connect enterprise auth and signing systems to Tempo accounts.
- [Hosted Universal Wallets](/docs/enterprise/hosted-universal-wallets): Stub for hosting a universal wallet on your own domain.
- [Handler.feePayer (Deprecated)](/docs/server/handler.feePayer): Deprecated — use Handler.relay with feePayer option instead.
- [tempoWallet](/docs/wagmi/tempoWallet): Wagmi connector for the Tempo Wallet dialog.
- [webAuthn](/docs/wagmi/webAuthn): Wagmi connector for passkey-based WebAuthn accounts.
- [AWS KMS](/docs/enterprise/bring-your-auth/aws-kms): Stub for integrating AWS KMS-backed signing with the Tempo Accounts SDK.
- [Custom Auth](/docs/enterprise/bring-your-auth/custom): Stub for first-party enterprise auth and signing integrations.
- [Privy](/docs/enterprise/bring-your-auth/privy): Enterprise notes for integrating Privy-backed auth with the Tempo Accounts SDK.
- [Turnkey](/docs/enterprise/bring-your-auth/turnkey): Stub for integrating Turnkey-backed signing with the Tempo Accounts SDK.
-->

# Connect Accounts

Connect a Tempo account in your application using the [Tempo Accounts SDK](/docs) and [Wagmi](https://wagmi.sh).

The Tempo Accounts SDK ships several signing adapters — [Tempo Wallet](/docs/adapters/tempo-wallet), [domain-bound Passkeys](/docs/adapters/webauthn), [Turnkey](/docs/adapters/turnkey), [Privy](/docs/adapters/privy), and more. Each adapter exposes the same Wagmi connector surface, so the integration code in this guide is the same regardless of which adapter you pick. Choose an adapter once in your Wagmi config; the rest of your app stays adapter-agnostic.

:::info\[Which adapter should I use?]

Most apps should start with **Tempo Wallet** for a universal, hosted account experience. Pick **domain-bound Passkeys** if you want full control over the auth ceremony on your own origin, or another adapter if you have an existing custody stack. See the [Adapters overview](/docs/adapters) for a side-by-side comparison.

:::

## Demo

By the end of this guide, you will be able to let users connect a Tempo account from your application using your adapter of choice.

<Demo title="Connect an Account" githubUrl="https://github.com/tempoxyz/accounts/tree/main/examples/basic" headerAction={<DemoReset />} className="flex justify-start">
  <ConnectAccount standalone />
</Demo>

## Walkthrough

::::steps

### Install the SDK

Install `accounts` together with Wagmi and Viem.

:::code-group

```bash [npm]
npm i accounts wagmi viem
```

```bash [pnpm]
pnpm i accounts wagmi viem
```

```bash [bun]
bun i accounts wagmi viem
```

:::

### Set up Wagmi

Ensure that you have set up your project with Wagmi by following the [official guide](https://wagmi.sh/react/getting-started).

### Configure an Adapter

Next, register a Tempo signing adapter as a Wagmi connector. Pick the adapter that fits how you want to custody accounts — the rest of the app code stays the same.

:::code-group

```tsx twoslash [Tempo Wallet]
// @noErrors
import { createConfig, http } from 'wagmi'
import { tempo } from 'wagmi/chains'
import { tempoWallet } from 'wagmi/connectors' // [!code ++]

export const config = createConfig({
  chains: [tempo],
  connectors: [tempoWallet()], // [!code ++]
  multiInjectedProviderDiscovery: false,
  transports: {
    [tempo.id]: http(),
  },
})
```

```tsx twoslash [Domain-bound Passkeys]
// @noErrors
import { createConfig, http } from 'wagmi'
import { tempo } from 'wagmi/chains'
import { webAuthn } from 'wagmi/tempo' // [!code ++]

export const config = createConfig({
  chains: [tempo],
  connectors: [webAuthn({ authUrl: '/auth' })], // [!code ++]
  multiInjectedProviderDiscovery: false,
  transports: {
    [tempo.id]: http(),
  },
})
```

:::

:::tip

This Wagmi configuration sets `multiInjectedProviderDiscovery` to `false` to
prevent injected browser wallets from being detected, and to prefer the Tempo connector.
If you would like to allow connection to other wallets, set this property to `true`.

:::

### Display Sign In Button

After that, set up a "Sign in" button that triggers the connector for the user.

We will create a new `Example.tsx` component to work in.

:::code-group

```tsx twoslash [Example.tsx]
// @noErrors
import { useConnect, useConnectors } from 'wagmi'

export function Example() {
  const connect = useConnect()
  const [connector] = useConnectors()

  return (
    <div>
      <button onClick={() => connect.connect({ connector })}>
        Sign in
      </button>
    </div>
  )
}
```

:::

### Display Account & Sign Out

After the user has signed in, display the account information and a sign out button.

```tsx twoslash [Example.tsx]
// @noErrors
import { useConnection, useConnect, useConnectors, useDisconnect } from 'wagmi'

export function Example() {
  const account = useConnection() // [!code ++]
  const connect = useConnect()
  const [connector] = useConnectors()
  const disconnect = useDisconnect() // [!code ++]

  if (account.address) // [!code ++]
    return ( // [!code ++]
      <div> {/* [!code ++] */}
        <div>{account.address.slice(0, 6)}...{account.address.slice(-4)}</div> {/* [!code ++] */}
        <button onClick={() => disconnect.disconnect()}>Sign out</button> {/* [!code ++] */}
      </div> {/* [!code ++] */}
    ) // [!code ++]

  return (
    <div>
      <button onClick={() => connect.connect({ connector })}>
        Sign in
      </button>
    </div>
  )
}
```

### Deploy to Production

When you're ready to go live, follow the [Deploying to Production](/docs/production) guide to configure your application for production use.

::::

## Recipes

### Request a Verified Email

Pass the `identity` capability to request the account's verified email during connect.

Set `withCapabilities: true` so the connect result includes per-account `capabilities`, then read the email from the authenticated account.

```tsx twoslash [Example.tsx]
// @noErrors
import { useConnect, useConnectors } from 'wagmi'

export function Example() {
  const connect = useConnect()
  const [connector] = useConnectors()

  return (
    <button
      onClick={async () => {
        const result = await connect.connectAsync({
          connector,
          withCapabilities: true, // [!code focus]
          capabilities: { // [!code focus]
            identity: { email: true }, // [!code focus]
          }, // [!code focus]
        })

        // Present only if the user approved sharing. // [!code focus]
        const email = result.accounts[0]?.capabilities?.identity?.email // [!code focus]
      }}
    >
      Sign in
    </button>
  )
}
```

:::warn
The plain `email` string is fine for client-side display, but anyone can set it. The result also carries a signed `idToken` that your server can verify to trust the email. See [Verify the Email Server-Side](/docs/guides/authentication#verify-the-email-server-side).
:::

## Best Practices

### Deposit Funds

If users should have a chance to fund their account immediately after connecting,
pass the `showDeposit` capability. The wallet shows the standard deposit picker
after connect succeeds. The prompt is optional, so the user can continue without
depositing.

```tsx twoslash [Example.tsx]
// @noErrors
import { useConnect, useConnectors } from 'wagmi'

export function Example() {
  const connect = useConnect()
  const [connector] = useConnectors()

  return (
    <button
      onClick={() =>
        connect.connect({
          connector,
          capabilities: { // [!code focus]
            showDeposit: true, // [!code focus]
          }, // [!code focus]
        })
      }
    >
      Sign up
    </button>
  )
}
```

:::tip

Use the object form when you want to pre-fill deposit details.

```tsx twoslash [Example.tsx]
// @noErrors
connect.connect({
  connector,
  capabilities: { // [!code focus]
    showDeposit: { // [!code focus]
      amount: '10', // [!code focus]
      token: 'USDC.e', // [!code focus]
    }, // [!code focus]
  }, // [!code focus]
})
```

:::

### Loading State

When the user is signing in or signing out, show loading state to indicate that the process is happening.

Use the `isPending` property from the `useConnect` hook to show pending state to the user.

```tsx twoslash [Example.tsx]
// @noErrors
import { useConnection, useConnect, useConnectors, useDisconnect } from 'wagmi'

export function Example() {
  const account = useConnection()
  const connect = useConnect()
  const [connector] = useConnectors()
  const disconnect = useDisconnect()

  if (connect.isPending) // [!code ++]
    return <div>Check prompt...</div> {/* [!code ++] */}
  return (/* ... */)
}
```

### Error Handling

If an error unexpectedly occurs, display an error message to the user.

Use the `error` property from the `useConnect` hook to show error state to the user.

```tsx twoslash [Example.tsx]
// @noErrors
import { useConnection, useConnect, useConnectors, useDisconnect } from 'wagmi'

export function Example() {
  const account = useConnection()
  const connect = useConnect()
  const [connector] = useConnectors()
  const disconnect = useDisconnect()

  if (connect.error) // [!code ++]
    return <div>Error: {connect.error.message}</div> {/* [!code ++] */}
  return (/* ... */)
}
```

## Learning Resources

<Cards>
  <Card description="Choose between Tempo Wallet, WebAuthn, Turnkey, Privy, and custom signing infrastructure" to="/docs/adapters" icon="lucide:route" title="Choose an Adapter" />

  <Card description="Send stablecoin transfers from a connected account, initiated by the user or by your server" to="/docs/guides/transfers" icon="lucide:send" title="Send Transfers" />

  <Card description="Sponsor transaction fees for your users to enable feeless transactions" to="/docs/guides/fee-sponsorship" icon="lucide:badge-dollar-sign" title="Sponsor Fees" />

  <Card description="Authenticate connected accounts against your own server with signed messages" to="/docs/guides/authentication" icon="lucide:fingerprint" title="Authentication" />
</Cards>
