<!--
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.
-->

# Deploying to Production

Each adapter has different production considerations. Pick the adapter you ship with below to walk through what to set up and check off the production checklist.

<Tabs stateKey="adapter">
  <Tab title="Tempo Wallet" className="pt-8!">
    The [Tempo Wallet adapter](/docs/adapters/tempo-wallet) embeds an iframe-hosted wallet served from `wallet.tempo.xyz`. Production readiness depends on configuring trusted hosts, CSP, and HTTPS so the dialog renders reliably across browsers.

    ## Production Checklist

    <CheckboxCards>
      <CheckboxCard id="tempo-wallet.trusted-hosts" href="#trusted-hosts">
        The production hostname is registered in the trusted hosts list.
      </CheckboxCard>

      <CheckboxCard id="tempo-wallet.csp-frame-src" href="#content-security-policy">
        The Content Security Policy allows wallet.tempo.xyz as a frame source.
      </CheckboxCard>

      <CheckboxCard id="tempo-wallet.https" href="#https">
        The app is served over HTTPS.
      </CheckboxCard>

      <CheckboxCard id="tempo-wallet.iframe-visibility" href="#iframe-visibility">
        The iframe dialog mounts visibly on every page that may trigger it.
      </CheckboxCard>
    </CheckboxCards>

    ## Trusted Hosts

    To enable the `iframe` dialog on all browsers in production, ensure your website hostname is added to the [trusted hosts list](https://github.com/tempoxyz/accounts/blob/main/src/trusted-hosts.json).

    Without this, the `iframe` dialog will fall back to a popup on browsers that do not support the [IntersectionObserver v2 API](https://web.dev/articles/intersectionobserver-v2).

    ## Content Security Policy

    If you've deployed a Content Security Policy, ensure that you have the Tempo Accounts SDK configured with your CSPs.

    The full set of directives that the Tempo Accounts SDK requires are:

    | Directive   | Value                      |
    | ----------- | -------------------------- |
    | `frame-src` | `https://wallet.tempo.xyz` |

    ## HTTPS

    Browsers refuse to load secure third-party iframes from insecure origins. Tempo Wallet's iframe communication and passkey ceremonies both require a secure context, so production traffic must be served over HTTPS.

    ## Iframe Visibility

    [IntersectionObserver v2](https://web.dev/articles/intersectionobserver-v2) disables iframes that are obscured by overlays, modals, or sticky headers. When the dialog is triggered, verify it is not covered by any other UI — otherwise the user will see a blank surface.
  </Tab>

  <Tab title="WebAuthn" className="pt-8!">
    The [WebAuthn adapter](/docs/adapters/webauthn) binds account keys to your own domain. Treat passkey infrastructure with the same care as user authentication.

    ## Production Checklist

    <CheckboxCards>
      <CheckboxCard id="webauthn.https-origin" href="#https-origin">
        The WebAuthn origin is served over HTTPS in production.
      </CheckboxCard>

      <CheckboxCard id="webauthn.persistent-kv" href="#persistent-storage">
        The WebAuthn handler is backed by persistent [Kv](/docs/server/kv) storage.
      </CheckboxCard>

      <CheckboxCard id="webauthn.rpid-future-proof" href="#choosing-an-rpid">
        The RP ID fits both the current hostname and any future subdomain plan.
      </CheckboxCard>

      <CheckboxCard id="webauthn.multiple-credentials" href="#multiple-credentials-per-user">
        Users can register a backup device or hardware security key.
      </CheckboxCard>

      <CheckboxCard id="webauthn.clear-errors" href="#surfacing-clear-errors">
        Specific errors are surfaced for failed ceremonies and origin mismatches.
      </CheckboxCard>

      <CheckboxCard id="webauthn.rate-limit" href="#rate-limiting">
        Registration and login ceremony endpoints are rate-limited.
      </CheckboxCard>
    </CheckboxCards>

    ## HTTPS Origin

    WebAuthn requires a [secure context](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts) outside of `localhost`. Production passkey ceremonies will fail outright over HTTP.

    ## Persistent Storage

    Memory-backed [`Kv`](/docs/server/kv) loses challenges and credential records on restart. Back `Handler.webAuthn` with `Kv.cookie`, `Kv.durableObject`, or `Kv.cloudflare` so registrations survive deploys and restarts.

    ## Choosing an `rpId`

    Passkeys are bound to the `rpId` at registration. Changing it later invalidates every existing credential and locks users out — pick a value that covers any subdomain you may add.

    ## Multiple Credentials per User

    Passkeys live on individual authenticators. Letting users add a backup device or hardware security key prevents lockouts when one device is lost or wiped.

    ## Surfacing Clear Errors

    WebAuthn ceremony failures are easy to misdiagnose. Surface specific error messages for expired challenges, canceled prompts, and RP ID or origin mismatches so users (and support) can recover quickly.

    ## Rate Limiting

    Unbounded `/register/options`, `/register`, `/login/options`, and `/login` endpoints are an enumeration and brute-force vector. Apply per-IP and per-user rate limits.
  </Tab>

  <Tab title="Private Keys" className="pt-8!">
    The [Private Key adapter](/docs/adapters/private-key) signs in-process with a `secp256k1` private key. Production use is appropriate for server-side signers, fee payers, and scripts.

    ## Production Checklist

    <CheckboxCards>
      <CheckboxCard id="private-key.trusted-server-environments" href="#trusted-server-environments">
        Production keys are held only in trusted server environments.
      </CheckboxCard>

      <CheckboxCard id="private-key.one-key-per-role" href="#one-key-per-role-and-environment">
        One key is used per role and per environment.
      </CheckboxCard>

      <CheckboxCard id="private-key.no-logging" href="#never-log-secrets">
        Private keys, derived mnemonics, and raw secret values are never logged.
      </CheckboxCard>

      <CheckboxCard id="private-key.rotation-runbook" href="#key-rotation-runbook">
        A key rotation runbook is in place before shipping.
      </CheckboxCard>
    </CheckboxCards>

    ## Trusted Server Environments

    Browsers, CI logs, and developer laptops are not trusted environments. Production keys belong on the same machine that signs with them, behind your secret manager.

    ## One Key per Role and Environment

    Sharing a key across dev, staging, and production means one leak compromises every environment. Separate keys also make audit logs and on-chain attribution meaningful.

    ## Never Log Secrets

    Logs flow into observability tools, error trackers, and backups. Strip private keys, derived mnemonics, and raw secret values at the source — never emit them, even at `debug` level.

    ## Key Rotation Runbook

    When a key leaks, you need a tested process to mint, deploy, and revoke before an attacker acts. Practice the runbook before you need it.
  </Tab>
</Tabs>
