Installation

npm install @gelatonetwork/smartwallet @dynamic-labs/sdk-react-core @dynamic-labs/ethereum @dynamic-labs/wagmi-connector @tanstack/react-query wagmi viem

Setup Instructions

1

Create Dynamic App

  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

Set Environment Variables

Create a .env.local file in your project root:
NEXT_PUBLIC_DYNAMIC_APP_ID=your_dynamic_environment_id
NEXT_PUBLIC_GELATO_API_KEY=your_gelato_api_key

Implementation

1

Import Dependencies

import {
  createGelatoSmartWalletClient,
  sponsored,
} from "@gelatonetwork/smartwallet";
import {
  DynamicContextProvider,
  useDynamicContext,
} from "@dynamic-labs/sdk-react-core";
import { QueryClientProvider, QueryClient } from "@tanstack/react-query";
import { EthereumWalletConnectors } from "@dynamic-labs/ethereum";
import { DynamicWagmiConnector } from "@dynamic-labs/wagmi-connector";
import { WagmiProvider, createConfig, http } from "wagmi";
import { baseSepolia } from "viem/chains";
import { wagmi } from "@gelatonetwork/smartwallet-react-sdk";
import {
  prepareAuthorization,
  SignAuthorizationReturnType,
} from "viem/actions";
import {
  isEthereumWallet,
  isTurnkeyWalletConnector,
} from "@dynamic-labs/ethereum";
2

Configure Providers

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(
          wagmi({
            chains: [baseSepolia],
            transports: {
              [baseSepolia.id]: http(),
            },
          }).config
        )}
      >
        <QueryClientProvider client={queryClient}>
          <DynamicWagmiConnector>
            <App />
          </DynamicWagmiConnector>
        </QueryClientProvider>
      </WagmiProvider>
    </DynamicContextProvider>
  );
}
3

Create Smart Wallet Client

const App = () => {
  const sendTransaction = async () => {
    const { primaryWallet, handleLogOut } = useDynamicContext();

    if (!primaryWallet || !isEthereumWallet(primaryWallet)) {
      return;
    }

    const connector = primaryWallet.connector;

    if (!connector || !isTurnkeyWalletConnector(connector)) {
      return;
    }

    if (chain.id) {
      await primaryWallet.switchNetwork(chain.id);
    }

    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
    });
  };
  return (
    <div>
      <button onClick={sendTransaction}>Send Transaction</button>
    </div>
  );
};
4

Execute Transactions

Execute transactions using different payment methods:

Additional Resources