VanillaJS library for Ethereum blockchain interactions with reactive primitives and utilities for building Ethereum applications
—
Advanced capabilities including EIP-5792 batch calls, wallet capabilities, code generation utilities, and experimental features.
Query wallet capabilities to understand what features are supported.
/**
* Gets wallet capabilities (EIP-5792)
* @param config - Wagmi configuration
* @param parameters - Capabilities query parameters
* @returns Wallet capabilities
*/
function getCapabilities<config extends Config>(
config: config,
parameters?: GetCapabilitiesParameters<config>
): Promise<GetCapabilitiesReturnType>;
interface GetCapabilitiesParameters<config extends Config> {
/** Account to query capabilities for */
account?: Address;
/** Chain ID */
chainId?: config['chains'][number]['id'];
}
interface GetCapabilitiesReturnType {
[chainId: string]: {
/** Paymaster service support */
paymasterService?: {
supported: boolean;
};
/** Auxiliary funds support */
auxiliaryFunds?: {
supported: boolean;
};
/** Batch transaction support */
atomicBatch?: {
supported: boolean;
};
};
}
type GetCapabilitiesErrorType = BaseErrorType;Usage Example:
import { getCapabilities } from '@wagmi/core'
const capabilities = await getCapabilities(config)
console.log('Wallet capabilities:', capabilities)
// Check if current chain supports batch transactions
const chainId = getChainId(config)
const chainCapabilities = capabilities[chainId.toString()]
if (chainCapabilities?.atomicBatch?.supported) {
console.log('Batch transactions supported!')
}Execute multiple operations in a single atomic transaction.
/**
* Sends batch of calls (EIP-5792)
* @param config - Wagmi configuration
* @param parameters - Batch calls parameters
* @returns Batch call identifier
*/
function sendCalls<config extends Config>(
config: config,
parameters: SendCallsParameters<config>
): Promise<SendCallsReturnType>;
interface SendCallsParameters<config extends Config> {
/** Array of calls to execute */
calls: readonly {
/** Target contract address */
to?: Address;
/** Call data */
data?: Hex;
/** Value to send with call */
value?: bigint;
}[];
/** Chain ID to execute on */
chainId?: config['chains'][number]['id'];
/** Capabilities for the batch */
capabilities?: {
/** Paymaster service configuration */
paymasterService?: {
url: string;
};
/** Auxiliary funds configuration */
auxiliaryFunds?: {
supported: boolean;
};
};
}
type SendCallsReturnType = string; // Batch identifier
/**
* Gets status of batch calls
* @param config - Wagmi configuration
* @param parameters - Status query parameters
* @returns Batch status information
*/
function getCallsStatus<config extends Config>(
config: config,
parameters: GetCallsStatusParameters<config>
): Promise<GetCallsStatusReturnType>;
interface GetCallsStatusParameters<config extends Config> {
/** Batch identifier */
id: string;
/** Chain ID */
chainId?: config['chains'][number]['id'];
}
interface GetCallsStatusReturnType {
/** Batch status */
status: 'PENDING' | 'CONFIRMED';
/** Transaction receipts (if confirmed) */
receipts?: TransactionReceipt[];
}
/**
* Waits for batch calls to complete
* @param config - Wagmi configuration
* @param parameters - Wait parameters
* @returns Final batch status
*/
function waitForCallsStatus<config extends Config>(
config: config,
parameters: WaitForCallsStatusParameters<config>
): Promise<WaitForCallsStatusReturnType>;
interface WaitForCallsStatusParameters<config extends Config> {
/** Batch identifier */
id: string;
/** Chain ID */
chainId?: config['chains'][number]['id'];
/** Polling interval */
pollingInterval?: number;
/** Timeout */
timeout?: number;
}
type WaitForCallsStatusReturnType = GetCallsStatusReturnType;Usage Example:
import {
sendCalls,
waitForCallsStatus,
encodeFunctionData
} from '@wagmi/core'
// Batch multiple token approvals
const batchId = await sendCalls(config, {
calls: [
{
to: '0xTokenA',
data: encodeFunctionData({
abi: erc20Abi,
functionName: 'approve',
args: ['0xSpender', 1000000n],
}),
},
{
to: '0xTokenB',
data: encodeFunctionData({
abi: erc20Abi,
functionName: 'approve',
args: ['0xSpender', 2000000n],
}),
},
],
})
console.log('Batch sent:', batchId)
// Wait for completion
const result = await waitForCallsStatus(config, {
id: batchId,
})
if (result.status === 'CONFIRMED') {
console.log('All approvals confirmed!')
console.log('Receipts:', result.receipts?.length)
}Generate type-safe contract interaction functions.
/**
* Creates typed read contract function
* @param parameters - Read contract creation parameters
* @returns Typed read function
*/
function createReadContract<TAbi extends Abi>(
parameters: CreateReadContractParameters<TAbi>
): CreateReadContractReturnType<TAbi>;
interface CreateReadContractParameters<TAbi extends Abi> {
/** Contract ABI */
abi: TAbi;
/** Contract address or address resolver */
address?: Address | Record<number, Address>;
}
type CreateReadContractReturnType<TAbi extends Abi> = <
TFunctionName extends string
>(
config: Config,
parameters: {
functionName: TFunctionName;
args?: unknown[];
chainId?: number;
}
) => Promise<any>;
/**
* Creates typed write contract function
* @param parameters - Write contract creation parameters
* @returns Typed write function
*/
function createWriteContract<TAbi extends Abi>(
parameters: CreateWriteContractParameters<TAbi>
): CreateWriteContractReturnType<TAbi>;
interface CreateWriteContractParameters<TAbi extends Abi> {
/** Contract ABI */
abi: TAbi;
/** Contract address or address resolver */
address?: Address | Record<number, Address>;
}
type CreateWriteContractReturnType<TAbi extends Abi> = <
TFunctionName extends string
>(
config: Config,
parameters: {
functionName: TFunctionName;
args?: unknown[];
chainId?: number;
}
) => Promise<Hash>;
/**
* Creates typed simulate contract function
* @param parameters - Simulate contract creation parameters
* @returns Typed simulate function
*/
function createSimulateContract<TAbi extends Abi>(
parameters: CreateSimulateContractParameters<TAbi>
): CreateSimulateContractReturnType<TAbi>;
interface CreateSimulateContractParameters<TAbi extends Abi> {
/** Contract ABI */
abi: TAbi;
/** Contract address or address resolver */
address?: Address | Record<number, Address>;
}
type CreateSimulateContractReturnType<TAbi extends Abi> = <
TFunctionName extends string
>(
config: Config,
parameters: {
functionName: TFunctionName;
args?: unknown[];
chainId?: number;
}
) => Promise<{ result: any; request: any }>;
/**
* Creates typed contract event watcher
* @param parameters - Event watcher creation parameters
* @returns Typed event watcher function
*/
function createWatchContractEvent<TAbi extends Abi>(
parameters: CreateWatchContractEventParameters<TAbi>
): CreateWatchContractEventReturnType<TAbi>;
interface CreateWatchContractEventParameters<TAbi extends Abi> {
/** Contract ABI */
abi: TAbi;
/** Contract address or address resolver */
address?: Address | Record<number, Address>;
}
type CreateWatchContractEventReturnType<TAbi extends Abi> = <
TEventName extends string
>(
config: Config,
parameters: {
eventName?: TEventName;
args?: Record<string, any>;
onLogs: (logs: Log[]) => void;
chainId?: number;
}
) => () => void;Usage Example:
import {
createReadContract,
createWriteContract,
createWatchContractEvent
} from '@wagmi/core/codegen'
// Create typed contract functions
const readToken = createReadContract({
abi: erc20Abi,
address: {
1: '0xMainnetTokenAddress',
137: '0xPolygonTokenAddress',
},
})
const writeToken = createWriteContract({
abi: erc20Abi,
address: {
1: '0xMainnetTokenAddress',
137: '0xPolygonTokenAddress',
},
})
const watchToken = createWatchContractEvent({
abi: erc20Abi,
address: {
1: '0xMainnetTokenAddress',
137: '0xPolygonTokenAddress',
},
})
// Use typed functions
const balance = await readToken(config, {
functionName: 'balanceOf',
args: ['0xUserAddress'],
chainId: 1,
})
const transferHash = await writeToken(config, {
functionName: 'transfer',
args: ['0xRecipient', 1000000n],
chainId: 1,
})
const unsubscribe = watchToken(config, {
eventName: 'Transfer',
args: { from: '0xUserAddress' },
onLogs: (logs) => {
console.log('Transfer events:', logs)
},
chainId: 1,
})Add tokens to wallet's watch list.
/**
* Adds token to wallet watch list
* @param config - Wagmi configuration
* @param parameters - Watch asset parameters
* @returns Success status
*/
function watchAsset<config extends Config>(
config: config,
parameters: WatchAssetParameters<config>
): Promise<WatchAssetReturnType>;
interface WatchAssetParameters<config extends Config> {
/** Asset type (always 'ERC20' for tokens) */
type: 'ERC20';
/** Token contract address */
address: Address;
/** Token symbol */
symbol: string;
/** Token decimals */
decimals: number;
/** Token icon URL */
image?: string;
/** Chain ID */
chainId?: config['chains'][number]['id'];
}
type WatchAssetReturnType = boolean;
type WatchAssetErrorType =
| BaseErrorType
| UserRejectedRequestErrorType;Usage Example:
import { watchAsset } from '@wagmi/core'
const added = await watchAsset(config, {
type: 'ERC20',
address: '0xA0b86a33E6411c0B7f8C4b5d3e1B9d3e8b4a4e6f',
symbol: 'CUSTOM',
decimals: 18,
image: 'https://example.com/token-icon.png',
})
if (added) {
console.log('Token added to wallet!')
} else {
console.log('User declined to add token')
}Create custom wallet connectors for specialized connection methods.
/**
* Creates a custom connector
* @param connectorFn - Connector implementation function
* @returns Custom connector function
*/
function createConnector<TProvider, TOptions = any>(
connectorFn: CreateConnectorFn<TProvider, TOptions>
): CreateConnectorFn<TProvider, TOptions>;
interface CreateConnectorFn<TProvider = any, TOptions = any> {
(options?: TOptions): (config: Config) => Connector<TProvider>;
}
interface Connector<TProvider = any> {
/** Unique connector ID */
id: string;
/** Display name */
name: string;
/** Connector type */
type: string;
/** Connector icon URL */
icon?: string;
/** Reverse Domain Name System identifier */
rdns?: string | readonly string[];
/** Setup function called once */
setup?(): Promise<void>;
/** Connect to wallet */
connect(parameters?: {
chainId?: number;
isReconnecting?: boolean;
}): Promise<{
accounts: readonly Address[];
chainId: number;
}>;
/** Disconnect from wallet */
disconnect(): Promise<void>;
/** Get connected accounts */
getAccounts(): Promise<readonly Address[]>;
/** Get current chain ID */
getChainId(): Promise<number>;
/** Get provider instance */
getProvider(): Promise<TProvider>;
/** Check if authorized */
isAuthorized(): Promise<boolean>;
/** Switch chain (optional) */
switchChain?(parameters: { chainId: number }): Promise<Chain>;
/** Event handlers */
onAccountsChanged?(accounts: string[]): void;
onChainChanged?(chainId: string | number): void;
onConnect?(connectInfo: { chainId: string | number }): void;
onDisconnect?(error?: { code: number; message: string }): void;
onMessage?(message: { type: string; data?: any }): void;
}Usage Example:
import { createConnector } from '@wagmi/core'
// Create a custom WebSocket-based connector
const webSocketConnector = createConnector((config) => ({
id: 'websocket-wallet',
name: 'WebSocket Wallet',
type: 'webSocket',
async setup() {
// Initialize WebSocket connection
this.ws = new WebSocket('wss://wallet.example.com')
},
async connect() {
if (!this.ws) await this.setup()
// Send connection request
this.ws.send(JSON.stringify({ type: 'connect' }))
// Wait for response
return new Promise((resolve, reject) => {
this.ws.onmessage = (event) => {
const data = JSON.parse(event.data)
if (data.type === 'connected') {
resolve({
accounts: data.accounts,
chainId: data.chainId,
})
} else if (data.type === 'error') {
reject(new Error(data.message))
}
}
})
},
async disconnect() {
if (this.ws) {
this.ws.send(JSON.stringify({ type: 'disconnect' }))
this.ws.close()
}
},
async getAccounts() {
// Implementation
return []
},
async getChainId() {
// Implementation
return 1
},
async getProvider() {
return this.ws
},
async isAuthorized() {
return this.ws?.readyState === WebSocket.OPEN
},
}))
// Use custom connector
const config = createConfig({
connectors: [webSocketConnector()],
// ... other config
})Configure advanced transport options.
/**
* Fallback transport that tries multiple transports in order
* @param transports - Array of transports to try
* @param config - Fallback configuration
* @returns Fallback transport
*/
function fallback<TTransport extends Transport>(
transports: TTransport[],
config?: FallbackConfig
): FallbackTransport<TTransport>;
interface FallbackConfig {
/** Number of times to retry */
retryCount?: number;
/** Delay between retries in ms */
retryDelay?: number;
/** Rank transports by priority */
rank?: boolean;
}
/**
* Unstable connector transport (experimental)
* @param config - Connector transport configuration
* @returns Connector transport
*/
function unstable_connector(config: ConnectorTransportConfig): ConnectorTransport;
interface ConnectorTransportConfig {
/** Connector to use for transport */
connector: Connector;
}Usage Example:
import { fallback, http, webSocket, unstable_connector } from '@wagmi/core'
const config = createConfig({
chains: [mainnet, polygon],
transports: {
[mainnet.id]: fallback([
http('https://eth-mainnet.alchemyapi.io/v2/...'), // Primary
http('https://mainnet.infura.io/v3/...'), // Fallback 1
http(), // Public RPC fallback
], {
retryCount: 3,
retryDelay: 1000,
}),
[polygon.id]: webSocket('wss://polygon-rpc.com'),
},
})
// Using connector transport (experimental)
const configWithConnectorTransport = createConfig({
chains: [mainnet],
transports: {
[mainnet.id]: unstable_connector({
connector: injected(),
}),
},
})Install with Tessl CLI
npx tessl i tessl/npm-wagmi--core