QubicTypeScript
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:

ConnectorDescription
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/react
npm install @qubic.org/react
pnpm add @qubic.org/react

API reference

PageWhat's covered
ProvidersQubicProvider, VaultProvider, WalletProvider — setup and configuration
Data hooksuseTickInfo, useBalance, useBalances, useContractQuery, asset hooks, archive hooks
Send mutationsuseSendTransfer, useSendContractCall
Wallet hooksuseWallet, useWalletConnector, useVaultState
ConnectorsextensionConnector, 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>
}

On this page