Installation

npm install @gelatonetwork/smartwallet @getpara/react-sdk @getpara/viem-v2-integration @tanstack/react-query viem

Setup Instructions

1

Create Para App

  1. Visit the Para Dashboard
  2. Create a new app or select an existing one
  3. Copy your API Key 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_PARA_API_KEY=your_para_api_key
NEXT_PUBLIC_GELATO_API_KEY=your_gelato_api_key

Implementation

1

Import Dependencies

import {
  createGelatoSmartWalletClient,
  sponsored,
} from "@gelatonetwork/smartwallet";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import {
  ParaProvider,
  Environment,
  useClient,
  useModal,
  useWallet,
} from "@getpara/react-sdk";
import { createParaAccount } from "@getpara/viem-v2-integration";
import { createPublicClient, createWalletClient, http } from "viem";
import { sepolia } from "viem/chains";
import { gelato } from "@gelatonetwork/smartwallet/accounts";
import "@getpara/react-sdk/styles.css";
2

Configure Providers

const queryClient = new QueryClient();

export default function Provider({ children }: { children: React.ReactNode }) {
  return (
    <QueryClientProvider client={queryClient}>
      <ParaProvider
        paraClientConfig={{
          env: Environment.BETA,
          apiKey: process.env.NEXT_PUBLIC_PARA_API_KEY!,
        }}
        config={{
          appName: "Your App Name",
        }}
      >
        <App>
      </ParaProvider>
    </QueryClientProvider>
  );
}
3

Create Smart Wallet Client

export default function App() {
  const para = useClient();
  const { openModal } = useModal();
  const { data: wallet } = useWallet();

  const sendTransaction = async () => {
    try {
      if (!para) {
        throw new Error("Para client not available");
      }

      const viemParaAccount = createParaAccount(para);
      if (!viemParaAccount) {
        throw new Error("Failed to create Para account");
      }

      viemParaAccount.signMessage = async ({ message }) => {
        return customSignMessage(para, message);
      };
      viemParaAccount.signAuthorization = async (authorization) => {
        return customSignAuthorization(para, authorization);
      };
      viemParaAccount.signTypedData = async (typedData) => {
        return customSignTypedData(para, typedData);
      };

      const publicClient = createPublicClient({
        chain: sepolia,
        transport: http(""),
      });

      const account = await gelato({
        owner: viemParaAccount,
        client: publicClient,
      });

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

      const smartWalletClient = await createGelatoSmartWalletClient(
        walletClient,
        {
          apiKey: process.env.NEXT_PUBLIC_GELATO_API_KEY,
        }
      );

    } catch (error) {
      console.error("Client creation failed:", error);
      throw error;
    }
  };

  return (
    <div>
      <button onClick={() => openModal()}>Connect Wallet</button>
      <button onClick={() => sendTransaction()}>Send Transaction</button>
      <p>Connected: {wallet?.address}</p>
    </div>
  );
}
4

Execute Transactions

Execute transactions using different payment methods:

Additional Resources