Hook
useSmartRetry
Retries asynchronous Solana operations with configurable backoff and error handling.
Installation
terminal
$npx shadcn@latest add https://uxdotsol.xyz/r/use-smart-retry.jsonUsage
use-smart-retry.tsx
"use client"; import { useState } from "react";import { address, createSolanaRpc,} from "@solana/kit";import { useSmartRetry } from "@/hooks/uxdotsol/use-smart-retry"; export function SolBalanceRefresh({ endpoint, owner,}: { endpoint: string; owner: string;}) { const rpc = createSolanaRpc(endpoint); const [balance, setBalance] = useState<bigint | null>(null); const retry = useSmartRetry<bigint>({ client: rpc, maxAttempts: 4 }); async function refreshBalance() { setBalance(null); try { const lamports = await retry.execute(async () => { const { value } = await rpc .getBalance(address(owner), { commitment: "confirmed" }) .send(); return value; }); setBalance(lamports); } catch { // The hook exposes the final error for the UI. } } return ( <section> <p> SOL balance:{" "} {balance === null ? "Not loaded" : (Number(balance) / 1_000_000_000).toFixed(4)} </p> <button disabled={retry.isRetrying} onClick={refreshBalance}> {retry.isRetrying ? `RPC busy, retrying (${retry.attempt}/4)...` : "Refresh balance"} </button> {!retry.isRetrying && retry.error && balance === null ? ( <p role="alert">Could not reach the Solana RPC.</p> ) : null} </section> );}Options
| Name | Type | Default | Description |
|---|---|---|---|
| maxAttempts | number | 4 | Maximum operation attempts before surfacing the error. |
| refreshBlockhash | () => Promise<unknown> | undefined | Optional callback used when a stale blockhash error is detected. |
| baseDelayMs / maxDelayMs | number | 400 / 6000 | Exponential backoff delay bounds. |
| shouldRetry | (error, attempt, decision) => boolean | decision.retryable | Override for retry decisions after Solana error classification. |
| onAttempt / onRetry / onSuccess / onFailure | callbacks | undefined | Lifecycle callbacks for telemetry or UI updates. |
Functions
| Name | Type | Default | Description |
|---|---|---|---|
| execute | (operation: (attempt: number) => Promise<T>, override?: Partial<SmartRetryOptions<T>>) => Promise<T> | - | Runs an async operation with retry behavior. |
| cancel | () => void | - | Stops future retry attempts. |
| classifySolanaRetry | (error: unknown) => SmartRetryDecision | - | Classifies blockhash, rate-limit, node, simulation, and transport errors. |
Types
| Name | Type | Default | Description |
|---|---|---|---|
| SolanaRetryReason | 'blockhash-expired' | 'rate-limited' | 'node-unhealthy' | 'simulation-failed' | 'transport' | 'unknown' | - | Known retry reason categories. |
| SmartRetryDecision | { reason; retryable; refreshBlockhash } | - | Classifier output used by retry logic. |
Returns
| Name | Type | Default | Description |
|---|---|---|---|
| isRetrying / attempt | boolean / number | false / 0 | Current retry activity and attempt count. |
| error | unknown | null | Last caught operation error. |

