@awarizon/react
React hooks built on the core SDK. Manages loading states, re-fetching, and cleanup automatically. Requires React 18+.
AwarizonProvider
Wraps your component tree and makes the SDK available to every hook inside it.
"use client" import { AwarizonProvider } from "@awarizon/react" import { AwarizonWeb3 } from "@awarizon/web3" const awarizon = new AwarizonWeb3({ chain: "base", apiKey: process.env.NEXT_PUBLIC_AWARIZON_API_KEY!, walletConnectProjectId: process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID, }) export function Providers({ children }: { children: React.ReactNode }) { return <AwarizonProvider awarizon={awarizon}>{children}</AwarizonProvider> }
awarizonAwarizonWeb3REQPre-configured SDK instance.childrenReactNodeREQThe component subtree that can access SDK hooks.ConnectButton
A fully self-contained wallet connect / account button. Auto-detects MetaMask, Rabby, Brave, Coinbase Wallet, and Phantom. Shows WalletConnect QR when walletConnectProjectId is set.
import { ConnectButton } from "@awarizon/react" // Zero-config — default styling <ConnectButton /> // Custom label <ConnectButton label="Sign In" /> // Custom Tailwind class <ConnectButton className="rounded-full bg-indigo-600 px-5 py-2 text-white text-sm font-medium" /> // Full render prop — you control the entire UI <ConnectButton> {({ isConnected, address, connect, disconnect, isConnecting }) => isConnected ? ( <button onClick={disconnect}> {address?.slice(0, 6)}…{address?.slice(-4)} </button> ) : ( <button onClick={connect} disabled={isConnecting}> {isConnecting ? "Connecting…" : "Connect Wallet"} </button> ) } </ConnectButton>
labelstringButton text when disconnected. Default: "Connect Wallet".classNamestringCSS class. When set, all default styles are removed.styleCSSPropertiesInline style override.childrenfn(props)Render prop — receive { isConnected, isConnecting, address, connectorName, connect, disconnect } and return your own JSX.ConnectModal
The wallet selection modal rendered by ConnectButton. Use it standalone to trigger the connect flow from your own button.
import { ConnectModal } from "@awarizon/react" import { useState } from "react" function Header() { const [open, setOpen] = useState(false) return ( <> <button onClick={() => setOpen(true)}>Connect</button> {open && <ConnectModal onClose={() => setOpen(false)} />} </> ) }
AccountModal
The mini account popup shown when connected. Displays chain logo, wallet address with one-click copy, live native token balance (polls every 15 s), and a disconnect button.
import { AccountModal, useWallet } from "@awarizon/react" import { useState } from "react" function AccountButton() { const { address, chainId, isConnected, disconnect } = useWallet() const [open, setOpen] = useState(false) if (!isConnected) return null return ( <div style={{ position: "relative", display: "inline-block" }}> <button onClick={() => setOpen(v => !v)}> {address?.slice(0, 6)}…{address?.slice(-4)} </button> {open && ( <AccountModal address={address!} chainId={chainId} onClose={() => setOpen(false)} onDisconnect={() => { disconnect(); setOpen(false) }} /> )} </div> ) }
addressAddressREQThe connected wallet address to display.chainIdnumber|nullActive chain ID — used to show the chain logo and name.onClose() => voidREQCalled when the user clicks outside the popup.onDisconnect() => voidREQCalled when the user clicks the Disconnect button.useWallet
Manage wallet state reactively. Reacts to connect, disconnect, account switches, and chain changes automatically — including when the user acts in their wallet app without interacting with your UI.
import { useWallet } from "@awarizon/react" function WalletPanel() { const { address, // Address | null isConnected, // boolean isLoading, // true during async wallet operations error, // Error | null chainId, // number | null isChainMismatch, // true when wallet is on a different chain than the SDK connectorInfo, // { type, name?, icon? } create, // () => Promise<CreatedWallet> importMnemonic, // (phrase, accountIndex?) => Promise<void> importPrivateKey, // (key) => Promise<void> connect, // (walletClient, info?) => void disconnect, // () => void signMessage, // (msg) => Promise<Hex> } = useWallet() if (isChainMismatch) return <p>Wrong network — please switch in your wallet</p> if (!isConnected) return <button onClick={create}>Create Wallet</button> return ( <div> <p>{address}</p> <button onClick={disconnect}>Disconnect</button> </div> ) }
addressAddress | nullActive wallet address, or null when no wallet is connected.isConnectedbooleanTrue when any wallet (internal or external) is active.isLoadingbooleanTrue during create, import, or connect operations.errorError | nullLast wallet operation error. Cleared on the next success.chainIdnumber | nullChain ID the external wallet is currently on.isChainMismatchbooleanTrue when the external wallet is on a different chain than the SDK config.connectorInfoConnectorInfo{ type, name?, icon? } — how the wallet is connected.create() => PromiseGenerate a fresh wallet keypair and activate it.importMnemonicfn(phrase, index?) → restore from a BIP-39 mnemonic.importPrivateKeyfn(key) → load from a hex private key.connectfn(walletClient, info?) → inject an external WalletClient.disconnect() => voidClear wallet state.signMessagefn(message | { raw }) → sign a plain text or raw-bytes message. Returns Hex.contract() — Simplified Contract Binding
Create a contract reference once at module level. Eliminates repeating address, abi, and method strings across every hook call — works for any contract (ERC-20, DAO, staking, NFT minting, etc.).
import { contract } from "@awarizon/react" import { ERC20_ABI } from "@awarizon/web3" // ── Define once (module level, outside any component) ───────────────────────── const USDC = contract("0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", ERC20_ABI) // ── DAO / Governance ────────────────────────────────────────────────────────── const DAO = contract("0x...", DAO_ABI) // ── Staking contract ────────────────────────────────────────────────────────── const STAKING = contract("0x...", STAKING_ABI) // ── NFT collection ──────────────────────────────────────────────────────────── const NFT = contract("0x...", NFT_ABI)
TOKEN.name()CallDescriptorCall with args → returns a descriptor for useRead(). No args = empty array.TOKEN.balanceOf(userAddress)CallDescriptorPass args inline — re-runs when args change thanks to useRead's dep tracking.TOKEN.transfer (un-called)BoundMethodPass without calling to useWrite(). Args are supplied at write() call time.useRead()
Reactive read hook. Pair with contract() — pass a bound method call to avoid repeating address/abi/method on every hook.
import { contract, useRead } from "@awarizon/react" import { ERC20_ABI, DAO_ABI, STAKING_ABI, NFT_ABI } from "@awarizon/web3" const USDC = contract("0x833589...", ERC20_ABI) const DAO = contract("0x...", DAO_ABI) const STAKING = contract("0x...", STAKING_ABI) const NFT = contract("0x...", NFT_ABI) function Dashboard({ user }: { user: `0x${string}` }) { // ERC-20 const { data: name } = useRead(USDC.name()) const { data: symbol } = useRead(USDC.symbol()) const { data: balance, isLoading } = useRead(USDC.balanceOf(user), { pollingInterval: 10_000 }) // DAO const { data: proposalCount } = useRead(DAO.proposalCount()) const { data: quorum } = useRead(DAO.quorumVotes()) // Staking const { data: staked } = useRead(STAKING.balanceOf(user)) const { data: earned } = useRead(STAKING.earned(user), { pollingInterval: 12_000 }) // NFT const { data: supply } = useRead(NFT.totalSupply()) const { data: price } = useRead(NFT.mintPrice()) if (isLoading) return <p>Loading…</p> return <p>{name} ({symbol}): {balance?.toString()}</p> }
callCallDescriptorREQDescriptor from a bound method call: TOKEN.balanceOf(user).options.pollingIntervalnumberAuto-refresh interval in ms. Omit to fetch once on mount.dataT | nullThe return value of the contract function.isLoadingbooleanTrue on initial load.isFetchingbooleanTrue on every refetch (including polling).errorError | nullError from the last call.refetch() => Promise<void>Manually trigger a re-fetch.useWrite()
Write hook. Pass a bound method (un-called) — args are supplied when you actually call write(). Works for any write function: ERC-20 transfers, DAO votes, NFT minting, staking deposits, etc.
import { contract, useRead, useWrite } from "@awarizon/react" const USDC = contract("0x833589...", ERC20_ABI) const DAO = contract("0x...", DAO_ABI) const STAKING = contract("0x...", STAKING_ABI) const NFT = contract("0x...", NFT_ABI) function Actions({ user }: { user: `0x${string}` }) { // Token const { write: transfer, isLoading: sending } = useWrite(USDC.transfer) // DAO const { write: vote, isLoading: voting } = useWrite(DAO.castVote) const { write: propose, isLoading: proposing } = useWrite(DAO.propose) // Staking const { write: stake, isLoading: staking } = useWrite(STAKING.stake) const { write: claim, isLoading: claiming } = useWrite(STAKING.getReward) // NFT mint (payable — pass value in last arg) const { data: price } = useRead(NFT.mintPrice()) const { write: mint, isLoading: minting } = useWrite(NFT.mint) return ( <div> <button onClick={() => transfer(recipient, 100n)} disabled={sending}> Send USDC </button> <button onClick={() => vote(proposalId, 1)} disabled={voting}> Vote For </button> <button onClick={() => stake(parseUnits("100", 18))} disabled={staking}> Stake </button> <button onClick={() => claim()} disabled={claiming}> Claim Rewards </button> <button onClick={() => mint(1n, { value: price ?? 0n })} disabled={minting}> Mint NFT </button> </div> ) }
write(...args) => Promise<TransactionResult>Call with the ABI args to execute the transaction.isLoadingbooleanTrue while the transaction is being submitted.isSuccessbooleanTrue after a successful transaction.resultTransactionResult | nullTransaction hash and receipt after success.errorError | nullError if the transaction failed.reset() => voidClear all state back to idle.useContract
Returns the raw ContractInstance for event subscriptions or advanced imperative use.
import { useEffect } from "react" import { useContract } from "@awarizon/react" function TransferFeed() { const { contract } = useContract({ address: "0xToken", abi: ERC20_ABI }) useEffect(() => { if (!contract) return const unsub = contract.on("Transfer", (log) => { console.log("Transfer:", log.args) }) return unsub // unsubscribe on unmount }, [contract]) return null }
useToken
Zero-ABI hook for ERC-20 tokens. Fetches name, symbol, decimals, and total supply on mount.
import { useToken } from "@awarizon/react" function TokenCard({ address }: { address: `0x${string}` }) { const { name, symbol, decimals, totalSupply, isLoading, error, balanceOf, transfer, approve, } = useToken(address) const [balance, setBalance] = useState<bigint | null>(null) useEffect(() => { balanceOf(userAddress).then(setBalance) }, [balanceOf]) if (isLoading) return <span>Loading…</span> return ( <div> <p>{name} ({symbol}) — {decimals} decimals</p> <p>Balance: {balance?.toString()}</p> <button onClick={() => transfer(recipient, 1_000_000n)}> Send 1 {symbol} </button> </div> ) }
useNFT
Zero-ABI hook for ERC-721 collections. Loads collection name and symbol on mount. Exposes all standard ownership and transfer helpers.
import { useNFT } from "@awarizon/react" function NFTCard({ address, tokenId }: { address: `0x${string}`; tokenId: bigint }) { const { name, symbol, ownerOf, tokenURI, safeTransferFrom, isLoading } = useNFT(address) const [owner, setOwner] = useState<string | null>(null) const [uri, setUri] = useState<string | null>(null) useEffect(() => { Promise.all([ownerOf(tokenId), tokenURI(tokenId)]) .then(([o, u]) => { setOwner(o); setUri(u) }) }, [tokenId, ownerOf, tokenURI]) if (isLoading) return <span>Loading collection…</span> return ( <div> <p>{name} #{tokenId.toString()} ({symbol})</p> <img src={uri ?? ''} alt="NFT" /> <button onClick={() => safeTransferFrom(owner!, recipient, tokenId)}>Transfer</button> </div> ) }
useNativeBalance
Fetch the native currency balance (ETH, MATIC, BNB…) for any address. Pass a pollingInterval in ms to keep it live.
import { useNativeBalance } from "@awarizon/react" function WalletBalance({ address }: { address: `0x${string}` }) { // Polls every 12 s — matches Ethereum's ~12 s block time const { formatted, balance, isLoading, refetch } = useNativeBalance(address, 12_000) if (isLoading) return <span>Loading…</span> return ( <div> <p>{formatted} ETH</p> {/* "1.2345" — human-readable */} <p>{balance?.toString()} wei</p> {/* raw bigint */} <button onClick={refetch}>Refresh</button> </div> ) }
Chain Icons & Metadata
Helper functions that map chain IDs to icons, human-readable names, and native currency symbols. Used internally by AccountModal and ConnectButton.
import { getChainIcon, getChainName, getChainNativeSymbol } from "@awarizon/react" getChainIcon(1) // "https://awarizon.com/eth.png" getChainIcon(8453) // "https://awarizon.com/base.png" getChainIcon(99999) // undefined — unknown chain getChainName(1) // "Ethereum" getChainName(8453) // "Base" getChainName(99999) // "Chain 99999" — fallback getChainNativeSymbol(1) // "ETH" getChainNativeSymbol(56) // "BNB" getChainNativeSymbol(137) // "POL" getChainNativeSymbol(43114) // "AVAX"
1Ethereum56BNB Chain137Polygon42161Arbitrum One10Optimism43114Avalanche8453Base2020Ronin146Sonic7000ZetaChain80094Berachain33139ApeChain