TL;DR: Web3 wallet onboarding in 2025 = embedded wallets + social/passkey login + gas sponsorship + multi-chain from day one. This post compares Dynamic, Web3Auth, Privy —then shows a copy-paste React & React Native quickstart that uses Openfort for in-app, non-custodial wallets, address fetching, chain switching, and sponsored transactions. Links and snippets are real and current.
Why another onboarding guide?
- “SDK wallet” posts are steady, but most skip multi-chain + RN.
- “Web3 wallet” is noisy (4–5 posts/day); let’s keep this dev-practical.
- The 2023 comparisons are dated—SDKs shipped major upgrades in 2024–2025.
Capability | Dynamic | Web3Auth | Privy | Openfort |
---|---|---|---|---|
Social / passkey login | ✅ | ✅ | ✅ | ✅ (email/social/passkey) |
Embedded non-custodial | ✅ | ✅ | ✅ | ✅ |
Multi-chain (EVM + SVM) | ✅ | ✅ | ✅ | ✅ (EIP-1193 + Wagmi/Viem) |
Mobile Focus | React Native | React Native | React Native | React Native + Swift |
Gas sponsorship | Third Party | Third Party | Built-in | Built-in + Dashboard policies |
Dev UX (hooks/components) | UI | UI | UI | headless or UI |
Sources & release notes: Dynamic SDK v4; Web3Auth product docs; Privy onboarding/wallets; Openfort docs (quickstart, wallet actions).
My take: if you need React + React Native parity, gasless by config, and standard EIP-1193 so you can use Wagmi/Viem without weird adapters, Openfort is the most “just-ship-it” today. If your org prefers MPC-first UX libraries, Web3Auth/Privy remain solid picks. Dynamic shines on polish and enterprise workflows.
Quick Start (React)
1. Install
npm install @openfort/react wagmi viem@^2.22.0 @tanstack/react-query
2. Providers: Openfort + Wagmi + Query
import React from "react";
import {
AuthProvider,
OpenfortProvider,
getDefaultConfig,
} from "@openfort/react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { WagmiProvider, createConfig } from "wagmi";
import { polygonAmoy } from "viem/chains";
const config = createConfig(
getDefaultConfig({
appName: "My Onboarding Demo",
chains: [polygonAmoy],
ssr: true,
})
);
const queryClient = new QueryClient();
export function Providers({ children }: { children: React.ReactNode }) {
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
<OpenfortProvider
publishableKey={import.meta.env.VITE_OPENFORT_PUB_KEY!}
walletConfig={{
shieldPublishableKey: import.meta.env.VITE_OPENFORT_SHIELD_PUB_KEY!,
// Optional: automatic recovery via your backend endpoint
createEncryptedSessionEndpoint: "/api/shield-session",
}}
>
<AuthProvider>{children}</AuthProvider>
</OpenfortProvider>
</QueryClientProvider>
</WagmiProvider>
);
}
3. Login + embedded wallet button:
import React from "react";
import { Providers } from "./Providers";
import { OpenfortButton } from "@openfort/react";
export default function App() {
return (
<Providers>
<h1>Onboard users in one click</h1>
<OpenfortButton />
</Providers>
);
}
4. Backend recovery endpoint (optional)
Use the one-click deploy or add a tiny /api/shield-session that returns a session—copied from the docs.
Get the wallet address (multi chain)
Under the hood, Openfort can expose an EIP-1193 provider, so you can use Wagmi/Viem normally.
import openfort from "./openfortConfig"; // see docs for setup
const provider = await openfort.embeddedWallet.getEthereumProvider();
const [address] = await provider.request({ method: "eth_accounts", params: [] });
console.log("Active address:", address);
Switch chains and re-use the same interface:
await provider.request({
method: "wallet_switchEthereumChain",
params: [{ chainId: "0x5" }], // Goerli example
});
Docs: EIP-1193 provider & network switching.
Tip: if you’re already on Wagmi, useAccount() gives you the active address; use switchChain (Viem/Wagmi) or the raw wallet_switchEthereumChain request
5. Sponsor gas in one line
Create a sponsor policy in the dashboard → paste the pol_... into your provider config:
<OpenfortProvider
publishableKey={import.meta.env.VITE_OPENFORT_PUB_KEY!}
walletConfig={{
shieldPublishableKey: import.meta.env.VITE_OPENFORT_SHIELD_PUB_KEY!,
ethereumProviderPolicyId: { 80002: "pol_..." }, // polygonAmoy.id
}}
>
{children}
</OpenfortProvider>
Then send transactions with Wagmi:
import { useCallback } from "react";
import { parseUnits } from "viem";
import { useAccount, useWriteContract } from "wagmi";
const usdc = "0xA0b8...eB48"; // replace
const abi = [{ name: "transfer", type: "function", inputs: [{name:"to",type:"address"},{name:"amount",type:"uint256"}], outputs:[{name:"success",type:"bool"}]}] as const;
export function useSendUsdc() {
const { address } = useAccount();
const { writeContract } = useWriteContract();
return useCallback(
async (to: `0x${string}`, amount: string) => {
if (!address) throw new Error("Wallet not connected");
writeContract({ address: usdc, abi, functionName: "transfer", args: [to, parseUnits(amount, 6)] });
},
[address, writeContract]
);
}
How sponsorship is configured and applied → docs.
React Native notes (2025)
- RN SDK is live—use the same mental model (Auth → Embedded wallet → EIP-1193 provider bridge). Feature announcement here; follow the product docs for setup.
- Set up your RN env with Expo/CLI as usual. Then drop in Openfort’s RN package & providers, mirroring the React setup.
When to pick what (quick decision chart)
- I want MPC, social login, and a long vendor list → Start with Web3Auth or Privy, then layer gas/onramps.
- I want clean UI and enterprise onboarding polish → Dynamic (v4) is strong.
- I want React + RN parity, standard EIP-1193, gasless via config → Openfort. Docs are concise, and the provider is drop-in with Wagmi/Viem.
Links you’ll like:
- Openfort overview & React quickstart → docs & sample code.
- Wallet actions (send ERC-20) + gas sponsor policies.
Open question for you
Do you prefer “black-box” onboarding (fewer knobs, faster ship) or “lego-kit” onboarding (standard EIP-1193 + your hooks)? What did I miss for RN? Drop your stack & pain points—I’ll add a RN-only follow-up with code if there’s interest.
Top comments (0)