Skip to Content

Hooks

Every hook is imported from rabitwallet and must be used inside a <RabitProvider>.

Overview

HookReturns
useAuth(){ isAuthenticated, user, logout, isLoading }
useWallet(){ evmAddress, solanaAddress, activeAccount, activeChainId, switchAccount, isReady, isLocked }
useBalances(){ balances, isLoading, refetch }
useSendToken(){ send, isSending, error, reset }
useSwap(){ getQuote, executeSwap, quote, isLoading }
useOnRamp(){ getQuote, buyWithQuote, getOffRampQuote, sellWithQuote, activeOrder }
useSignMessage(){ signMessage, isSigning, signature }
useContractRead(){ data, isLoading, refetch }
useContractWrite(){ write, isPending, hash }
useActivity(){ activity, isLoading }
usePortfolioTotal(){ total, isLoading }
useChains() / useSolanaChains()active chains + switchers

useAuth

Sign-in state and sign-out. The full sign-in flow (email OTP / Google) is handled for you by <WalletButton> and <AuthModal> — you rarely call login directly.

import { useAuth } from 'rabitwallet' function Profile() { const { isAuthenticated, user, logout } = useAuth() if (!isAuthenticated) return <p>Signed out</p> return ( <div> <p>{user?.displayName ?? user?.email}</p> <button onClick={() => logout()}>Sign out</button> </div> ) }

useWallet

The active account and addresses. One login yields both an EVM and a Solana address.

import { useWallet } from 'rabitwallet' const { evmAddress, // "0x…" | null solanaAddress, // base58 | null activeAccount, // WalletAccount | null activeChainId, // current chain id | null switchAccount, // (address) => void isReady, // wallet reconstructed & ready isLocked, // true if a PIN is set and not yet entered } = useWallet()

useBalances

Native + token balances for the active chain, as a unified list across EVM and Solana.

import { useBalances } from 'rabitwallet' function Balances() { const { balances, isLoading, refetch } = useBalances() if (isLoading) return <p>Loading…</p> return ( <ul> {balances.map((b) => ( <li key={`${b.ecosystem}-${b.symbol}`}> {b.formatted} {b.symbol} <small>({b.name})</small> </li> ))} <button onClick={() => refetch()}>Refresh</button> </ul> ) }

Each UnifiedBalance has { ecosystem, symbol, name, decimals, address, raw, formatted }.

useSendToken

Send native coins or tokens (ERC-20 / SPL) on the active chain. Pass a balance object from useBalances() as the token.

import { useSendToken, useBalances } from 'rabitwallet' function Send() { const { balances } = useBalances() const { send, isSending, error } = useSendToken() const eth = balances.find((b) => b.symbol === 'ETH') async function onSend() { if (!eth) return const { hash, explorerUrl } = await send({ token: eth, to: '0x000000000000000000000000000000000000dEaD', amount: '0.001', }) console.log('sent', hash, explorerUrl) } return ( <button disabled={isSending} onClick={onSend}> {isSending ? 'Sending…' : 'Send 0.001 ETH'} </button> ) }

useSwap

In-wallet swaps — LiFi on EVM, Jupiter on Solana.

import { useSwap } from 'rabitwallet' const { getQuote, executeSwap, quote, isLoading } = useSwap() await getQuote({ from: 'ETH', to: 'USDC', amount: '0.1' }) if (quote) await executeSwap(quote)

useOnRamp

Fiat on-ramp and off-ramp. See the full walkthrough in On-ramp & off-ramp.

import { useOnRamp } from 'rabitwallet' const { getQuote, buyWithQuote } = useOnRamp() const quote = await getQuote({ fiatAmount: '50', fiatCurrency: 'USD', cryptoAsset: 'USDC', chain: 'evm', paymentMethod: 'card', })

Contract calls

useContractRead / useContractWrite wrap viem for arbitrary EVM contracts, signed by the embedded wallet.

import { useContractRead, useContractWrite } from 'rabitwallet' const { data } = useContractRead({ address: '0x…', abi, functionName: 'balanceOf', args: [addr] }) const { write, isPending } = useContractWrite() await write({ address: '0x…', abi, functionName: 'transfer', args: [to, amount] })