2025-09-25 21:52:40 +05:30
## @opchan/react
Lightweight React provider and hooks for building OpChan clients on top of `@opchan/core` .
### Install
```bash
npm i @opchan/react @opchan/core react react-dom
```
### Quickstart
2025-10-28 12:45:05 +05:30
#### Quickstart Provider (wagmi-only)
2025-09-25 21:52:40 +05:30
2025-10-28 12:45:05 +05:30
OpChan uses wagmi connectors for wallet management. The OpChanProvider already wraps WagmiProvider and React Query internally, so you can mount it directly:
2025-09-25 21:52:40 +05:30
```tsx
import React from 'react';
2025-10-23 12:16:25 +05:30
import { OpChanProvider } from '@opchan/react ';
2025-09-25 21:52:40 +05:30
2025-10-28 12:45:05 +05:30
const opchanConfig = {};
2025-09-25 21:52:40 +05:30
function App() {
return (
2025-10-28 11:29:21 +05:30
< OpChanProvider config = {opchanConfig} >
{/* your app */}
< / OpChanProvider >
2025-09-25 21:52:40 +05:30
);
}
createRoot(document.getElementById('root')!).render(< App / > );
```
### Common usage
```tsx
import { useForum } from '@opchan/react ';
export function NewPostButton({ cellId }: { cellId: string }) {
const { user, content, permissions } = useForum();
const onCreate = async () => {
if (!permissions.canPost) return;
await content.createPost({ cellId, title: 'Hello', content: 'World' });
};
return (
< button disabled = {!permissions.canPost | | ! user . isAuthenticated } onClick = {onCreate} >
New post
< / button >
);
}
```
```tsx
import { useAuth, useUserDisplay } from '@opchan/react ';
export function Connect() {
const { currentUser, connect, disconnect, verifyOwnership } = useAuth();
const display = useUserDisplay(currentUser?.address ?? '');
return (
< div >
{currentUser ? (
< >
< span > {display.displayName}< / span >
< button onClick = {() = > verifyOwnership()}>Verify< / button >
< button onClick = {() = > disconnect()}>Disconnect< / button >
< />
) : (
2025-10-23 12:16:25 +05:30
< >
2025-10-28 12:45:05 +05:30
< button onClick = {() = > connect()}>
Connect Wallet
< / button >
2025-10-23 12:16:25 +05:30
< />
2025-09-25 21:52:40 +05:30
)}
< / div >
);
}
```
### API
- **Providers**
2025-10-28 12:45:05 +05:30
- **`OpChanProvider` **: High-level provider that constructs an `OpChanClient` and wires wagmi + React Query.
2025-09-25 21:52:40 +05:30
- Props:
- `config: OpChanClientConfig` — core client configuration.
- `children: React.ReactNode` .
2025-10-28 12:45:05 +05:30
- Requirements: None — this provider already wraps `WagmiProvider` and `QueryClientProvider` internally.
2025-10-23 12:16:25 +05:30
- **`AppKitWalletProvider` **: Wallet context provider (automatically included in `OpChanProvider` ).
- Provides wallet state and controls from AppKit.
2025-09-25 21:52:40 +05:30
- **`ClientProvider` **: Low-level provider if you construct `OpChanClient` yourself.
- Props: `{ client: OpChanClient; children: React.ReactNode }` .
- **Hooks**
- **`useForum()` ** → `{ user, content, permissions, network }` — convenience bundle of the hooks below.
- **`useAuth()` ** → session & identity actions
- Data: `currentUser` , `verificationStatus` , `isAuthenticated` , `delegationInfo` .
2025-10-23 12:16:25 +05:30
- Actions: `connect(walletType: 'bitcoin' | 'ethereum')` , `disconnect()` , `verifyOwnership()` ,
2025-09-25 21:52:40 +05:30
`delegate(duration)` , `delegationStatus()` , `clearDelegation()` ,
`updateProfile({ callSign?, displayPreference? })` .
2025-10-23 12:16:25 +05:30
2025-10-28 12:45:05 +05:30
2025-09-25 21:52:40 +05:30
- **`useContent()` ** → forum data & actions
- Data: `cells` , `posts` , `comments` , `bookmarks` , `postsByCell` , `commentsByPost` ,
`cellsWithStats` , `userVerificationStatus` , `lastSync` , `pending` helpers.
- Actions: `createCell({ name, description, icon? })` ,
`createPost({ cellId, title, content })` ,
`createComment({ postId, content })` ,
`vote({ targetId, isUpvote })` ,
`moderate.{post,unpost,comment,uncomment,user,unuser}(...)` ,
`togglePostBookmark(post, cellId?)` , `toggleCommentBookmark(comment, postId?)` ,
`removeBookmark(bookmarkId)` , `clearAllBookmarks()` , `refresh()` .
- **`usePermissions()` ** → permission checks
- Booleans: `canPost` , `canComment` , `canVote` , `canCreateCell` , `canDelegate` .
- Functions: `canModerate(cellId)` , `check(action, cellId?) → { allowed, reason }` , `reasons` .
- **`useNetwork()` ** → connection state
2025-10-23 18:20:16 +05:30
- Data: `isConnected` , `statusMessage` , `issues` , `isHydrated` , `canRefresh` .
2025-09-25 21:52:40 +05:30
- Actions: `refresh()` — triggers a light data refresh via core.
- **`useUIState(key, defaultValue, category?)` ** → persisted UI state
- Returns `[value, setValue, { loading, error? }]` .
- Categories: `'wizardStates' | 'preferences' | 'temporaryStates'` (default `'preferences'` ).
- **`useUserDisplay(address)` ** → identity details for any address
2025-10-28 12:45:05 +05:30
- Returns `{ address, displayName, callSign?, ensName?, verificationStatus, displayPreference, lastUpdated, isLoading, error }` .
2025-09-25 21:52:40 +05:30
- Backed by a centralized identity cache; updates propagate automatically.
- **`useClient()` ** → access the underlying `OpChanClient` (advanced use only).
### Notes
- Identity resolution, verification states, and display preferences are centralized and cached;
`useUserDisplay` and `useAuth.verifyOwnership()` will keep store and local DB in sync.
- This package is UI-agnostic; pair with your component library of choice.
2025-10-28 11:29:21 +05:30
### Runtime requirements
- Browser Buffer polyfill (for some crypto/wallet libs):
```ts
import { Buffer } from 'buffer'
if (!(window as any).Buffer) (window as any).Buffer = Buffer
```
- Config values you likely need to pass to `OpChanProvider` :
- `wakuConfig` with `contentTopic` and `reliableChannelId`
2025-09-25 21:52:40 +05:30
### License
MIT