LazorKit LogoLazorKit
React Native SDK

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

PropTypeDefaultRequired
rpcUrlstringhttps://api.devnet.solana.comno
portalUrlstringhttps://portal.lazor.shno
configPaymaster{ paymasterUrl: string; apiKey?: string }Devnet Korano
v1ConfigPaymaster{ paymasterUrl: string; apiKey?: string }configPaymasterno
cluster'mainnet' | 'devnet'read from rpcUrl, else mainnetno
rpIdstringportal.lazor.shno
isDebugbooleanfalseno
childrenReactNode—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 via expo-web-browser. Self-hosters can point this at their own portal.
  • configPaymaster — Kora JSON-RPC endpoint for v2 wallets. apiKey is sent as x-api-key on 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 cluster rpcUrl serves. Read from the URL (mainnet, devnet, localhost) otherwise, and anything unrecognised is taken as mainnet.
  • isDebug — Enables verbose logs via the built-in logger.

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.

PropTypeDefault
onConfirmWallet'builtin' | 'throw' | ConfirmWalletHandler'builtin'
trustedAuthoritiesreadonly string[] — your own Ed25519 keysnone
watchMintsreadonly string[] — SPL Token mints you receivenone

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 Connection on rpcUrl (at confirmed), so rebuilds are cheap.
  • Persists { wallet, config } to AsyncStorage under key lazor-wallet-store. Per passkey it also keeps the slot of its last transaction (ten minutes) and any send whose outcome is unknown, under lazorkit: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 smartWallet held the wallet PDA) to v1, where smartWallet is the vault. This is a storage format version, unrelated to the protocol version. A stored wallet without protocolVersion is treated as protocol v1.