How to Add Embedded Wallets to a React App
A step-by-step guide to adding embedded wallets to a React or Next.js app with Para: install, provider setup, auth, wallet creation, and signing.
By Para Team · Published July 5, 2026
Adding a crypto wallet to a React app used to mean building or wiring together authentication, key management, and chain-specific signing logic from scratch. With a modern SDK, it looks a lot more like adding any other authentication provider. This guide walks through adding embedded wallets to a React or Next.js app with Para: installing the SDK, setting up the provider, opening the auth modal, checking wallet state, and signing.
The steps below follow Para's current React SDK. Code is accurate as of writing; always check the Para docs for the latest package versions before shipping.
What you need before starting
You need a Para account and API key, which you get from the Para developer portal. Sign up, create a project, and copy the API key from the dashboard. Keys carry an environment prefix, BETA_ for development or PROD_ for production, so you can build against a beta key and switch over when you launch. You also need a React or Next.js app already scaffolded; the steps below assume the Next.js App Router, but the SDK works the same way in plain React and Vite.
Step 1: Install the SDK
Install the Para React SDK along with its peer dependencies for chain support:
npm install @getpara/react-sdk @tanstack/react-query wagmi@^2 viem @solana/web3.js @stellar/stellar-sdk --save-exact
Para's SDK is built to sit alongside the EVM and Solana libraries teams already use, so wagmi and viem here are the same libraries you would use in any React app talking to EVM chains, not Para-specific replacements. If your app needs Cosmos support, the docs list the additional Cosmos-specific packages to add.
Step 2: Set up the provider
Wrap your app in ParaProvider, which needs your API key and an app name. This example uses a client component, providers.tsx, that the root layout renders:
// app/providers.tsx
"use client";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ParaProvider } from "@getpara/react-sdk";
import "@getpara/react-sdk/styles.css";
const queryClient = new QueryClient();
export function Providers({ children }: Readonly<{ children: React.ReactNode }>) {
return (
<QueryClientProvider client={queryClient}>
<ParaProvider
paraClientConfig={{
apiKey: process.env.NEXT_PUBLIC_PARA_API_KEY!,
}}
config={{ appName: "Your App Name" }}
>
{children}
</ParaProvider>
</QueryClientProvider>
);
}
The @getpara/react-sdk/styles.css import is required for Para's prebuilt modal to render correctly. Then render Providers from your root layout:
// app/layout.tsx
import { Providers } from "./providers";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<Providers>{children}</Providers>
</body>
</html>
);
}
Keep your API key in an environment variable rather than hardcoding it, and use a beta key locally.
Step 3: Add the authentication modal
Para ships a prebuilt authentication modal that handles email, social login, and passkeys out of the box, so you do not need to build auth screens yourself. Use the useModal hook to open it, and useAccount to check whether a user is already connected:
// app/components/ConnectButton.tsx
"use client";
import { useModal, useAccount, useWallet } from "@getpara/react-sdk";
export function ConnectButton() {
const { openModal } = useModal();
const { isConnected } = useAccount();
const { data: wallet } = useWallet();
if (!isConnected) {
return <button onClick={() => openModal()}>Sign in</button>;
}
return <p>Connected: {wallet?.address}</p>;
}
That is the entire authentication flow: no custom forms, no OTP handling, no OAuth redirect logic to wire up yourself. The modal handles email one-time codes, social login, and passkeys, and Para creates the wallet automatically as part of that flow.
Step 4: Read wallet state
Once a user authenticates through the modal, useWallet gives you the wallet data your app needs, most commonly the address to display or use in other calls:
"use client";
import { useWallet, useAccount } from "@getpara/react-sdk";
export function WalletBadge() {
const { isConnected } = useAccount();
const { data: wallet } = useWallet();
if (!isConnected || !wallet) return null;
return (
<div>
<p>Wallet address: {wallet.address}</p>
</div>
);
}
There is no separate "create wallet" call to make. Wallet creation happens as part of authentication, so by the time isConnected is true, a wallet already exists for that user.
Step 5: Sign a message
To sign a message, use the useSignMessage hook with the connected wallet's ID:
"use client";
import { useSignMessage, useWallet } from "@getpara/react-sdk";
export function SignMessageButton() {
const { mutateAsync: signMessageAsync } = useSignMessage();
const { data: wallet } = useWallet();
const handleSign = async () => {
if (!wallet) return;
const message = "Hello from Para";
const messageBase64 = btoa(message);
const result = await signMessageAsync({
walletId: wallet.id,
messageBase64,
});
console.log("Signature:", result);
};
return <button onClick={handleSign}>Sign message</button>;
}
signMessage signs raw bytes directly, which is useful for authentication challenges or off-chain signatures. For onchain transactions, Para's SDK is designed to work with the Web3 libraries you already use, viem, ethers, or wagmi on EVM, rather than reinventing transaction construction. That means once your wallet is connected, you build and send transactions the same way you would with any other viem or wagmi setup, with Para providing the signer underneath.
Step 6: Get API keys and go further
Everything above runs on a single API key from the Para developer portal. From here, the natural next steps are wiring in your production API key, customizing the modal's branding, and adding chain-specific transaction logic with viem or wagmi for EVM, or the Solana or Cosmos equivalents if your app needs them. The Para docs cover framework-specific setup for Vite and Next.js, plus guides for signing transactions with each major chain library.
Why this is worth doing without a backend
For most apps, none of the steps above require a server. Authentication, wallet creation, and signing all run from the client through Para's SDK and infrastructure, which keeps a basic integration genuinely simple. A backend becomes useful later if you want server-side signing for automated flows, pregenerated wallets created before a user signs up, or custom session handling, but it is optional for shipping a working embedded wallet.
Under the hood, Para creates wallets using Distributed MPC, so a key share lives in the user's device secure enclave, protected by a passkey, and another lives in Para's infrastructure. Neither Para nor your app can sign alone, which makes the wallet non-custodial by design. Our MPC wallet explainer and embedded wallets guide cover this architecture in depth if you want to understand what is happening behind the hooks above.
Para's approach
Para's React SDK gives you a working, non-custodial embedded wallet with a handful of hooks and a prebuilt modal, backed by Distributed MPC and passkey authentication. It supports EVM chains, Solana, and Cosmos through the same integration, works alongside viem, ethers, and wagmi, and runs at scale across 15M+ wallets with SOC 2 Type II compliance. Start from the Para docs, or see plans on the pricing page once you are ready to move past the free tier.
Frequently asked questions
How do I add an embedded wallet to a React app?
Install the Para React SDK, wrap your app in ParaProvider with an API key, then use the useModal hook to open Para's prebuilt authentication modal. Once a user authenticates, useAccount and useWallet give you connection status and wallet data, and useSignMessage lets you sign. A basic integration takes minutes.
Do I need a backend to add embedded wallets to React?
No. Para's React SDK handles authentication, wallet creation, and signing entirely from the client for most use cases. A backend becomes useful later if you want server-side signing, pregenerated wallets, or custom session handling, but it is not required to get a working embedded wallet in your app.
Does Para work with viem and wagmi?
Yes. Para's React SDK is designed to work alongside the EVM libraries teams already use, including viem and wagmi, so you are not rewriting your app's transaction logic around a new wallet provider. The wallet integration adds authentication and key management without replacing your existing chain tooling.
Where do I get a Para API key?
Sign up or log in at the Para developer portal, create a project, and copy the API key from the dashboard. Keys are prefixed with an environment tag for beta or production use, so you can develop against a beta key and switch to a production key when you ship.
How long does a basic React integration take?
A prototype with Para's prebuilt modal and a working wallet can be running in well under an hour. A production integration with custom branding, error handling, and edge cases typically takes longer, but the core wallet functionality itself is not the bottleneck.
Related reading
What Are Embedded Wallets? The Complete Guide (2026)
Embedded wallets let users hold crypto inside your app with no seed phrase and no extension. Learn how they work, how they stay secure, and how to ship them.
What Is Wallet-as-a-Service (WaaS)? The 2026 Guide
Wallet-as-a-service lets you embed non-custodial crypto wallets into any app through an API. Learn how WaaS works, who needs it, and how to evaluate providers.
What Is an MPC Wallet? Multi-Party Computation Explained
An MPC wallet splits a private key into shares so it never exists in one place. Learn how multi-party computation works and how it differs from multisig.
What Are Passkey Wallets? Passkeys Explained
Passkey wallets use device secure enclaves instead of seed phrases. Learn how passkeys work, how they pair with MPC, and why they replace recovery phrases.
Embedded vs. External Wallets: Which Should You Offer?
Embedded wallets live inside your app; external wallets are user-managed. See the UX and conversion differences and when to offer both.