EVM wallet integration

This guide will walk you through the process of integrating EVM Wallets into your Para Modal and Para-enabled application, allowing you to onboard new users and connect with existing users who may already have external wallets like MetaMask, Coinbase Wallet and more.

Prerequisites

Before integrating wallet connections, ensure you have an existing Para project with the Para Modal set up. If you haven’t set up Para yet, follow one of our Framework Setup guides like this guide.

Looking for a lighter version?

How It Works

Para’s EVM wallet integration is powered by , the popular React hooks library for Ethereum. When you configure the ParaProvider with external wallet support, Para automatically creates and manages the Wagmi provider internally. This means:

  • No manual Wagmi setup required - Para handles all Wagmi provider configuration
  • All Wagmi hooks available - Use any Wagmi hook in your application alongside Para hooks
  • Unified configuration - Configure chains and settings through Para’s externalWalletConfig
  • Automatic connector management - Para controls wallet connectors based on your configuration

Setting up EVM Wallets

Setup is simple - just wrap your app in a provider and pass the appropriate props and configuration options to the provider. Once configured, the Para modal and wallet options will automatically appear in the modal when opened.

Para provides seamless integration with popular EVM wallets including

, , , , , , , , , , and .

Safe App Registration: To use Safe as an external wallet, you’ll need to register your application as a Safe App in the . This is required because Safe apps need to run within Safe’s context to ensure proper security and functionality. The registration process involves providing your app’s details and undergoing a review by the Safe team.

Import components

Import the wallet connectors and supporting components you need. Adjust the imports based on which wallets you want to support:

main.tsx
import {
  ParaProvider,
  ExternalWallet,
} from "@getpara/react-sdk";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { sepolia, celo, mainnet, polygon } from "wagmi/chains";

Configure the providers

Configure the ParaProvider component by wrapping your application content in the QueryClientProvider and ParaProvider components. Pass in the required configuration props:

main.tsx
const queryClient = new QueryClient();

export const App = () => {
  return (
    <QueryClientProvider client={queryClient}>
      <ParaProvider
        // ... rest of your provider config
        externalWalletConfig: {
          wallets: [ExternalWallet.Metamask],
          evmConnector: {
            config: {
              chains: [mainnet, polygon, sepolia, celo],
            },
            // wagmiProviderProps={}
          },
          walletConnect: {
            projectId: 'your_walletconnect_project_id',
          },
        }> 
        {/* Your app content */}
      </ParaProvider>
    </QueryClientProvider>
  );
};

The ParaProvider automatically creates and manages the Wagmi provider internally. You only need to provide the QueryClientProvider - Para handles all Wagmi setup for you.

External Wallet Configuration

WalletConnect (Reown) Setup: You’ll need a WalletConnect project ID if you’re using their connector. Get one from the . You can use an empty string for testing, but this isn’t recommended for production.

The ParaProvider extends Wagmi’s provider functionality, giving you access to all in your application. Place the provider near the root of your component tree for optimal performance.

Accessing the Wagmi Configuration

Para provides two methods to access the Wagmi configuration depending on your use case:

During Runtime (Inside ParaProvider)

Use the getWagmiConfig function when you need the configuration inside the ParaProvider context but outside of React hooks:

import { getWagmiConfig } from "@getpara/evm-wallet-connectors@alpha";

// Use anywhere inside ParaProvider context
const wagmiConfig = getWagmiConfig();

// Now you can use with @wagmi/core actions
import { getAccount } from '@wagmi/core'
const account = getAccount(wagmiConfig)

Before ParaProvider Initialization

If you need the Wagmi config before the ParaProvider mounts (e.g., for server-side operations or early initialization), use createParaWagmiConfig:

import { createParaWagmiConfig } from "@getpara/evm-wallet-connectors@alpha";

// Initialize config early
const wagmiConfig = createParaWagmiConfig({
  chains: [mainnet, polygon],
  // ... other wagmi config options
});

// ParaProvider will automatically use this pre-created config
// when it mounts later

The createParaWagmiConfig function creates the same configuration that ParaProvider would create internally. This enables you to use the config with @wagmi/core actions before your React app renders.

Server-Side Rendering (SSR) Considerations

When using Next.js or other SSR frameworks, proper client-side initialization is crucial since web3 functionality relies on browser APIs. SSR management is the developer’s responsibility, and Para provides the tools to handle it effectively.

Handling Hydration Issues

If you encounter hydration errors related to @getpara/evm-wallet-connectors, this indicates that Wagmi’s store hydration is happening too eagerly. Since Para uses Wagmi internally, all apply:

  1. Enable SSR mode in your configuration:
externalWalletConfig={{
  evmConnector: {
    config: {
      chains: [mainnet],
      ssr: true, // Enable SSR support
    },
  },
  // ... rest of config
}}
  1. Use dynamic imports for client-side only rendering:
import dynamic from 'next/dynamic'

const ParaProvider = dynamic(
  () => import('@getpara/react-sdk@alpha').then(mod => mod.ParaProvider),
  { ssr: false }
)
  1. Add the 'use client' directive in Next.js 13+:
'use client'

import { ParaProvider } from '@getpara/react-sdk'

export function Providers({ children }) {
  // Provider implementation
}

For advanced SSR scenarios where you want to persist wallet connection state across server renders, implement :

import { cookieStorage, createStorage } from 'wagmi'

externalWalletConfig={{
  evmConnector: {
    config: {
      chains: [mainnet],
      ssr: true,
      storage: createStorage({
        storage: cookieStorage,
      }),
    },
  },
  // ... rest of config
}}

Cookie-based persistence requires proper cookie handling on your server. This is entirely managed by the developer - Para provides the configuration options, but implementation depends on your server framework.

External Wallets with Linked Embedded Wallets

You can also provision linked embedded wallets for external wallets.

In this case, the external wallet would be the Para auth method for the user’s embedded wallet (instead of an email or social login). Embedded wallets would be created according to your API key settings.

To enable this, you can include the createLinkedEmbeddedForExternalWallets prop to indicate which external wallets this setting should be applied to.

Advanced Provider Pattern

Setting up a dedicated provider component that encapsulates all the necessary providers and modal state management is considered a best practice. This pattern makes it easier to manage the modal state globally and handle session management throughout your application.

Configuring the Para Modal

After setting up your providers you need to configure the ParaModal component to display the external wallets and authentication options to your users. You need to pass in the externalWallets and authLayout configuration options to the ParaModal component to control which of the wallets show in the modal that were specified in the provider configuration.

Set the modal props

paraModalConfig={{
  authLayout: ["AUTH_FULL","EXTERNAL_FULL"]
  theme: {
    mode: "light",
    foregroundColor: "#000000",
    backgroundColor: "#FFFFFF",
    accentColor: "#007AFF"
  }
  logo: yourLogoUrl
  // ... other modal config
}}

Modal prop options for customizing the Para Modal are included below. For advanced customization options, refer to

.

External Wallet Verification via SIWE

External wallet verification via Sign in With Ethereum adds a verification step during external connection to ensure the user owns the wallet. Enabling this feature establishes a valid Para session, which you can later use in your app to securely validate wallet ownership. To enable this, set the following option on your externalWalletConfig of your ParaProvider:

externalWalletConfig={{
  includeWalletVerification: true,
  ...REST_OF_CONFIG
}}

Connection Only Wallets

Connection only external wallets bypass all Para functionality (account creation, user tracking, etc.) when connecting an external wallet. To enable this, set the following option on your externalWalletConfig of your ParaProvider:

externalWalletConfig={{
  connectionOnly: true,
  ...REST_OF_CONFIG
}}

Since connection only wallets bypass Para, most Para functionality will be unavailable. This includes linked embedded wallets, external wallet verification, on & off ramping, etc.

Examples

For an example of what the Para External Wallets Modal might look like in your application, check out our live demo:

Modal Designer

For an example code implementation using EVM Wallets, check out our GitHub repository:

GitHub Repository

Next Steps

Now that you have integrated EVM wallets into your Para Modal, you can explore more advanced features like signing using the Para SDK with popular libraries like Ethers.js.

EVM Integrations