# Public Client [A function to create a Public Client] A Public Client is an interface to "public" [JSON-RPC API](https://ethereum.org/en/developers/docs/apis/json-rpc/) methods such as retrieving block numbers, transactions, reading from smart contracts, etc through [Public Actions](/docs/actions/public/introduction). The `createPublicClient` function sets up a Public Client with a given [Transport](/docs/clients/intro) configured for a [Chain](/docs/chains/introduction). ## Import ```ts twoslash import { createPublicClient } from 'viem' ``` ## Usage Initialize a Client with your desired [Chain](/docs/chains/introduction) (e.g. `mainnet`) and [Transport](/docs/clients/intro) (e.g. `http`). ```ts twoslash import { createPublicClient, http } from 'viem' import { mainnet } from 'viem/chains' const publicClient = createPublicClient({ chain: mainnet, transport: http() }) ``` Then you can consume [Public Actions](/docs/actions/public/introduction): ```ts twoslash // [!include ~/snippets/publicClient.ts] // ---cut--- const blockNumber = await publicClient.getBlockNumber() // [!code focus:10] ``` ## Optimization The Public Client also supports [`eth_call` Aggregation](#multicall) for improved performance. ### `eth_call` Aggregation (via Multicall) The Public Client supports the aggregation of `eth_call` requests into a single multicall (`aggregate3`) request. This means for every Action that utilizes an `eth_call` request (ie. `readContract`), the Public Client will batch the requests (over a timed period) and send it to the RPC Provider in a single multicall request. This can dramatically improve network performance, and decrease the amount of [Compute Units (CU)](https://docs.alchemy.com/reference/compute-units) used by RPC Providers like Alchemy, Infura, etc. The Public Client schedules the aggregation of `eth_call` requests over a given time period. By default, it executes the batch request at the end of the current [JavaScript message queue](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Event_loop#queue) (a [zero delay](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Event_loop#zero_delays)), however, consumers can specify a custom `wait` period (in ms). You can enable `eth_call` aggregation by setting the `batch.multicall` flag to `true`: ```ts twoslash import { createPublicClient, http } from 'viem' import { mainnet } from 'viem/chains' // ---cut--- const publicClient = createPublicClient({ batch: { multicall: true, // [!code focus] }, chain: mainnet, transport: http(), }) ``` > You can also [customize the `multicall` options](#batchmulticallbatchsize-optional). Now, when you start to utilize `readContract` Actions, the Public Client will batch and send over those requests at the end of the message queue (or custom time period) in a single `eth_call` multicall request: :::code-group ```ts twoslash [example.ts] // @filename: client.ts // [!include ~/snippets/publicClient.ts] // @filename: abi.ts // [!include ~/snippets/erc20Abi.ts] // @filename: example.ts const address = '0x' // ---cut--- import { getContract } from 'viem' import { abi } from './abi' import { publicClient } from './client' const contract = getContract({ address, abi, client: publicClient }) // The below will send a single request to the RPC Provider. const [name, totalSupply, symbol, balance] = await Promise.all([ contract.read.name(), contract.read.totalSupply(), contract.read.symbol(), contract.read.balanceOf([address]), ]) ``` ```ts twoslash [client.ts] // [!include ~/snippets/publicClient.ts] ``` ```ts twoslash [abi.ts] // [!include ~/snippets/erc20Abi.ts] ``` ::: > Read more on [Contract Instances](/docs/contract/getContract). ## Parameters ### transport - **Type:** [Transport](/docs/glossary/types#transport) The [Transport](/docs/clients/intro) of the Public Client. ```ts twoslash // [!include ~/snippets/publicClient.ts:imports] // ---cut--- const publicClient = createPublicClient({ chain: mainnet, transport: http(), // [!code focus] }) ``` ### chain (optional) - **Type:** [Chain](/docs/glossary/types#chain) The [Chain](/docs/chains/introduction) of the Public Client. ```ts twoslash // [!include ~/snippets/publicClient.ts:imports] // ---cut--- const publicClient = createPublicClient({ chain: mainnet, // [!code focus] transport: http(), }) ``` ### batch (optional) Flags for batch settings. ### batch.multicall (optional) - **Type:** `boolean | MulticallBatchOptions` - **Default:** `false` Toggle to enable `eth_call` multicall aggregation. ```ts twoslash // [!include ~/snippets/publicClient.ts:imports] // ---cut--- const publicClient = createPublicClient({ batch: { multicall: true, // [!code focus] }, chain: mainnet, transport: http(), }) ``` ### batch.multicall.batchSize (optional) - **Type:** `number` - **Default:** `1_024` The maximum size (in bytes) for each multicall (`aggregate3`) calldata chunk. > Note: Some RPC Providers limit the amount of calldata that can be sent in a single request. It is best to check with your RPC Provider to see if there are any calldata size limits to `eth_call` requests. ```ts twoslash // [!include ~/snippets/publicClient.ts:imports] // ---cut--- const publicClient = createPublicClient({ batch: { multicall: { batchSize: 512, // [!code focus] }, }, chain: mainnet, transport: http(), }) ``` ### batch.multicall.deployless (optional) - **Type:** `boolean` - **Default:** `false` Enable deployless multicall. ```ts twoslash // [!include ~/snippets/publicClient.ts:imports] // ---cut--- const publicClient = createPublicClient({ batch: { multicall: { deployless: true, // [!code focus] }, }, chain: mainnet, transport: http(), }) ``` ### batch.multicall.wait (optional) - **Type:** `number` - **Default:** `0` ([zero delay](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Event_loop#zero_delays)) The maximum number of milliseconds to wait before sending a batch. ```ts twoslash // [!include ~/snippets/publicClient.ts:imports] // ---cut--- const publicClient = createPublicClient({ batch: { multicall: { wait: 16, // [!code focus] }, }, chain: mainnet, transport: http(), }) ``` ### cacheTime (optional) - **Type:** `number` - **Default:** `client.pollingInterval` Time (in ms) that cached data will remain in memory. ```ts twoslash // [!include ~/snippets/publicClient.ts:imports] // ---cut--- const publicClient = createPublicClient({ cacheTime: 10_000, // [!code focus] chain: mainnet, transport: http(), }) ``` ### ccipRead (optional) - **Type:** `(parameters: CcipRequestParameters) => Promise | false` - **Default:** `true` [CCIP Read](https://eips.ethereum.org/EIPS/eip-3668) configuration. CCIP Read is enabled by default, but if set to `false`, the client will not support offchain CCIP lookups. ```ts twoslash // [!include ~/snippets/publicClient.ts:imports] // ---cut--- const publicClient = createPublicClient({ ccipRead: false, // [!code focus] chain: mainnet, transport: http(), }) ``` ### ccipRead.request (optional) - **Type:** `(parameters: CcipRequestParameters) => Promise` A function that will be called to make the [offchain CCIP lookup request](https://eips.ethereum.org/EIPS/eip-3668#client-lookup-protocol). ```ts twoslash // @noErrors // [!include ~/snippets/publicClient.ts:imports] // ---cut--- const publicClient = createPublicClient({ ccipRead: { // [!code focus] async request({ data, sender, urls }) { // [!code focus] // ... // [!code focus] } // [!code focus] }, // [!code focus] chain: mainnet, transport: http(), }) ``` ### experimental_blockTag (optional) - **Type:** `BlockTag` - **Default:** `'latest'` The default block tag to use for Actions. This will be used as the default block tag for the following Actions: - `call` - `estimateGas` - `getBalance` - `getBlock` - `simulateBlocks` - `waitForTransactionReceipt` - `watchBlocks` :::note If the chain supports a pre-confirmation mechanism (set via `chain.experimental_preconfirmationTime`), the default block tag will be `'pending'`. ::: ```ts twoslash // [!include ~/snippets/publicClient.ts:imports] // ---cut--- const publicClient = createPublicClient({ experimental_blockTag: 'pending', // [!code focus] chain: mainnet, transport: http(), }) ``` ### key (optional) - **Type:** `string` - **Default:** `"public"` A key for the Client. ```ts twoslash // [!include ~/snippets/publicClient.ts:imports] // ---cut--- const publicClient = createPublicClient({ chain: mainnet, key: 'public', // [!code focus] transport: http(), }) ``` ### name (optional) - **Type:** `string` - **Default:** `"Public Client"` A name for the Client. ```ts twoslash // [!include ~/snippets/publicClient.ts:imports] // ---cut--- const publicClient = createPublicClient({ chain: mainnet, name: 'Public Client', // [!code focus] transport: http(), }) ``` ### pollingInterval (optional) - **Type:** `number` - **Default:** `4_000` Frequency (in ms) for polling enabled Actions. ```ts twoslash // [!include ~/snippets/publicClient.ts:imports] // ---cut--- const publicClient = createPublicClient({ chain: mainnet, pollingInterval: 10_000, // [!code focus] transport: http(), }) ``` ### rpcSchema (optional) - **Type:** `RpcSchema` - **Default:** `PublicRpcSchema` Typed JSON-RPC schema for the client. ```ts twoslash // [!include ~/snippets/publicClient.ts:imports] // @noErrors // ---cut--- import { rpcSchema } from 'viem' type CustomRpcSchema = [{ // [!code focus] Method: 'eth_wagmi', // [!code focus] Parameters: [string] // [!code focus] ReturnType: string // [!code focus] }] // [!code focus] const publicClient = createPublicClient({ chain: mainnet, rpcSchema: rpcSchema(), // [!code focus] transport: http(), }) const result = await publicClient.request({ // [!code focus] method: 'eth_wa // [!code focus] // ^| params: ['hello'], // [!code focus] }) // [!code focus] ``` ### dataSuffix (optional) - **Type:** `Hex | { value: Hex; required?: boolean }` Data to append to the end of transaction calldata. Useful for adding [transaction attribution](https://oxlib.sh/ercs/erc8021/Attribution). When a simple hex string is provided, the suffix is appended on a best-effort basis. When using the object form with `required: true`, transactions will fail if the suffix cannot be appended. Applies to `simulateContract` and `estimateContractGas` actions. For transaction-sending actions like `sendTransaction`, see [Wallet Client](/docs/clients/wallet#datasuffix-optional). ```ts twoslash // [!include ~/snippets/publicClient.ts:imports] // ---cut--- const publicClient = createPublicClient({ chain: mainnet, dataSuffix: '0xdeadbeef', // [!code focus] transport: http(), }) ``` ## Live Example Check out the usage of `createPublicClient` in the live [Public Client Example](https://stackblitz.com/github/wagmi-dev/viem/tree/main/examples/clients_public-client) below.