Installation

npm install @gelatonetwork/smartwallet @privy-io/react-auth @privy-io/wagmi @tanstack/react-query viem

Setup Instructions

1

Create Privy App

  1. Visit the Privy Dashboard
  2. Create a new app or select an existing one
  3. Enable the Embedded Wallets feature
  4. Copy your App ID from the dashboard
2

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
3

Set Environment Variables

Create a .env.local file in your project root:
NEXT_PUBLIC_PRIVY_APP_ID=your_privy_app_id
NEXT_PUBLIC_GELATO_API_KEY=your_gelato_api_key

Implementation

1

Import Dependencies

import {
  createGelatoSmartWalletClient,
  sponsored,
} from "@gelatonetwork/smartwallet";
import {
  PrivyClientConfig,
  PrivyProvider,
  useSignAuthorization,
  useWallets,
} from "@privy-io/react-auth";
import { WagmiProvider, createConfig } from "@privy-io/wagmi";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import {
  Chain,
  Transport,
  Account,
  http,
  zeroAddress,
  custom,
  createWalletClient,
  Hex,
} from "viem";
import { SmartAccount } from "viem/account-abstraction";
import {
  prepareAuthorization,
  PrepareAuthorizationParameters,
} from "viem/actions";
import { baseSepolia } from "viem/chains";
2

Configure Providers

const queryClient = new QueryClient();

const wagmiConfig = createConfig({
  chains: [baseSepolia],
  transports: {
    [baseSepolia.id]: http(),
  },
});

const privyConfig: PrivyClientConfig = {
  embeddedWallets: {
    createOnLogin: "users-without-wallets",
    requireUserPasswordOnCreate: false,
  },
  loginMethods: ["email"],
  appearance: {
    showWalletLoginFirst: false,
  },
};

export const App = () => {
  return (
    <PrivyProvider
      appId={process.env.NEXT_PUBLIC_PRIVY_APP_ID as string}
      config={privyConfig}
    >
      <QueryClientProvider client={queryClient}>
        <WagmiProvider config={wagmiConfig} reconnectOnMount={false}>
          <App />
        </WagmiProvider>
      </QueryClientProvider>
    </PrivyProvider>
  );
};
3

Create Smart Wallet Client

const App = () => {
  const { wallets } = useWallets();
  const { signAuthorization } = useSignAuthorization();

  const sendTransaction = async () => {
    const primaryWallet = wallets[0];
    const chain = baseSepolia;

    const provider = await primaryWallet?.getEthereumProvider();
    const client = createWalletClient({
      account: primaryWallet.address as Hex,
      chain,
      transport: custom(provider),
    });

    (
      client.account as SmartAccount & {
        signAuthorization: typeof client.signAuthorization;
      }
    ).signAuthorization = async (
      parameters: PrepareAuthorizationParameters<Account>
    ) => {
      const preparedAuthorization = await prepareAuthorization(
        client,
        parameters
      );

      const signedAuthorization = await signAuthorization({
        chainId: preparedAuthorization.chainId,
        contractAddress: preparedAuthorization.address,
        nonce: preparedAuthorization.nonce,
      });

      return signedAuthorization;
    };

    const smartWalletClient = await createGelatoSmartWalletClient<
      Transport,
      Chain,
      Account
    >(client, {
      apiKey: process.env.NEXT_PUBLIC_GELATO_API_KEY,
      scw: { type: "gelato" }, // use gelato, kernel, safe, or custom
    });
  };

  return (
    <div>
      <button onClick={sendTransaction}>Send Transaction</button>
    </div>
  );
};
4

Execute Transactions

Execute transactions using different payment methods:

Additional Resources