Skip to main content
Migrate your existing Thirdweb application to Para’s unified wallet system. Para provides similar wallet connection capabilities with additional features like embedded wallets and session management while maintaining a simple integration.

Installation

Replace Thirdweb with Para SDK:
Terminal
npm uninstall thirdweb
npm install @getpara/react-sdk @tanstack/react-query wagmi viem
For a full list of dependencies, refer to the Quick Start Guide.

Configuration Changes

Before: Thirdweb Client

Your existing Thirdweb client configuration:
lib/client.ts
import { createThirdwebClient } from "thirdweb";

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

After: Para Configuration

Replace with Para configuration:
src/config/constants.ts
import { Environment } from "@getpara/react-sdk";

export const API_KEY = process.env.NEXT_PUBLIC_PARA_API_KEY ?? "";
export const ENVIRONMENT = 
  (process.env.NEXT_PUBLIC_PARA_ENVIRONMENT as Environment) || Environment.BETA;

if (!API_KEY) {
  throw new Error("Missing NEXT_PUBLIC_PARA_API_KEY environment variable");
}

Provider Migration

Before: Thirdweb Provider

Your existing Thirdweb provider in the layout:
app/layout.tsx
import type { Metadata } from "next";
import { ThirdwebProvider } from "thirdweb/react";

export const metadata: Metadata = {
  title: "Your App",
  description: "Your App Description",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body>
        <ThirdwebProvider>{children}</ThirdwebProvider>
      </body>
    </html>
  );
}

After: Para Provider Setup

Create a Para provider component:
src/context/ParaProvider.tsx
"use client";

import { ParaProvider as Provider } from "@getpara/react-sdk";
import { API_KEY, ENVIRONMENT } from "@/config/constants";
import { mainnet, polygon, arbitrum } from "wagmi/chains";

export function ParaProvider({ children }: { children: React.ReactNode }) {
  return (
    <Provider
      paraClientConfig={{
        apiKey: API_KEY,
        env: ENVIRONMENT,
      }}
      externalWalletConfig={{
        wallets: ["METAMASK", "COINBASE", "WALLETCONNECT", "RAINBOW"],
        evmConnector: {
          config: {
            chains: [mainnet, polygon, arbitrum],
          },
        },
        walletConnect: {
          projectId: process.env.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID || "",
        },
      }}
      config={{
        appName: "Your App Name",
      }}
      paraModalConfig={{
        authLayout: ["AUTH:FULL", "EXTERNAL:FULL"],
        theme: { mode: "light" },
      }}
    >
      {children}
    </Provider>
  );
}
Update your layout:
src/app/layout.tsx
import type { Metadata } from "next";
import "@getpara/react-sdk/styles.css";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ParaProvider } from "@/context/ParaProvider";

const queryClient = new QueryClient();

export const metadata: Metadata = {
  title: "Your App",
  description: "Your App Description",
};

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <QueryClientProvider client={queryClient}>
          <ParaProvider>
            {children}
          </ParaProvider>
        </QueryClientProvider>
      </body>
    </html>
  );
}

Connect Button Migration

Before: Thirdweb ConnectButton

app/page.tsx
"use client";
import { ConnectButton } from "thirdweb/react";
import { client } from "@/lib/client";

export default function Home() {
  return (
    <main>
      <ConnectButton client={client} />
    </main>
  );
}

After: Para Connect Button

src/components/ConnectButton.tsx
"use client";

import { useAccount, useModal, useWallet } from "@getpara/react-sdk";

export function ConnectButton() {
  const { openModal } = useModal();
  const { data: wallet } = useWallet();
  const { isConnected } = useAccount();

  if (isConnected && wallet?.address) {
    return (
      <button onClick={() => openModal()} className="connect-button">
        {wallet.address.slice(0, 6)}...{wallet.address.slice(-4)}
      </button>
    );
  }

  return (
    <button onClick={() => openModal()} className="connect-button">
      Connect Wallet
    </button>
  );
}
Use it in your page:
src/app/page.tsx
import { ConnectButton } from "@/components/ConnectButton";

export default function Home() {
  return (
    <main>
      <ConnectButton />
    </main>
  );
}

Hook Migration

Account Information

import { useActiveAccount } from "thirdweb/react";

function Account() {
  const account = useActiveAccount();
  
  return (
    <div>
      Address: {account?.address}
    </div>
  );
}

Wallet Connection Status

import { useActiveWalletConnectionStatus } from "thirdweb/react";

function ConnectionStatus() {
  const status = useActiveWalletConnectionStatus();
  
  return (
    <div>
      Status: {status}
    </div>
  );
}

Disconnect Wallet

import { useDisconnect } from "thirdweb/react";

function DisconnectButton() {
  const { disconnect } = useDisconnect();
  
  return (
    <button onClick={disconnect}>
      Disconnect
    </button>
  );
}

Smart Contract Interaction

Para uses Wagmi for contract interactions, providing a different approach than Thirdweb:

Reading Contract Data

import { getContract } from "thirdweb";
import { useReadContract } from "thirdweb/react";
import { client } from "@/lib/client";

const contract = getContract({
  client,
  chain: ethereum,
  address: "0x...",
});

function ContractRead() {
  const { data } = useReadContract({
    contract,
    method: "function balanceOf(address) returns (uint256)",
    params: ["0x..."],
  });
  
  return <div>{data?.toString()}</div>;
}

Writing to Contract

import { prepareContractCall } from "thirdweb";
import { useSendTransaction } from "thirdweb/react";

function ContractWrite() {
  const { mutate: sendTransaction } = useSendTransaction();
  
  const handleTransfer = () => {
    const transaction = prepareContractCall({
      contract,
      method: "function transfer(address, uint256)",
      params: ["0x...", 100n],
    });
    sendTransaction(transaction);
  };
  
  return <button onClick={handleTransfer}>Transfer</button>;
}

Feature Comparison

FeatureThirdwebPara
Wallet Connection
Social LoginVia Auth SDK✅ Built-in
Email/Phone LoginVia Auth SDK✅ Built-in
Smart ContractsCustom SDKWagmi hooks
Chain Switching
Session ManagementLimited✅ Advanced
Gas SponsorshipVia Engine✅ Built-in

Advanced Features

Social Login

Para includes social login without additional configuration:
src/context/ParaProvider.tsx
paraModalConfig={{
  oAuthMethods: ["GOOGLE", "APPLE", "DISCORD", "TWITTER", "FACEBOOK"],
  disableEmailLogin: false,
  disablePhoneLogin: false,
}}

Multi-Chain Support

src/context/ParaProvider.tsx
import { mainnet, polygon, arbitrum, optimism, base } from "wagmi/chains";

externalWalletConfig={{
  evmConnector: {
    config: {
      chains: [mainnet, polygon, arbitrum, optimism, base],
    },
  },
}}

Custom Theme

src/context/ParaProvider.tsx
paraModalConfig={{
  theme: {
    mode: "dark",
    foregroundColor: "#FFFFFF",
    backgroundColor: "#1A1A1A",
    accentColor: "#6366F1",
    borderRadius: "medium",
    font: "Inter",
  },
  logo: "/logo.svg",
}}

Migration Checklist

  • Remove thirdweb package
  • Install @getpara/react-sdk, wagmi, viem
  • Add @tanstack/react-query
  • Run Para postinstall script
  • Replace Thirdweb client with Para configuration
  • Update environment variables
  • Configure supported chains
  • Set up WalletConnect project ID if needed
  • Replace ThirdwebProvider with ParaProvider
  • Update ConnectButton implementation
  • Migrate hooks to Para/Wagmi equivalents
  • Update contract interaction code
  • Test wallet connections
  • Verify contract interactions
  • Check chain switching
  • Test social login if enabled

Common Patterns

Balance Display

src/components/Balance.tsx
import { useAccount, useBalance } from "wagmi";
import { formatEther } from "viem";

export function Balance() {
  const { address } = useAccount();
  const { data } = useBalance({ address });

  if (!data) return null;

  return (
    <div>
      {formatEther(data.value)} {data.symbol}
    </div>
  );
}

Transaction History

src/components/TransactionHistory.tsx
import { useWallet } from "@getpara/react-sdk";

export function TransactionHistory() {
  const { data: wallet } = useWallet();
  
  // Para provides transaction history through the wallet object
  const transactions = wallet?.transactions || [];
  
  return (
    <ul>
      {transactions.map((tx) => (
        <li key={tx.hash}>{tx.hash}</li>
      ))}
    </ul>
  );
}

Next Steps

I