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

# Turnkey

> Integrate Turnkey signers with Rhinestone smart accounts.

## Overview

Turnkey provides secure key management infrastructure that enables you to create and manage signing keys for your users. This guide shows you how to integrate Turnkey signers with Rhinestone smart accounts for secure, non-custodial wallet experiences.

**How it works:** Unlike Privy and Dynamic, Turnkey operates at a lower level. You create a viem-compatible account using `@turnkey/viem`, then pass that account to Rhinestone. Turnkey handles the secure key management while Rhinestone adds cross-chain capabilities.

## Prerequisites

* A Turnkey account and organization
* Turnkey API credentials (API public/private key pair)
* Your organization ID from Turnkey

<Steps>
  <Step title="Install Dependencies">
    Install the required dependencies:

    <CodeGroup>
      ```bash npm theme={null}
      npm install @turnkey/http @turnkey/api-key-stamper @turnkey/viem @rhinestone/sdk viem
      ```

      ```bash pnpm theme={null}
      pnpm add @turnkey/http @turnkey/api-key-stamper @turnkey/viem @rhinestone/sdk viem
      ```

      ```bash bun theme={null}
      bun install @turnkey/http @turnkey/api-key-stamper @turnkey/viem @rhinestone/sdk viem
      ```
    </CodeGroup>
  </Step>

  <Step title="Create a Signer Wallet">
    Using the Turnkey dashboard or API, create a new Ethereum (EVM) wallet. This wallet will be the owner of the Rhinestone smart account.

    1. Log into your Turnkey dashboard
    2. Navigate to the Wallets section
    3. Create a new Ethereum wallet
    4. Note the wallet address for the next step
  </Step>

  <Step title="Create a Turnkey Signer">
    Use `@turnkey/viem` to create a viem-compatible account backed by Turnkey's signing infrastructure:

    <Note>The `createAccount` function from `@turnkey/viem` returns a full viem `LocalAccount` with `signMessage`, `signTransaction`, and `signTypedData` already implemented.</Note>

    ```tsx theme={null}
    import { TurnkeyClient } from "@turnkey/http"
    import { ApiKeyStamper } from "@turnkey/api-key-stamper"
    import { createAccount } from "@turnkey/viem"

    const turnkeyClient = new TurnkeyClient(
      { baseUrl: "https://api.turnkey.com" },
      new ApiKeyStamper({
        apiPublicKey: process.env.API_PUBLIC_KEY,
        apiPrivateKey: process.env.API_PRIVATE_KEY,
      })
    )

    const turnkeySigner = await createAccount({
      client: turnkeyClient,
      organizationId: process.env.ORGANIZATION_ID,
      signWith: "0x...", // Your Turnkey wallet address
    })
    ```
  </Step>

  <Step title="Initialize Rhinestone Account">
    Create a new Rhinestone account using the Turnkey signer. This is the same pattern as with other providers - pass the signer to Rhinestone, and it wraps it with cross-chain functionality:

    ```tsx theme={null}
    import { RhinestoneSDK } from "@rhinestone/sdk"

    const rhinestone = new RhinestoneSDK({
      apiKey: process.env.RHINESTONE_API_KEY,
    })
    const rhinestoneAccount = await rhinestone.createAccount({
      owners: {
        type: "ecdsa",
        accounts: [turnkeySigner],
      },
    })
    ```
  </Step>
</Steps>

## Usage

### Send a Cross-chain Transaction

The Rhinestone account will automatically use the Turnkey signer for all transactions:

```tsx theme={null}
import { encodeFunctionData, parseUnits, erc20Abi } from 'viem'
import { baseSepolia, arbitrumSepolia } from 'viem/chains'

const transaction = await rhinestoneAccount.sendTransaction({
  sourceChains: [baseSepolia],
  targetChain: arbitrumSepolia,
  calls: [
    {
      to: "USDC",
      data: encodeFunctionData({
        abi: erc20Abi,
        functionName: "transfer",
        args: ["0xrecipient", parseUnits("10", 6)],
      }),
    },
  ],
  tokenRequests: [
    {
      address: "USDC",
      amount: parseUnits("10", 6),
    },
  ],
})
```

<Note>Don't forget to fund the account before making any transactions.</Note>

## Environment Variables

Make sure to set the following environment variables:

```bash theme={null}
API_PRIVATE_KEY=your_turnkey_api_private_key
API_PUBLIC_KEY=your_turnkey_api_public_key
ORGANIZATION_ID=your_turnkey_organization_id
RHINESTONE_API_KEY=your_rhinestone_api_key
```

## Next Steps

* Learn about [sending cross-chain transactions](../create-first-transaction) for more transaction details
* Explore [chain abstraction](../../chain-abstraction/unified-balance) capabilities
* Check out [creating an account](../create-account) for more details
