Skip to main content

Installation

npm install @gelatonetwork/smartwallet @turnkey/react-wallet-kit @turnkey/viem viem

Setup Instructions

1

Create Turnkey Organization

  1. Visit the Turnkey Dashboard
  2. Create a new organization or select an existing one
  3. Navigate to the organization settings
  4. Copy your Organization ID from the dashboard
2

Configure Auth Proxy

  1. Navigate to the Wallet Kit section in the Turnkey Dashboard and enable the Auth Proxy.
  2. Customize auth methods such as email OTP and passkey.
  3. Copy the Auth Proxy Config ID
3

Get Gelato API Key

  1. Visit the Gelato App
  2. Navigate to Paymaster & Bundler > API Keys
  3. Create a new API Key and select your required networks
  4. Copy the generated API Key
4

Set Environment Variables

Create a .env.local file in your project root:
NEXT_PUBLIC_ORGANIZATION_ID=your_turnkey_organization_id
NEXT_PUBLIC_AUTH_PROXY_CONFIG_ID=your_auth_proxy_config_id
NEXT_PUBLIC_GELATO_API_KEY=your_gelato_api_key

Implementation

1

Import Dependencies

import {
  createGelatoSmartWalletClient,
  sponsored,
} from "@gelatonetwork/smartwallet";
import {
  TurnkeyProvider,
  TurnkeyProviderConfig,
  useTurnkey,
} from "@turnkey/react-wallet-kit";
import { createAccount } from "@turnkey/viem";
import { createWalletClient, http } from "viem";
import { baseSepolia } from "viem/chains";
import { useMemo } from "react";
import { CreateSubOrgParams } from "@turnkey/react-wallet-kit";
import "@turnkey/react-wallet-kit/styles.css";
2

Configure Providers

export function Providers({ children }: { children: React.ReactNode }) {
  const suborgParams = useMemo<CreateSubOrgParams>(() => {
    const ts = Date.now();
    return {
      userName: `User-${ts}`,
      customWallet: {
        walletName: `Wallet-${ts}`,
        walletAccounts: [
          {
            curve: "CURVE_SECP256K1",
            pathFormat: "PATH_FORMAT_BIP32",
            path: "m/44'/60'/0'/0/0",
            addressFormat: "ADDRESS_FORMAT_ETHEREUM",
          },
        ],
      },
    };
  }, []);

  const turnkeyConfig: TurnkeyProviderConfig = {
    organizationId: process.env.NEXT_PUBLIC_ORGANIZATION_ID!,
    authProxyConfigId: process.env.NEXT_PUBLIC_AUTH_PROXY_CONFIG_ID!,
    auth: {
      createSuborgParams: {
        emailOtpAuth: suborgParams,
        smsOtpAuth: suborgParams,
        walletAuth: suborgParams,
        oauth: suborgParams,
        passkeyAuth: {
          ...suborgParams,
          passkeyName: "My Passkey",
        },
      },
    },
  };

  return (
    <TurnkeyProvider
      config={turnkeyConfig}
      callbacks={{
        onError: (error) => console.error("Turnkey error:", error),
      }}
    >
      <App />
    </TurnkeyProvider>
  );
}
3

Create Custom Account Utility

import { LocalAccount } from "viem";

export function createCustomAccount(account: LocalAccount): LocalAccount {
  return {
    ...account,
    signAuthorization: async (parameters: any) => {
      const authorization = await (account as any).signAuthorization(
        parameters
      );
      return {
        ...authorization,
        yParity: Number(authorization.yParity),
      };
    },
  };
}
4

Create Smart Wallet Client

import { TurnkeySDKClientBase } from "@turnkey/react-wallet-kit";

export default function App() {
  const { handleLogin, wallets, httpClient } = useTurnkey();

  const sendTransaction = async () => {
    const viemAccount = await createAccount({
      client: httpClient as TurnkeySDKClientBase,
      organizationId: wallets[0].accounts[0].organizationId,
      signWith: wallets[0].accounts[0].address,
    });

    const turnkeyAccount = createCustomAccount(viemAccount);

    const walletClient = createWalletClient({
      account: turnkeyAccount,
      chain: baseSepolia,
      transport: http(),
    });

    const smartWalletClient = await createGelatoSmartWalletClient(
      walletClient,
      {
        apiKey: process.env.NEXT_PUBLIC_GELATO_API_KEY!,
        scw: { type: "gelato" }, // use gelato, kernel, safe, or custom
      }
    );
  };

  function LoginButton() {
    return <button onClick={() => handleLogin()}>Login / Sign Up</button>;
  }

  return (
    <div className="font-sans grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20">
      <LoginButton />
      <button onClick={sendTransaction}>Send Transaction</button>
    </div>
  );
}
5

Execute Transactions

Execute transactions using different payment methods:

Additional Resources