Hooks Reference
Complete reference for all React hooks exported by @kevo-ws/sdk/react. All hooks must be used inside a KevoProvider.
{ fn, isLoading, error }.error is reset to null on each new invocation. No walletId is needed — the SDK uses the authenticated user's wallet automatically.useKevoModal
Controls the visibility of the sign-in modal.
const { open, close, isOpen } = useKevoModal()| Prop | Type | Description |
|---|---|---|
open | () => void | Opens the sign-in modal. |
close | () => void | Closes the modal. |
isOpen | boolean | Whether the modal is currently visible. |
useKevoDashboard
Controls the visibility of the settings/dashboard overlay.
const { open, close, isOpen } = useKevoDashboard()| Prop | Type | Description |
|---|---|---|
open | () => void | Opens the dashboard overlay. |
close | () => void | Closes the overlay. |
isOpen | boolean | Whether the overlay is currently visible. |
useKevo
Primary hook for session state, auth methods, and delegation management. Replaces the old useSession / useKevoClient pattern.
const {
client, // KevoClient instance
session, // KevoSession | null
isAuthenticated, // boolean
isLoading, // boolean (true during initial restore)
userProfile, // KevoResolvedUserProfile
rawUserProfile, // KevoUserProfile | null
enabledChains, // SupportedChain[] (e.g. ['evm', 'solana'])
projectConfig, // KevoProjectConfig | null
logout, // () => Promise<void>
sendEmailOtp, // (email: string) => Promise<void>
verifyEmailOtp, // (email: string, code: string) => Promise<void>
loginWithGoogle, // () => void — opens Google OAuth popup
loginWithX, // () => void — opens X (Twitter) OAuth popup
loginWithApple, // () => void — opens Apple OAuth popup
getDelegation, // () => Promise<KevoDelegation | null>
grantDelegation, // (opts?: GrantDelegationOptions) => Promise<KevoDelegation>
revokeDelegation, // () => Promise<void>
} = useKevo()useUserProfile
Returns a normalized profile for display plus the raw API profile. Kevo always uses the wallet address as the primary display name, shows provider username/name when available, and falls back to a deterministic generated avatar if the provider does not return one.
const {
profile, // KevoResolvedUserProfile
rawProfile, // KevoUserProfile | null
refresh, // () => Promise<KevoUserProfile | null>
requestEmailLink, // (email: string) => Promise<void>
confirmEmailLink, // (email: string, code: string) => Promise<void>
} = useUserProfile()
return (
<div>
<img src={profile.avatarUrl} alt="" />
<span>{profile.name}</span> {/* wallet address, shortened */}
{profile.username && <small>{profile.username}</small>}
</div>
)| Prop | Type | Description |
|---|---|---|
profile | KevoResolvedUserProfile | Display-safe profile with name, username, avatarUrl, address, and raw profile. |
rawProfile | KevoUserProfile | null | Raw user object returned by Kevo, including email and authMethods. |
refresh | () => Promise<KevoUserProfile | null> | Reloads the current user profile from the API. |
requestEmailLink | (email: string) => Promise<void> | Sends an OTP so the signed-in user can link an email. |
confirmEmailLink | (email: string, code: string) => Promise<void> | Verifies the OTP and links the email to the current account. |
requestEmailLink and confirmEmailLink when an email is needed for OTP-gated export.useWallets
Returns the user's EVM and Solana wallets. The wallet is created automatically after first authentication — no manual creation needed.
const { evmWallet, solanaWallet, enabledChains, isLoading } = useWallets()
// evmWallet: KevoWallet | null — { address: '0x...', id, createdAt }
// solanaWallet: KevoSolanaWallet | null — { address: 'Base58...', id, createdAt }| Prop | Type | Description |
|---|---|---|
evmWallet | KevoWallet | null | The user's embedded EVM wallet, or null if not yet created / chain not enabled. |
solanaWallet | KevoSolanaWallet | null | The user's embedded Solana wallet, or null. |
enabledChains | SupportedChain[] | Project's enabled chains. |
isLoading | boolean | True while wallets are being loaded. |
useWallet() returns { wallet, isLoading } (EVM only) and useSolanaWallet() returns { solanaWallet, isLoading }.useChain
Manages the active EVM chain when multiple chains are configured via KevoConfig.chains. Switching chain triggers a re-render of all chain-aware hooks (useBalance, useTokenBalance).
const { activeChainId, setChain, chains, rpcUrl } = useChain()
// Switch to Base
setChain(8453)
// Render a chain selector
Object.keys(chains).map(id => (
<button key={id} onClick={() => setChain(Number(id))}>
Chain {id}
</button>
))| Prop | Type | Description |
|---|---|---|
activeChainId | number | null | Currently active EVM chain ID. Null if KevoConfig.chains is not set. |
setChain | (chainId: number) => void | Switch the active EVM chain. Throws if chainId is not in KevoConfig.chains. |
chains | Record<number, string> | Full chains map from KevoConfig.chains. |
rpcUrl | string | null | RPC URL for the currently active chain. |
useSignMessage
Chain-aware message signing. Auto-routes to EVM or Solana based on project config. For multi-chain projects, pass { chain: 'solana' } to override.
const { signMessage, isLoading, error } = useSignMessage()
// Single-chain project — just works:
const sig = await signMessage('Hello from Kevo!')
// Multi-chain project — specify chain:
const sig = await signMessage('Hello', { chain: 'solana' })| Prop | Type | Description |
|---|---|---|
signMessage | (message: string, options?: { chain?: SupportedChain }) => Promise<string> | Signs the message. Returns hex signature. |
isLoading | boolean | True while signing. |
error | Error | null | Last error, if any. |
useSignSolanaMessage
Explicit Solana message signing — for raw byte signing or fine-grained control.
const { signSolanaMessage, isLoading, error } = useSignSolanaMessage()
// Accepts string or Uint8Array
const sigHex = await signSolanaMessage('Hello Solana!')
const sigHex = await signSolanaMessage(new Uint8Array([1, 2, 3]))| Prop | Type | Description |
|---|---|---|
signSolanaMessage | (message: string | Uint8Array) => Promise<string> | Signs with Ed25519. Returns 64-byte signature as hex. |
isLoading | boolean | True while signing. |
error | Error | null | Last error, if any. |
useSignTypedData
Signs EIP-712 structured data with the user's EVM wallet.
const { signTypedData, isLoading, error } = useSignTypedData()
const sig = await signTypedData({
domain: { name: 'MyApp', version: '1', chainId: 1 },
types: { MyType: [{ name: 'value', type: 'uint256' }] },
primaryType: 'MyType',
message: { value: 42 },
})| Prop | Type | Description |
|---|---|---|
signTypedData | (data: Eip712TypedData) => Promise<string> | Signs EIP-712 data. Returns hex signature. |
isLoading | boolean | True while signing. |
error | Error | null | Last error, if any. |
useSignTransaction
Sign and/or broadcast EVM transactions. Returns both signTransaction (sign only) and sendTransaction (sign + auto-fill + broadcast).
sendTransaction automatically fills missing nonce, gasLimit, maxFeePerGas, and maxPriorityFeePerGas from the RPC. You can override any field explicitly.
const { signTransaction, sendTransaction, isLoading, error } = useSignTransaction()
// Sign only (returns raw signed tx hex):
const rawTx = await signTransaction({ to: '0x...', value: 0n, chainId: 1 })
// Sign + auto-fill + broadcast (returns tx hash):
const txHash = await sendTransaction({
to: '0xRecipient',
value: 1_000_000_000_000_000n,
chainId: 1,
})
// With calldata for smart contract calls:
const txHash = await sendTransaction({
to: '0xContractAddress',
data: '0xa9059cbb000000...', // calldata
chainId: 1,
})
// Override specific fields (nonce, gas, fees):
const txHash = await sendTransaction({
to: '0xRecipient',
value: 0n,
chainId: 1,
nonce: 42,
gasLimit: 500_000n,
maxFeePerGas: '0x3B9ACA00',
})
// Optional rpcUrl override (falls back to evmRpcUrl from config):
const txHash = await sendTransaction(tx, 'https://custom-rpc.com')| Prop | Type | Description |
|---|---|---|
signTransaction | (tx: TransactionRequest) => Promise<string> | Signs without broadcasting. Returns raw signed tx hex. |
sendTransaction | (tx: TransactionRequest, rpcUrl?: string) => Promise<string> | Signs, auto-fills nonce/gas/fees, and broadcasts. Returns tx hash. |
isLoading | boolean | True while signing/broadcasting. |
error | Error | null | Last error, if any. |
useSignSolanaTransaction
Sign and/or broadcast Solana transactions. sendSolanaTransaction signs, assembles the wire-format transaction, and broadcasts in one call.
const { signSolanaTransaction, sendSolanaTransaction, isLoading, error } = useSignSolanaTransaction()
// Sign only (returns Ed25519 signature hex):
const sigHex = await signSolanaTransaction(messageBytes)
// Sign + assemble + broadcast (returns base58 tx signature):
const txSig = await sendSolanaTransaction(messageBytes)
// Optional rpcUrl override:
const txSig = await sendSolanaTransaction(messageBytes, 'https://api.devnet.solana.com')| Prop | Type | Description |
|---|---|---|
signSolanaTransaction | (txBytes: Uint8Array) => Promise<string> | Signs the message bytes. Returns Ed25519 signature as hex. |
sendSolanaTransaction | (txBytes: Uint8Array, rpcUrl?: string) => Promise<string> | Signs, assembles, and broadcasts. Returns base58 tx signature. |
isLoading | boolean | True while signing/broadcasting. |
error | Error | null | Last error, if any. |
useEstimateGas
Estimates gas for an EVM transaction via the configured RPC.
const { estimateGas, isLoading, error } = useEstimateGas()
const gas: bigint = await estimateGas({
to: '0xRecipient',
value: '0x16345785D8A0000',
chainId: 1,
})| Prop | Type | Description |
|---|---|---|
estimateGas | (tx: TransactionRequest, rpcUrl?: string) => Promise<bigint> | Returns estimated gas units as bigint. |
isLoading | boolean | True while estimating. |
error | Error | null | Last error, if any. |
useBalance
Fetches and auto-refreshes the native ETH balance. Polls every 15 seconds by default.
const { balance, isLoading, error, refetch } = useBalance()
// balance: bigint | null (wei), null if not yet fetched
// Example: display in ETH
const ethDisplay = balance !== null
? (Number(balance) / 1e18).toFixed(6) + ' ETH'
: 'Loading…'
// Optional: custom RPC and poll interval
const { balance } = useBalance('https://custom-rpc.com', 30_000)
// Disable auto-polling
const { balance, refetch } = useBalance(undefined, 0)| Prop | Type | Description |
|---|---|---|
balance | bigint | null | Balance in wei, or null if not yet fetched. |
isLoading | boolean | True while fetching. |
error | Error | null | Fetch error, if any. |
refetch | () => Promise<void> | Manually trigger a balance refresh. |
useTokenBalance
Fetches and auto-refreshes an ERC-20 token balance.
const { balance, isLoading, error, refetch } = useTokenBalance(
'0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' // USDC
)
// balance: bigint | null (smallest unit)
// For USDC (6 decimals): Number(balance) / 1e6| Prop | Type | Description |
|---|---|---|
balance | bigint | null | Token balance in smallest unit, or null. |
isLoading | boolean | True while fetching. |
error | Error | null | Fetch error, if any. |
refetch | () => Promise<void> | Manually trigger a refresh. |
useSolanaBalance
Fetches and auto-refreshes the native SOL balance.
const { balance, isLoading, error, refetch } = useSolanaBalance()
// balance: bigint | null (lamports)
// Display in SOL: (Number(balance) / 1e9).toFixed(6) + ' SOL'| Prop | Type | Description |
|---|---|---|
balance | bigint | null | Balance in lamports, or null. |
isLoading | boolean | True while fetching. |
error | Error | null | Fetch error, if any. |
refetch | () => Promise<void> | Manually trigger a refresh. |
useExportKey / useSolanaExportKey
Two-step private key export. Step 1: request OTP. Step 2: verify OTP and the key is displayed securely inside the Kevo iframe (never returned to your app).
const { requestExport, confirmExport, isLoading } = useExportKey()
// or for Solana:
const { requestExport, confirmExport, isLoading } = useSolanaExportKey()
// Step 1: returns masked email (e.g. "a***@example.com")
const maskedEmail = await requestExport()
// Step 2: verify OTP — key shown in iframe
await confirmExport('123456')| Prop | Type | Description |
|---|---|---|
requestExport | () => Promise<string> | Sends OTP email. Returns masked email address. |
confirmExport | (otpCode: string) => Promise<void> | Verifies OTP. Key is shown in secure iframe. |
isLoading | boolean | True during either step. |
error | Error | null | Last error, if any. |
useUserProfile().