React Hooks for Ethereum providing reactive primitives for wallet connections, smart contract interactions, and blockchain data
—
Contract interaction hooks for reading from and writing to smart contracts with full type safety. This module provides comprehensive functionality for all contract operations including reads, writes, simulation, deployment, and event watching.
Hook to read data from a smart contract function with automatic caching and revalidation.
/**
* Hook to read from a contract
* @param parameters - Contract read parameters with ABI and function details
* @returns Contract read result with query state
*/
function useReadContract<config = Config, selectData = UseReadContractReturnType>(
parameters: UseReadContractParameters<config, selectData>
): UseReadContractReturnType<selectData>;
interface UseReadContractParameters<config = Config, selectData = UseReadContractReturnType> {
/** Contract ABI */
abi: Abi;
/** Contract address */
address: Address;
/** Function name to call */
functionName: string;
/** Function arguments */
args?: readonly unknown[];
/** Account to call from */
account?: Address;
/** Block number to read at */
blockNumber?: bigint;
blockTag?: 'latest' | 'earliest' | 'pending' | 'safe' | 'finalized';
/** Chain to use */
chainId?: config['chains'][number]['id'];
config?: Config | config;
query?: {
enabled?: boolean;
staleTime?: number;
gcTime?: number;
refetchInterval?: number;
select?: (data: UseReadContractReturnType) => selectData;
};
}
type UseReadContractReturnType = unknown;Usage Example:
import { useReadContract } from "wagmi";
import { erc20Abi } from "viem";
function TokenInfo() {
const { data: name } = useReadContract({
abi: erc20Abi,
address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // DAI
functionName: 'name',
});
const { data: balance } = useReadContract({
abi: erc20Abi,
address: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
functionName: 'balanceOf',
args: ['0x742d35Cc6634C0532925a3b8D'],
});
return (
<div>
<p>Token: {name}</p>
<p>Balance: {balance?.toString()}</p>
</div>
);
}Hook to write to a smart contract function with transaction lifecycle management.
/**
* Hook to write to a contract
* @param parameters - Contract write configuration with mutation callbacks
* @returns Contract write mutation with transaction state
*/
function useWriteContract<config = Config, context = unknown>(
parameters?: UseWriteContractParameters<config, context>
): UseWriteContractReturnType<config, context>;
interface UseWriteContractParameters<config = Config, context = unknown> {
config?: Config | config;
mutation?: {
onMutate?: (variables: WriteContractVariables) => Promise<context> | context;
onError?: (error: WriteContractErrorType, variables: WriteContractVariables, context?: context) => Promise<void> | void;
onSuccess?: (data: WriteContractData, variables: WriteContractVariables, context?: context) => Promise<void> | void;
onSettled?: (data?: WriteContractData, error?: WriteContractErrorType, variables?: WriteContractVariables, context?: context) => Promise<void> | void;
};
}
interface UseWriteContractReturnType<config = Config, context = unknown> {
/** Write to contract */
writeContract: (variables: WriteContractVariables, options?: WriteContractMutateOptions) => void;
/** Async version of writeContract */
writeContractAsync: (variables: WriteContractVariables, options?: WriteContractMutateAsyncOptions) => Promise<WriteContractData>;
/** Transaction data */
data?: WriteContractData;
/** Write error */
error: WriteContractErrorType | null;
/** Write status flags */
isError: boolean;
isIdle: boolean;
isPending: boolean;
isSuccess: boolean;
/** Reset write state */
reset: () => void;
/** Current status */
status: 'error' | 'idle' | 'pending' | 'success';
/** Additional variables */
variables?: WriteContractVariables;
}
interface WriteContractVariables {
/** Contract ABI */
abi: Abi;
/** Contract address */
address: Address;
/** Function name to call */
functionName: string;
/** Function arguments */
args?: readonly unknown[];
/** Account to write from */
account?: Address;
/** Chain to use */
chainId?: number;
/** Gas limit */
gas?: bigint;
/** Gas price */
gasPrice?: bigint;
/** Max fee per gas (EIP-1559) */
maxFeePerGas?: bigint;
/** Max priority fee per gas (EIP-1559) */
maxPriorityFeePerGas?: bigint;
/** Nonce */
nonce?: number;
/** Value to send with transaction */
value?: bigint;
}
type WriteContractData = Hash;Usage Example:
import { useWriteContract, useWaitForTransactionReceipt } from "wagmi";
import { erc20Abi } from "viem";
function TransferTokens() {
const { writeContract, data: hash, isPending } = useWriteContract();
const { isLoading: isConfirming, isSuccess: isConfirmed } =
useWaitForTransactionReceipt({
hash,
});
const handleTransfer = () => {
writeContract({
abi: erc20Abi,
address: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
functionName: 'transfer',
args: ['0x742d35Cc6634C0532925a3b8D', 1000000000000000000n], // 1 token
});
};
return (
<div>
<button onClick={handleTransfer} disabled={isPending || isConfirming}>
{isPending ? 'Preparing...' : isConfirming ? 'Confirming...' : 'Transfer'}
</button>
{isConfirmed && <div>Transfer successful!</div>}
</div>
);
}Hook to simulate a contract call before executing it to prevent failed transactions.
/**
* Hook to simulate contract call
* @param parameters - Contract simulation parameters
* @returns Simulation result with gas estimates and return data
*/
function useSimulateContract<config = Config, selectData = UseSimulateContractReturnType>(
parameters: UseSimulateContractParameters<config, selectData>
): UseSimulateContractReturnType<selectData>;
interface UseSimulateContractParameters<config = Config, selectData = UseSimulateContractReturnType> {
/** Contract ABI */
abi: Abi;
/** Contract address */
address: Address;
/** Function name to call */
functionName: string;
/** Function arguments */
args?: readonly unknown[];
/** Account to simulate from */
account?: Address;
/** Block number to simulate at */
blockNumber?: bigint;
blockTag?: 'latest' | 'earliest' | 'pending' | 'safe' | 'finalized';
/** Chain to use */
chainId?: config['chains'][number]['id'];
/** Gas limit for simulation */
gas?: bigint;
/** Gas price */
gasPrice?: bigint;
/** Max fee per gas */
maxFeePerGas?: bigint;
/** Max priority fee per gas */
maxPriorityFeePerGas?: bigint;
/** Nonce */
nonce?: number;
/** Value to send */
value?: bigint;
config?: Config | config;
query?: {
enabled?: boolean;
staleTime?: number;
select?: (data: UseSimulateContractReturnType) => selectData;
};
}
interface UseSimulateContractReturnType {
/** Simulation result */
result: unknown;
/** Request data that can be used with useWriteContract */
request: {
abi: Abi;
address: Address;
functionName: string;
args?: readonly unknown[];
account?: Address;
chainId?: number;
gas?: bigint;
gasPrice?: bigint;
maxFeePerGas?: bigint;
maxPriorityFeePerGas?: bigint;
nonce?: number;
value?: bigint;
};
}Hook to read from multiple contracts in a single request for optimal performance.
/**
* Hook to read from multiple contracts
* @param parameters - Multiple contract read parameters
* @returns Array of contract read results
*/
function useReadContracts<config = Config, selectData = UseReadContractsReturnType>(
parameters: UseReadContractsParameters<config, selectData>
): UseReadContractsReturnType<selectData>;
interface UseReadContractsParameters<config = Config, selectData = UseReadContractsReturnType> {
/** Array of contract calls */
contracts: readonly ContractCall[];
/** Block number to read at */
blockNumber?: bigint;
blockTag?: 'latest' | 'earliest' | 'pending' | 'safe' | 'finalized';
/** Chain to use */
chainId?: config['chains'][number]['id'];
config?: Config | config;
query?: {
enabled?: boolean;
staleTime?: number;
select?: (data: UseReadContractsReturnType) => selectData;
};
}
interface ContractCall {
abi: Abi;
address: Address;
functionName: string;
args?: readonly unknown[];
}
type UseReadContractsReturnType = {
error?: Error;
result?: unknown;
status: 'failure' | 'success';
}[];Hook for paginated contract reads with infinite scroll support.
/**
* Hook to read contracts with pagination
* @param parameters - Infinite contract read parameters
* @returns Paginated contract read results with fetch functions
*/
function useInfiniteReadContracts<config = Config, selectData = UseInfiniteContractReadsReturnType>(
parameters: UseInfiniteContractReadsParameters<config, selectData>
): UseInfiniteContractReadsReturnType<selectData>;
interface UseInfiniteContractReadsParameters<config = Config, selectData = UseInfiniteContractReadsReturnType> {
/** Function to generate contract calls for each page */
contracts: (pageParam: unknown) => readonly ContractCall[];
/** Block number to read at */
blockNumber?: bigint;
blockTag?: 'latest' | 'earliest' | 'pending' | 'safe' | 'finalized';
/** Chain to use */
chainId?: config['chains'][number]['id'];
config?: Config | config;
query?: {
enabled?: boolean;
staleTime?: number;
getNextPageParam?: (lastPage: unknown[], allPages: unknown[][]) => unknown;
select?: (data: UseInfiniteContractReadsReturnType) => selectData;
};
}
interface UseInfiniteContractReadsReturnType<selectData = unknown> {
data?: {
pages: unknown[][];
pageParams: unknown[];
};
error: Error | null;
fetchNextPage: () => void;
hasNextPage?: boolean;
isFetching: boolean;
isFetchingNextPage: boolean;
isLoading: boolean;
isError: boolean;
}Hook to deploy a new smart contract with transaction tracking.
/**
* Hook to deploy a contract
* @param parameters - Contract deployment configuration
* @returns Deploy contract mutation with transaction state
*/
function useDeployContract<config = Config, context = unknown>(
parameters?: UseDeployContractParameters<config, context>
): UseDeployContractReturnType<config, context>;
interface UseDeployContractParameters<config = Config, context = unknown> {
config?: Config | config;
mutation?: {
onMutate?: (variables: DeployContractVariables) => Promise<context> | context;
onError?: (error: DeployContractErrorType, variables: DeployContractVariables, context?: context) => Promise<void> | void;
onSuccess?: (data: DeployContractData, variables: DeployContractVariables, context?: context) => Promise<void> | void;
onSettled?: (data?: DeployContractData, error?: DeployContractErrorType, variables?: DeployContractVariables, context?: context) => Promise<void> | void;
};
}
interface UseDeployContractReturnType<config = Config, context = unknown> {
/** Deploy contract */
deployContract: (variables: DeployContractVariables, options?: DeployContractMutateOptions) => void;
/** Async version of deployContract */
deployContractAsync: (variables: DeployContractVariables, options?: DeployContractMutateAsyncOptions) => Promise<DeployContractData>;
/** Deploy transaction data */
data?: DeployContractData;
/** Deploy error */
error: DeployContractErrorType | null;
/** Deploy status flags */
isError: boolean;
isIdle: boolean;
isPending: boolean;
isSuccess: boolean;
/** Reset deploy state */
reset: () => void;
/** Current status */
status: 'error' | 'idle' | 'pending' | 'success';
/** Additional variables */
variables?: DeployContractVariables;
}
interface DeployContractVariables {
/** Contract ABI */
abi: Abi;
/** Contract bytecode */
bytecode: Hex;
/** Constructor arguments */
args?: readonly unknown[];
/** Account to deploy from */
account?: Address;
/** Chain to deploy to */
chainId?: number;
/** Gas limit */
gas?: bigint;
/** Gas price */
gasPrice?: bigint;
/** Max fee per gas */
maxFeePerGas?: bigint;
/** Max priority fee per gas */
maxPriorityFeePerGas?: bigint;
/** Nonce */
nonce?: number;
/** Value to send with deployment */
value?: bigint;
}
type DeployContractData = Hash;Hook to watch for specific contract events in real-time.
/**
* Hook to watch contract events
* @param parameters - Event watching parameters
* @returns Event watcher that triggers on new events
*/
function useWatchContractEvent<config = Config>(
parameters: UseWatchContractEventParameters<config>
): UseWatchContractEventReturnType;
interface UseWatchContractEventParameters<config = Config> {
/** Contract ABI */
abi: Abi;
/** Contract address */
address: Address;
/** Event name to watch */
eventName: string;
/** Event parameter filters */
args?: Record<string, unknown>;
/** Batch event handling */
batch?: boolean;
/** Chain to watch */
chainId?: config['chains'][number]['id'];
config?: Config | config;
/** Event handler callback */
onLogs: (logs: Log[]) => void;
/** Polling interval in milliseconds */
pollingInterval?: number;
/** Whether to fetch past events */
strict?: boolean;
}
type UseWatchContractEventReturnType = void;
interface Log {
/** Event address */
address: Address;
/** Topics (indexed parameters) */
topics: Hash[];
/** Event data */
data: Hex;
/** Block hash */
blockHash: Hash;
/** Block number */
blockNumber: bigint;
/** Transaction hash */
transactionHash: Hash;
/** Transaction index */
transactionIndex: number;
/** Log index */
logIndex: number;
/** Whether log was removed */
removed: boolean;
}Usage Example:
import { useWatchContractEvent } from "wagmi";
import { erc20Abi } from "viem";
function TransferWatcher() {
useWatchContractEvent({
abi: erc20Abi,
address: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
eventName: 'Transfer',
args: {
from: '0x742d35Cc6634C0532925a3b8D', // Watch transfers from specific address
},
onLogs(logs) {
console.log('New transfers!', logs);
},
});
return <div>Watching for transfers...</div>;
}type Abi = readonly AbiItem[];
interface AbiItem {
type: 'function' | 'event' | 'error' | 'constructor' | 'fallback' | 'receive';
name?: string;
inputs?: AbiParameter[];
outputs?: AbiParameter[];
stateMutability?: 'pure' | 'view' | 'nonpayable' | 'payable';
anonymous?: boolean;
}
interface AbiParameter {
name: string;
type: string;
components?: AbiParameter[];
indexed?: boolean;
}
type Address = `0x${string}`;
type Hash = `0x${string}`;
type Hex = `0x${string}`;
interface ContractCall {
abi: Abi;
address: Address;
functionName: string;
args?: readonly unknown[];
}
interface WriteContractMutateOptions {
onError?: (error: Error, variables: WriteContractVariables, context?: unknown) => void;
onSuccess?: (data: Hash, variables: WriteContractVariables, context?: unknown) => void;
onSettled?: (data?: Hash, error?: Error, variables?: WriteContractVariables, context?: unknown) => void;
}
interface WriteContractMutateAsyncOptions {
onError?: (error: Error, variables: WriteContractVariables, context?: unknown) => void;
onSuccess?: (data: Hash, variables: WriteContractVariables, context?: unknown) => void;
onSettled?: (data?: Hash, error?: Error, variables?: WriteContractVariables, context?: unknown) => void;
}Install with Tessl CLI
npx tessl i tessl/npm-wagmi