LazorKitProvider
Provider component — initialises config, RPC, and the wallet store.
Wrap your app once at the root with LazorKitProvider. It sets up the Zustand store,
builds the Connection, installs Buffer polyfills, and holds the portal / paymaster config.
import { LazorKitProvider } from '@lazorkit/wallet-mobile-adapter';Minimum setup
<LazorKitProvider>
<App />
</LazorKitProvider>Devnet defaults
With no props, the provider connects to Solana devnet through portal.lazor.sh and
LazorKit's devnet Kora paymaster at kora.devnet.lazorkit.com. Perfect for demos and
local development. Mainnet runs protocol v1 today: see Networks & versions.
Production setup
<LazorKitProvider
rpcUrl={process.env.EXPO_PUBLIC_RPC_URL}
portalUrl="https://portal.lazor.sh"
cluster="mainnet"
configPaymaster={{
paymasterUrl: process.env.EXPO_PUBLIC_PAYMASTER_URL!,
apiKey: process.env.EXPO_PUBLIC_PAYMASTER_KEY,
}}
v1ConfigPaymaster={{ paymasterUrl: process.env.EXPO_PUBLIC_V1_PAYMASTER_URL! }}
rpId="portal.lazor.sh"
isDebug={__DEV__}
>
<App />
</LazorKitProvider>Props
| Prop | Type | Default | Required |
|---|---|---|---|
rpcUrl | string | https://api.devnet.solana.com | no |
portalUrl | string | https://portal.lazor.sh | no |
configPaymaster | { paymasterUrl: string; apiKey?: string } | Devnet Kora | no |
v1ConfigPaymaster | { paymasterUrl: string; apiKey?: string } | configPaymaster | no |
cluster | 'mainnet' | 'devnet' | read from rpcUrl, else mainnet | no |
rpId | string | portal.lazor.sh | no |
isDebug | boolean | false | no |
children | ReactNode | — | yes |
Prop details
rpId must match
rpId is the WebAuthn Relying Party ID baked into each passkey at registration time.
Changing it between connect calls invalidates existing passkeys. Keep it stable in
production.
rpcUrl— Any Solana RPC. Falsy values fall back to the Devnet default.portalUrl— The WebAuthn-enabled web page the SDK opens viaexpo-web-browser. Self-hosters can point this at their own portal.configPaymaster— Kora JSON-RPC endpoint for v2 wallets.apiKeyis sent asx-api-keyon every request; it ships in your app, so it is not a secret.v1ConfigPaymaster(2.0.0+) — the relayer for users whose wallet is still on LazorKit v1: the one your app used before v2. LazorKit's v2 relayer does not sponsor v1. See Migrating from v1.cluster(2.0.0+) — which clusterrpcUrlserves. Read from the URL (mainnet,devnet,localhost) otherwise, and anything unrecognised is taken as mainnet.isDebug— Enables verbose logs via the built-inlogger.
Wallet confirmation props
Version note
These props are in @lazorkit/wallet-mobile-adapter 2.0.0 and later. Earlier
versions — 1.x, and the 2.0.0 betas up to 2.0.0-beta.4 — do not have them.
| Prop | Type | Default |
|---|---|---|
onConfirmWallet | 'builtin' | 'throw' | ConfirmWalletHandler | 'builtin' |
trustedAuthorities | readonly string[] — your own Ed25519 keys | none |
watchMints | readonly string[] — SPL Token mints you receive | none |
connect uses a returning user's wallet on its own only when it is the one wallet the
passkey has signed for and nothing else can spend from it; otherwise it asks the user.
onConfirmWallet picks how: the provider's built-in chooser, your own UI, or a thrown
WalletNeedsConfirmationError. See Wallet Confirmation.
Recipes
Switch networks at runtime
import { useState } from 'react';
import { LazorKitProvider } from '@lazorkit/wallet-mobile-adapter';
export function Root() {
const [network] = useState<'devnet' | 'mainnet'>('devnet');
const rpcUrl = network === 'devnet'
? 'https://api.devnet.solana.com'
: 'https://api.mainnet-beta.solana.com';
return (
<LazorKitProvider rpcUrl={rpcUrl} cluster={network}>
<App />
</LazorKitProvider>
);
}Changing rpcUrl recreates the Connection. The persisted wallet record is untouched: it
belongs to the cluster it was created on, so disconnect before switching clusters.
Hide behind an env-driven config
const isProd = !__DEV__;
<LazorKitProvider
rpcUrl={isProd
? process.env.EXPO_PUBLIC_MAINNET_RPC!
: 'https://api.devnet.solana.com'}
configPaymaster={{
paymasterUrl: isProd
? process.env.EXPO_PUBLIC_MAINNET_PAYMASTER!
: 'https://kora.devnet.lazorkit.com',
}}
>
<App />
</LazorKitProvider>Runtime notes
- Memoizes the
ConnectiononrpcUrl(atconfirmed), so rebuilds are cheap. - Persists
{ wallet, config }toAsyncStorageunder keylazor-wallet-store. Per passkey it also keeps the slot of its last transaction (ten minutes) and any send whose outcome is unknown, underlazorkit:passkey-lane:…(2.1.0+). - Never stores session or authority secret keys: you hold those (use secure storage).
- Migrates records from the store's own format v0 (before April 2026, when
smartWalletheld the wallet PDA) to v1, wheresmartWalletis the vault. This is a storage format version, unrelated to the protocol version. A stored wallet withoutprotocolVersionis treated as protocol v1.