How to use Para with thirdweb

How to use Para with thirdweb

Learn how to connect Para with thirdweb. This guide shows you how to integrate Para’s embedded wallets with the thirdweb SDK to onboard users without seed phrases, while enabling full EVM and Solana compatibility, account abstraction, and seamless in-app payments.

Prerequisites

Before proceeding, ensure your application has the necessary setup for the Para SDK.

Step 1: Create a thirdweb Project

To access a client for authentication and transactions, follow these steps:

  1. Navigate to the thirdweb Dashboard.
  2. Click on Create a new project.
  3. Enter a project name (e.g., "My thirdweb project").
  4. Configure allowed domains:
    • Add your production domain (e.g., mydomain.com).
    • Add localhost:<port> for local development.
  5. Click Create to generate your project.
  6. Securely save your Client ID and Secret Key.

Add your keys to .env.local

Use either yarn or npm to install the required package:At the root of your project, create (or update) a .env.local fi

NEXT_PUBLIC_THIRDWEB_CLIENT_ID=your_thirdweb_client_id
NEXT_PUBLIC_PARA_API_KEY=your_para_api_key

Step 2: Configure the thirdweb SDK

Install Dependencies

Use either yarn or npm to install the required package:

yarn add thirdweb

# or

npm install thirdweb

Set Up the Provider

// app/providers.tsx (or _app.tsx)
"use client";

import { ReactNode } from "react";
import { ThirdwebProvider } from "thirdweb/react";
import { Environment, ParaProvider, ParaModal } from "@getpara/react-sdk";

export default function Providers({ children }: { children: ReactNode }) {
  return (
    <ThirdwebProvider>
      <ParaProvider
        paraClientConfig={{
          env: Environment.BETA, // use PROD for live
          apiKey: process.env.NEXT_PUBLIC_PARA_API_KEY!,
        }}
       config={{ appName: "Para Modal Example" }}
      >
        {children}
      </ParaProvider>
    </ThirdwebProvider>
  );
}

Step 3: Implement Login and Wallet Connection

Import Required Dependencies

In your login page or main application file, include the necessary imports:

"use client";

import { useEffect } from "react";
import { defineChain } from "thirdweb";
import { viemAdapter } from "thirdweb/adapters/viem";
import { createWalletAdapter } from "thirdweb";
import { useSetActiveWallet, useActiveWallet, ConnectButton, PayEmbed } from "thirdweb/react";
import { useViemClient, useViemAccount, useModal } from "@getpara/react-sdk";
import { client } from "@/lib/thirdwebClient";

Initialize thirdweb client

const client = createThirdwebClient({
  clientId: process.env.NEXT_PUBLIC_TEMPLATE_CLIENT_ID!,
});

// (Optional) choose your active chain the same way you do elsewhere
const chain = defineChain(1); // e.g., Ethereum mainnet, or your target EVM chain

Handle Wallet Connection

"use client";

import { useEffect } from "react";
import { defineChain } from "thirdweb";
import { viemAdapter } from "thirdweb/adapters/viem";
import { createWalletAdapter } from "thirdweb";
import { useSetActiveWallet, useActiveWallet, ConnectButton, PayEmbed } from "thirdweb/react";
import { useViemClient, useViemAccount } from "@getpara/react-sdk"; // Para hooks
import { client } from "@/lib/thirdwebClient"; // ← shared client

export function WalletBridge() {
  const { viemClient } = useViemClient();     // Para-provided viem WalletClient
  const { viemAccount } = useViemAccount();   // { address, status } etc.
  const setActiveWallet = useSetActiveWallet();
  const thirdwebWallet = useActiveWallet();
  const isConnected = Boolean(viemAccount?.address);

  // Bridge Para's viem wallet client into a thirdweb wallet
  useEffect(() => {
    let cancelled = false;

    const setActive = async () => {
      if (!viemClient || !viemAccount?.address) return;

      // Determine current chain id from the Para viem client
      const chainId =
        (await viemClient.getChainId?.()) ??
        viemClient.chain?.id ??
        1; // fallback: Ethereum mainnet

      const personalAccount = viemAdapter.walletClient.fromViem({
        walletClient: viemClient as any,
      });

      const w = createWalletAdapter({
        client,
        adaptedAccount,
        chain: defineChain(chainId),
        onDisconnect: async () => {
          // optional: any local cleanup you need
        },
        switchChain: async (next) => {
          // If you support user-initiated chain switching, implement it here.
          // Typically you’d re-create the adapter with the new chain or
          // call your own chain-switch UX before re-bridging.
        },
      });

      if (!cancelled) setActiveWallet(w);
    };

    setActive();
    return () => {
      cancelled = true;
    };
  }, [viemClient, viemAccount?.address, setActiveWallet]);
 }

Managing Wallet Disconnection

  // If the Para account goes away (user logs out / session expired),
  // make sure thirdweb disconnects too so state stays in sync.
  useEffect(() => {
    const syncDisconnect = async () => {
      if (thirdwebWallet && !viemAccount?.address) {
        await thirdwebWallet.disconnect();
      }
    };
    syncDisconnect();
  }, [thirdwebWallet, viemAccount?.address]);

Render UI Components

  return (
    <>
      {isConnected ? (
        <div className="connected-container">
          <div className="component-card">
            <h2 className="component-title">thirdweb Pay</h2>
            <PayEmbed client={client} theme="light" />
          </div>
          <div className="component-card">
            <h2 className="component-title">Wallet Management</h2>
            <ConnectButton client={client} theme="light" />
          </div>
        </div>
      ) : (
        <div className="disconnected-message">
          Connect with Para to share the wallet between both libraries!
        </div>
      )}
    </>
  );
}

Using Para x Thirdweb Together: Camp Network

Teams like Camp Network are already using Para wallets with thirdweb Account Abstraction tooling to power seamless onboarding and in-app transactions. Para provides the universal embedded wallet layer (Distributed MPC, passkeys, and multi-chain support), while thirdweb’s AA SDK gives Camp flexible smart account features like gas sponsorship, batched transactions, session keys.
The result: users log in once with Para and get a gasless and bundled transaction experience through thirdweb, without ever touching seed phrases or juggling multiple wallets.