Packages
@qubic.org/react
React hooks and providers for the Qubic SDK — TanStack Query data fetching, encrypted vault, and pluggable wallet connectors.
Introduction
Provider setup
Wrap your app in QubicProvider to make all hooks available. The provider configures the RPC clients, TanStack Query instance, and optional vault:
import { QubicProvider } from "@qubic.org/react"
export default function App({ children }: { children: React.ReactNode }) {
return (
<QubicProvider>
{children}
</QubicProvider>
)
}For wallet functionality, add VaultProvider and WalletProvider inside:
<QubicProvider>
<VaultProvider>
<WalletProvider connectors={[extensionConnector()]}>
{children}
</WalletProvider>
</VaultProvider>
</QubicProvider>Data hooks vs mutation hooks
- Data hooks (
useTickInfo,useBalance, …) use TanStack Query under the hood — they cache results, deduplicate parallel requests, and re-fetch on a configurable interval. - Mutation hooks (
useSendTransfer,useSendContractCall) manage loading/error/success state for operations that change network state.
Wallet connectors
The connector system is pluggable. Three connectors are included:
| Connector | Description |
|---|---|
extensionConnector() | Browser extension wallet (e.g. Qubic Wallet) |
walletConnectConnector() | WalletConnect v2 — QR code / mobile link |
metamaskSnapConnector() | MetaMask Snap for Qubic |
You can implement WalletConnector to add custom connectors.
Installation
bun add @qubic.org/reactnpm install @qubic.org/reactpnpm add @qubic.org/reactAPI reference
| Page | What's covered |
|---|---|
| Providers | QubicProvider, VaultProvider, WalletProvider — setup and configuration |
| Data hooks | useTickInfo, useBalance, useBalances, useContractQuery, asset hooks, archive hooks |
| Send mutations | useSendTransfer, useSendContractCall |
| Wallet hooks | useWallet, useWalletConnector, useVaultState |
| Connectors | extensionConnector, walletConnectConnector, metamaskSnapConnector, custom connectors |
Examples
Display live tick info
import { useTickInfo } from "@qubic.org/react"
export function TickDisplay() {
const { data, isLoading } = useTickInfo()
if (isLoading) return <span>Loading…</span>
return (
<div>
<span>Tick: {data?.tick}</span>
<span>Epoch: {data?.epoch}</span>
</div>
)
}Fetch a balance
import { useBalance } from "@qubic.org/react"
import { toIdentity } from "@qubic.org/types"
const IDENTITY = toIdentity("CFBMEMZOIDEXQAUXYYSZIURADQLAPWPMNJXQSNVQZAHYVOPYUKKJBJUCTVJL")
export function BalanceCard() {
const { data, isLoading, error } = useBalance(IDENTITY)
if (isLoading) return <div>Loading…</div>
if (error) return <div>Error: {error.message}</div>
return <div>{data?.balance.toString()} QU</div>
}Send a transfer
import { useSendTransfer } from "@qubic.org/react"
import { toIdentity } from "@qubic.org/types"
export function SendButton() {
const { send, isPending, isSuccess, error } = useSendTransfer()
async function handleSend() {
await send({
destination: toIdentity("CFBMEMZOIDEX..."),
amount: 1_000_000n,
})
}
return (
<button onClick={handleSend} disabled={isPending}>
{isPending ? "Sending…" : "Send"}
</button>
)
}Connect a wallet
import { useWalletConnector } from "@qubic.org/react"
export function ConnectButton() {
const { connect, disconnect, isConnected, identity } = useWalletConnector()
if (isConnected) {
return (
<div>
<span>{identity}</span>
<button onClick={disconnect}>Disconnect</button>
</div>
)
}
return <button onClick={connect}>Connect Wallet</button>
}