WizardConnect/docs/react.md
Dagur Valberg Johannsson 45fd9f4cb5
Add 'react' package with QR code and modal dialog
Makes it easier for dapp developers to integrate WizardConnect and have
consistent user interface for it across dapps.
2026-03-18 16:34:41 +01:00

4.1 KiB

React integration

@wizardconnect/react provides React components and hooks for dapp developers who want to add WizardConnect wallet connectivity without writing relay boilerplate.

Quick start

import { useWizardConnect, WizardConnectQRDialog } from "@wizardconnect/react";

function App() {
  const wc = useWizardConnect({ dappName: "My Dapp" });

  return (
    <>
      <button onClick={wc.connect} disabled={wc.state !== "idle"}>
        Connect Wallet
      </button>

      {wc.uri && wc.qrUri && (
        <WizardConnectQRDialog
          show={wc.state === "connecting"}
          onClose={() => wc.disconnect()}
          uri={wc.uri}
          qrUri={wc.qrUri}
        />
      )}

      {wc.state === "connected" && (
        <p>Connected to {wc.walletName}</p>
      )}
    </>
  );
}

useWizardConnect

The useWizardConnect hook manages the full relay lifecycle:

  1. connect() — calls initiateDappRelay(), creates a DappConnectionManager, and returns the connection URI for QR display.
  2. Key exchange — listens for keyexchangecomplete and persists the wallet's public key to localStorage for auto-reconnect.
  3. walletready — updates state to "connected" and populates walletName/walletIcon.
  4. Auto-reconnect — on mount, checks localStorage for a stored session with a walletPublicKey and automatically reconnects.
  5. disconnect() — sends a courtesy disconnect, cleans up the relay, and clears session storage.

Return value

interface UseWizardConnectResult {
  state: "idle" | "connecting" | "connected" | "disconnected";
  manager: DappConnectionManager | null;
  uri: string | null;
  qrUri: string | null;
  walletName: string | null;
  walletIcon: string | null;
  connect: () => boolean;
  disconnect: () => Promise<void>;
  error: string | null;
}

Using the manager

Once state === "connected", the manager is a live DappConnectionManager from @wizardconnect/dapp. Use it to derive addresses and request signatures:

// Derive a receive address pubkey
const pubkey = wc.manager.getPubkey(0, 0n);

// Send a sign request
const seq = wc.manager.nextSequence();
const response = await wc.manager.sendSignRequest({ ... });

For most dapps, you'll wrap the manager in an app-specific wallet adapter (like RelayWalletDapp in the Cauldron and Moria codebases).

WizardConnectQRDialog

A framework-independent modal dialog for displaying the connection QR code. Uses inline styles (no Tailwind or CSS framework dependency) with a dark theme by default.

Customization

Colors, text, and logos are all customizable via props:

<WizardConnectQRDialog
  show={true}
  onClose={handleClose}
  uri={connection.uri}
  qrUri={connection.qrUri}
  title="My Protocol"
  subtitle="Scan to pair your wallet"
  logoUrl="/my-logo.png"
  theme={{
    dialogBackground: "#0f172a",
    headerBackground: "#0f172a",
    borderColor: "#334155",
  }}
  onCopy={(uri) => {
    navigator.clipboard.writeText(uri);
    showToast("Copied!");
  }}
/>

The onCopy callback replaces the default navigator.clipboard.writeText behavior, which is useful when the dapp has its own toast/notification system.

AlphanumericQRCode

A standalone canvas-based QR code component. Uses QR Alphanumeric mode with error correction level H (30% recovery), which allows a center logo overlay without breaking the code.

<AlphanumericQRCode
  value="WIZ://..."
  size={280}
  foreground="#1e2a4a"
  background="#ffffff"
  logoUrl="/logo.png"
/>

Session persistence

By default, useWizardConnect persists session credentials (private key, shared secret, and wallet public key) to localStorage under the wizardconnect-session key. This enables auto-reconnect when the user refreshes the page.

The persistence key and behavior can be customized:

useWizardConnect({
  sessionKey: "my-app-wc-session",  // custom localStorage key
  persistSession: false,             // disable persistence entirely
});

Credentials are only stored after the key exchange completes. On disconnect, the stored session is cleared.