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

# Privy

> Use a Privy embedded wallet as the owner of a Rhinestone smart account.

Privy handles authentication and embedded wallet creation. Convert its connected wagmi wallet client to a viem account, then use that account as a Rhinestone owner.

## Prerequisites

* A Privy application and app ID
* A React application
* A backend that issues short-lived Rhinestone JWTs

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

  <Step title="Configure Privy and wagmi">
    Import `createConfig` and `WagmiProvider` from `@privy-io/wagmi` so Privy and wagmi share connection state.

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

    import { PrivyProvider } from '@privy-io/react-auth'
    import { createConfig, WagmiProvider } from '@privy-io/wagmi'
    import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
    import { http } from 'wagmi'
    import { arbitrum, base } from 'viem/chains'

    const queryClient = new QueryClient()
    const wagmiConfig = createConfig({
      chains: [arbitrum, base],
      transports: {
        [arbitrum.id]: http(),
        [base.id]: http(),
      },
    })

    export function Providers({ children }: { children: React.ReactNode }) {
      return (
        <PrivyProvider
          appId={process.env.NEXT_PUBLIC_PRIVY_APP_ID!}
          config={{
            loginMethods: ['email', 'wallet'],
            embeddedWallets: {
              ethereum: { createOnLogin: 'users-without-wallets' },
            },
            defaultChain: base,
            supportedChains: [arbitrum, base],
          }}
        >
          <QueryClientProvider client={queryClient}>
            <WagmiProvider config={wagmiConfig}>{children}</WagmiProvider>
          </QueryClientProvider>
        </PrivyProvider>
      )
    }
    ```

    The Privy app ID is public application configuration. It is not your Rhinestone API key.
  </Step>

  <Step title="Configure browser authentication">
    Do not put `RHINESTONE_API_KEY` in a `NEXT_PUBLIC_*` variable. When the SDK runs in the browser, fetch short-lived tokens from your backend:

    ```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 the server boundary and sponsored-intent extension tokens.
  </Step>

  <Step title="Create the Rhinestone account">
    Wait until Privy is ready and wagmi returns a connected wallet client. `walletClientToAccount` requires that client to have an active account.

    ```tsx theme={null}
    import { usePrivy } from '@privy-io/react-auth'
    import { useWalletClient } from 'wagmi'
    import { walletClientToAccount } from '@rhinestone/sdk/utils'
    import { rhinestone } from './rhinestone'

    export function ConnectRhinestoneButton() {
      const { ready, authenticated, login } = usePrivy()
      const { data: walletClient } = useWalletClient()

      async function connect() {
        if (!ready || !authenticated || !walletClient) return

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

        console.log(account.getAddress())
      }

      if (!ready) return <button disabled>Loading…</button>
      if (!authenticated) return <button onClick={login}>Sign in</button>
      return <button onClick={connect}>Create account</button>
    }
    ```
  </Step>
</Steps>

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

See the [Privy documentation](https://docs.privy.io/) for additional login methods and embedded wallet settings.
