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

# Openfort

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

Openfort provides authentication and embedded EOA wallets protected by Shield. Convert the authenticated wallet's EIP-1193 provider to a viem wallet client, then adapt that client for Rhinestone.

## Prerequisites

* An Openfort project and publishable key
* A Shield publishable key
* A React application
* A backend that issues short-lived Rhinestone JWTs

<Steps>
  <Step title="Install the dependencies">
    ```bash theme={null}
    npm install @openfort/react @rhinestone/sdk viem
    ```
  </Step>

  <Step title="Configure Openfort">
    Configure Openfort to create EOAs. Rhinestone supplies the smart account layer.

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

    import {
      AccountTypeEnum,
      AuthProvider,
      OpenfortProvider,
    } from '@openfort/react'
    import { sepolia } from 'viem/chains'

    export function Providers({ children }: { children: React.ReactNode }) {
      return (
        <OpenfortProvider
          publishableKey={process.env.NEXT_PUBLIC_OPENFORT_PUBLISHABLE_KEY!}
          walletConfig={{
            shieldPublishableKey:
              process.env.NEXT_PUBLIC_SHIELD_PUBLISHABLE_KEY!,
            createEncryptedSessionEndpoint: '/api/openfort/encryption-session',
            ethereum: {
              accountType: AccountTypeEnum.EOA,
              chainId: sepolia.id,
            },
          }}
          uiConfig={{
            authProviders: [
              AuthProvider.EMAIL_OTP,
              AuthProvider.GOOGLE,
              AuthProvider.GUEST,
            ],
          }}
        >
          {children}
        </OpenfortProvider>
      )
    }
    ```

    The encryption-session route must authenticate the Openfort access token and mint the user's Shield encryption session on your backend. Never expose a Shield secret key in this component. Alternatively, configure and implement Openfort passkey or password recovery instead of automatic recovery.
  </Step>

  <Step title="Configure browser authentication">
    Openfort's publishable keys can be used by the client. Your Rhinestone API key cannot. Use short-lived JWTs for the browser SDK:

    ```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 secure token issuance.
  </Step>

  <Step title="Create the Rhinestone account">
    Wait for Openfort authentication and an embedded wallet before requesting its provider.

    ```tsx theme={null}
    import { useUser } from '@openfort/react'
    import { useEthereumEmbeddedWallet } from '@openfort/react/ethereum'
    import { walletClientToAccount } from '@rhinestone/sdk/utils'
    import { createWalletClient, custom } from 'viem'
    import { sepolia } from 'viem/chains'
    import { rhinestone } from './rhinestone'

    export function ConnectRhinestoneButton() {
      const { isAuthenticated } = useUser()
      const wallet = useEthereumEmbeddedWallet({ chainId: sepolia.id })

      async function connect() {
        if (!isAuthenticated || wallet.status !== 'connected') return

        const walletClient = createWalletClient({
          account: wallet.address,
          chain: sepolia,
          transport: custom(wallet.provider),
        })
        const owner = walletClientToAccount(walletClient)
        const account = await rhinestone.createAccount({
          owners: { type: 'ecdsa', accounts: [owner] },
        })

        console.log(account.getAddress())
      }

      return <button onClick={connect}>Create account</button>
    }
    ```
  </Step>
</Steps>

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

See the [Openfort embedded wallet documentation](https://www.openfort.io/docs/products/embedded-wallet/react) for authentication and Shield recovery configuration.
