## OpChan React SDK (packages/react) — Building Forum UIs
This guide shows how to build a forums-based app using the React SDK. It covers project wiring, wallet connection/disconnection, key delegation, waiting for Waku/network readiness, loading content, posting/commenting, voting, moderation, bookmarks, and user display utilities.
The examples assume you install and use the `@opchan/react` and `@opchan/core` packages.
---
### 1) Install and basic setup
```bash
npm i @opchan/react @opchan/core
```
Create an app-level provider using `OpChanProvider`. You must pass a minimal client config (e.g., Ordiscan API key if you have one). OpChanProvider already wraps `WagmiProvider` and `AppKitProvider` from Reown AppKit internally, so mount it directly at the app root.
```tsx
import React from 'react';
import { OpChanProvider } from '@opchan/react';
export function AppProviders({ children }: { children: React.ReactNode }) {
return (
{children}
);
}
```
OpChanProvider automatically integrates with AppKit for wallet management.
---
### 2) High-level hook
Use `useForum()` for a single entry point to the main hooks:
```tsx
import { useForum } from '@opchan/react';
function Example() {
const { user, content, permissions, network } = useForum();
// user: auth + delegation
// content: cells/posts/comments/bookmarks + actions
// permissions: derived booleans + reasons
// network: Waku readiness + refresh
return null;
}
```
---
### 3) Wallets — connect/disconnect & verification
API: `useAuth()`
```tsx
import { useAuth } from '@opchan/react';
function WalletControls() {
const { currentUser, verificationStatus, connect, disconnect, verifyOwnership } = useAuth();
return (
{currentUser ? (
<>
Connected: {currentUser.displayName}
Status: {verificationStatus}
>
) : (
<>
>
)}
);
}
```
Notes:
- `connect(walletType)` opens the AppKit modal for the specified wallet type (bitcoin/ethereum). Upon successful connection, OpChan automatically syncs the wallet state and creates a user session.
- `verifyOwnership()` refreshes identity and sets `EVerificationStatus` appropriately (checks ENS or Bitcoin Ordinals).
---
### 4) Key delegation — create, check, clear
API: `useAuth()` → `delegate(duration)`, `delegationStatus()`, `clearDelegation()`; also `delegationInfo` in-session.
```tsx
import { useAuth } from '@opchan/react';
function DelegationControls() {
const { delegate, delegationInfo, delegationStatus, clearDelegation } = useAuth();
return (
);
}
```
Behavior:
- The library generates a browser keypair and requests a wallet signature authorizing it until a selected expiry.
- All messages (cells/posts/comments/votes/moderation/profile updates) are signed with the delegated browser key and verified via the proof.
---
### 5) Network (Waku) — readiness and manual refresh
API: `useNetwork()`
```tsx
import { useNetwork } from '@opchan/react';
function NetworkStatus() {
const { isConnected, statusMessage, refresh } = useNetwork();
return (
);
}
export default function App() {
return (
);
}
```
---
### 14) Notes and best practices
- Always gate actions with `usePermissions()` to provide clear UX reasons.
- Use `pending.isPending(id)` to show optimistic “syncing…” states for content you just created or voted on.
- The store is hydrated from IndexedDB on load; Waku live messages keep it in sync.
- Identity (ENS/Ordinals/Call Sign) is resolved and cached; calling `verifyOwnership()` or updating the profile will refresh it.