Oviato Connect
Using Hooks
React hooks for Oviato Connect - useOviConnect and useOviStore
@oviato/connect provides React hooks to access authentication state and SDK functionality in your React components.
useOviConnect Hook
The primary hook for accessing Oviato authentication state and methods. Must be used inside OviConnectProvider.
Basic Usage
import { useOviConnect } from '@oviato/connect/client';
function MyComponent() {
const { session, isLoading, disconnect } = useOviConnect();
if (isLoading) {
return <div>Loading...</div>;
}
if (!session) {
return <div>Not connected</div>;
}
return (
<div>
<p>Address: {session.address}</p>
<button onClick={disconnect}>Disconnect</button>
</div>
);
}Return Values
The useOviConnect hook returns an object with the following properties:
{
// Current user session (null if not authenticated)
session: Session | null;
// Whether SDK is initializing
isLoading: boolean;
// Whether SDK is ready to use
ready: boolean;
// Update the session
setSession: (session: Session) => void;
// Disconnect and clear session
disconnect: () => void;
// Get current initialization options
getInitOptions: () => InitOptions | null;
}Session Object
When authenticated, the session object contains:
type Session = {
address: string; // Wallet address
publicKey: string; // Public key (hex)
username?: string; // OVI.ID username (if set)
network: Network; // Current network
appId: string; // Your app ID
userId: string; // Oviato user ID
createdAt: number; // Timestamp
};Complete Example
'use client';
import { useOviConnect } from '@oviato/connect/client';
import { authenticate, signMessage } from '@oviato/connect';
export default function WalletPage() {
const { session, isLoading, ready, disconnect } = useOviConnect();
const handleConnect = async () => {
const result = await authenticate();
if (result.status === 'error') {
console.error('Auth failed:', result.message);
}
};
const handleSign = async () => {
const result = await signMessage('Hello from Oviato!');
if (result.status === 'success') {
console.log('Signature:', result.data.signature);
}
};
if (isLoading || !ready) {
return <div>Loading Oviato...</div>;
}
if (!session) {
return (
<div>
<h1>Connect Your Wallet</h1>
<button onClick={handleConnect}>Connect with Oviato</button>
</div>
);
}
return (
<div>
<h1>Connected</h1>
<p>Address: {session.address}</p>
{session.username && <p>Username: @{session.username}</p>}
<p>Network: {session.network}</p>
<button onClick={handleSign}>Sign Message</button>
<button onClick={disconnect}>Disconnect</button>
</div>
);
}useOviStore Hook
Advanced hook for accessing the Zustand store directly. Provides more granular control over state subscriptions.
Basic Usage
import { useOviStore } from '@oviato/connect';
function MyComponent() {
// Subscribe to specific state
const session = useOviStore(state => state.session);
const isAuthenticated = useOviStore(state => state.isAuthenticated());
return (
<div>
{isAuthenticated ? (
<p>Address: {session?.address}</p>
) : (
<p>Not connected</p>
)}
</div>
);
}When to Use useOviStore
Use useOviStore when you need:
- Fine-grained subscriptions to avoid unnecessary re-renders
- Access to store methods directly
- Integration with other state management solutions
- Advanced state debugging
For most cases, useOviConnect is recommended as it provides a simpler API.
Available State
{
// Session state
session: Session | null;
isAuthenticated: () => boolean;
// Loading state
isLoading: boolean;
ready: boolean;
// Methods
setSession: (session: Session) => void;
clearSession: () => void;
setLoading: (loading: boolean) => void;
setReady: (ready: boolean) => void;
}Performance Optimization
import { useOviStore } from '@oviato/connect';
function AddressDisplay() {
// Only re-renders when address changes
const address = useOviStore(state => state.session?.address);
return <div>{address || 'Not connected'}</div>;
}
function LoadingIndicator() {
// Only re-renders when loading state changes
const isLoading = useOviStore(state => state.isLoading);
return isLoading ? <Spinner /> : null;
}Combining Multiple State Values
import { useOviStore } from '@oviato/connect';
function WalletInfo() {
// Efficient: single subscription for multiple values
const { address, network, username } = useOviStore(state => ({
address: state.session?.address,
network: state.session?.network,
username: state.session?.username,
}));
return (
<div>
<p>Address: {address}</p>
<p>Network: {network}</p>
{username && <p>Username: @{username}</p>}
</div>
);
}Hook Rules
Both hooks must follow React's rules of hooks:
- ✅ Must be used inside
OviConnectProvider - ✅ Only call at the top level of components
- ✅ Only call from React function components or custom hooks
- ❌ Don't call inside loops, conditions, or nested functions
Error: Hook Used Outside Provider
// ❌ Wrong: Used outside provider
function App() {
const { session } = useOviConnect(); // Error!
return <div>{session?.address}</div>;
}
// ✅ Correct: Used inside provider
function App() {
return (
<OviConnectProvider appId="your-app-id" network="bitcoinmainnet">
<MyComponent />
</OviConnectProvider>
);
}
function MyComponent() {
const { session } = useOviConnect(); // Works!
return <div>{session?.address}</div>;
}TypeScript Support
Both hooks have full TypeScript support:
import { useOviConnect } from '@oviato/connect/client';
import type { Session } from '@oviato/connect';
function MyComponent() {
const { session }: { session: Session | null } = useOviConnect();
// TypeScript knows session can be null
if (session) {
// Here, TypeScript knows session is Session
console.log(session.address); // ✅ Type-safe
}
}Next Steps
- Components Reference - Explore pre-built UI components
- Signing Messages - Sign messages with hooks
- Signing Transactions - Send transactions with hooks