Skip to main content
This guide is currently React only.

Setup Instructions

1

Create Dynamic Environment

  1. Visit the Dynamic Dashboard
  2. Create a new app or select an existing one
  3. Enable the Embedded Wallets feature
  4. Copy your Environment 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

Create App with create-dynamic-app

Use the CLI to scaffold a Next.js app pre-configured with Dynamic, Wagmi and viem (non-interactive via flags):
npx create-dynamic-app@latest gelato-smart-wallet --framework nextjs --library viem --wagmi true --chains ethereum --pm npm
4

Install Gelato Smart Wallet SDK

Install the Gelato Smart Wallet SDK in the generated project:
cd gelato-smart-wallet && npm install @gelatonetwork/smartwallet
5

Set Environment Variables

In the scaffolded project, create a .env.local file in the project root:
NEXT_PUBLIC_DYNAMIC_APP_ID=your_dynamic_environment_id
NEXT_PUBLIC_GELATO_API_KEY=your_gelato_api_key

Implementation

1

Configure providers (lib/providers.tsx)

In the scaffolded app, update your providers to include Dynamic, Wagmi, and React Query. If your project already has a lib/providers.tsx, edit it; otherwise create it and use it in your root layout.
// lib/providers.tsx
import React from "react";
import { DynamicContextProvider } from "@dynamic-labs/sdk-react-core";
import { EthereumWalletConnectors, isEthereumWallet } from "@dynamic-labs/ethereum";
import { DynamicWagmiConnector } from "@dynamic-labs/wagmi-connector";
import { QueryClientProvider, QueryClient } from "@tanstack/react-query";
import { WagmiProvider, createConfig, http } from "wagmi";
import { baseSepolia } from "viem/chains";

const queryClient = new QueryClient();

export default function Providers({ children }: { children: React.ReactNode }) {
  return (
    <DynamicContextProvider
      settings={{
        environmentId: process.env.NEXT_PUBLIC_DYNAMIC_APP_ID!,
        walletConnectors: [EthereumWalletConnectors],
      }}
    >
      <WagmiProvider
        config={createConfig({
          chains: [baseSepolia],
          transports: {
            [baseSepolia.id]: http(),
          },
        })}
      >
        <QueryClientProvider client={queryClient}>
          <DynamicWagmiConnector>{children}</DynamicWagmiConnector>
        </QueryClientProvider>
      </WagmiProvider>
    </DynamicContextProvider>
  );
}
2

Create Smart Wallet Client (components/SendTransactionButton.tsx)

// components/SendTransactionButton.tsx
import React from "react";
import { useDynamicContext } from "@dynamic-labs/sdk-react-core";
import { isEthereumWallet } from "@dynamic-labs/ethereum";
import { isDynamicWaasConnector } from "@dynamic-labs/wallet-connector-core";
import {
  createGelatoSmartWalletClient,
} from "@gelatonetwork/smartwallet";
import {
  prepareAuthorization,
  SignAuthorizationReturnType,
} from "viem/actions";

export function SendTransactionButton() {
  const { primaryWallet } = useDynamicContext();

  const sendTransaction = async () => {
    if (!primaryWallet || !isEthereumWallet(primaryWallet)) return;

    const connector = primaryWallet.connector;
    if (!connector || !isDynamicWaasConnector(connector)) return;

    const client = await primaryWallet.getWalletClient();

    client.account.signAuthorization = async (parameters) => {
      const preparedAuthorization = await prepareAuthorization(client, parameters);
      const signedAuthorization = await connector.signAuthorization(preparedAuthorization);

      return {
        address: preparedAuthorization.address,
        chainId: preparedAuthorization.chainId,
        nonce: preparedAuthorization.nonce,
        r: signedAuthorization.r,
        s: signedAuthorization.s,
        v: signedAuthorization.v,
        yParity: signedAuthorization.yParity,
      } as SignAuthorizationReturnType;
    };

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

    // Example: call execute later (see next step)
    console.log("Gelato Smart Wallet client ready", smartWalletClient);
  };

  return <button onClick={sendTransaction}>Send Transaction</button>;
}
3

Use the button (e.g., app/page.tsx)

// app/page.tsx
import { SendTransactionButton } from "@/components/SendTransactionButton";

export default function Page() {
  return (
    <main>
      <SendTransactionButton />
    </main>
  );
}
4

Execute Transactions

Execute transactions using different payment methods:

Additional Resources