Skip to content
On this page

Wallet Client

A Wallet Client is an interface to interact with Ethereum Account(s) and provides the ability to retrieve accounts, execute transactions, sign messages, etc through Wallet Actions.

The createWalletClient function sets up a Wallet Client with a given Transport.

The Wallet Client supports signing over:

Import

ts
import { createWalletClient } from 'viem'

JSON-RPC Accounts

A JSON-RPC Account defers signing of transactions & messages to the target Wallet over JSON-RPC. An example could be sending a transaction via a Browser Extension Wallet (e.g. MetaMask) with the window.ethereum Provider.

Below is an example of how you can set up a JSON-RPC Account.

Initialize a Wallet Client

Before we set up our Account and start consuming Wallet Actions, we will need to set up our Wallet Client with the custom Transport, where we will pass in the window.ethereum Provider:

ts
import { createWalletClient, custom } from 'viem'

const client = createWalletClient({
  transport: custom(window.ethereum)
})

Set up your JSON-RPC Account

We will want to retrieve a list of addresses we can access in our Wallet (e.g. MetaMask), and then use one of them to retrieve an Account:

ts
import { createWalletClient, custom, getAccount } from 'viem' 

const client = createWalletClient({
  transport: custom(window.ethereum)
})

const [address] = await client.getAddresses() 
// or: const [address] = await client.requestAddresses() 
const account = getAccount(address)

Note: Some Wallets (like MetaMask) may require you to request access to Account addresses via client.requestAddresses first.

Consume Wallet Actions

Now you can use that Account within Wallet Actions that require a signature from the user:

ts
import { createWalletClient, custom } from 'viem'

const client = createWalletClient({
  transport: custom(window.ethereum)
})

const [address] = await client.getAddresses()
const account = getAccount(address)

const hash = await client.sendTransaction({ 
  account,
  to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
  value: parseEther('0.001')
})

Local Accounts (Experimental)

WARNING

Local Accounts are currently experimental. Use with caution.

A Local Account performs signing of transactions & messages with a private key before executing a method over JSON-RPC.

Below are the steps to integrate an Local Account into viem.

Initialize a Wallet Client

Before we set up our Account and start consuming Wallet Actions, we will need to set up our Wallet Client with the http Transport:

ts
import { createWalletClient, http } from 'viem'

const client = createWalletClient({
  transport: http()
})

Set up your Local Account

Next, we will instantiate a viem Account using getAccount.

viem currently does not have client-side signing utilities (coming soon!). For now, you will have to bring your own signing utilities and pass them through to the getAccount function:

ts
import { createWalletClient, http, getAccount } from 'viem'
import { getAddress, signMessage, signTransaction } from './sign-utils' 

const client = createWalletClient({
  transport: http()
})

const privateKey = '0x...' 
const account = getAccount({
  address: getAddress(privateKey),
  signMessage(message) {
    return signMessage(message, privateKey)
  },
  signTransaction(transaction) {
    return signTransaction(transaction, privateKey)
  }
})

Tip: Instead of building private key signing utilities yourself, you can plug in a third-party signer into the getAccount interface. We have an Ethers.js Wallet Adapter if you are coming from Ethers.js, but you could also hook up a web3.js Wallet, micro-eth-signer, etc to the getAccount interface.

Consume Wallet Actions

Now you can use that Account within Wallet Actions that need a signature from the user:

ts
import { createWalletClient, http, getAccount } from 'viem'
import { getAddress, signMessage, signTransaction } from './sign-utils'

const client = createWalletClient({
  transport: http()
})

const privateKey = '0x...'
const account = getAccount({
  address: getAddress(privateKey),
  signMessage(message) {
    return signMessage(message, privateKey)
  },
  signTransaction(transaction) {
    return signTransaction(transaction, privateKey)
  }
})

const hash = await client.sendTransaction({ 
  account,
  to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
  value: parseEther('0.001')
})

Parameters

chain (optional)

The Chain of the Wallet Client.

Used in the sendTransaction & writeContract Actions to assert that the chain matches the wallet's active chain.

ts
const client = createWalletClient({
  chain: mainnet, 
  transport: custom(window.ethereum)
})

key (optional)

  • Type: string
  • Default: "wallet"

A key for the Client.

ts
import { createWalletClient, custom } from 'viem'

const client = createWalletClient({
  key: 'foo', 
  transport: custom(window.ethereum)
})

name (optional)

  • Type: string
  • Default: "Wallet Client"

A name for the Client.

ts
import { createWalletClient, custom } from 'viem'

const client = createWalletClient({
  name: 'Foo Wallet Client', 
  transport: custom(window.ethereum)
})

pollingInterval (optional)

  • Type: number
  • Default: 4_000

Frequency (in ms) for polling enabled Actions.

ts
import { createWalletClient, custom } from 'viem'

const client = createWalletClient({
  pollingInterval: 10_000, 
  transport: custom(window.ethereum)
})

Ethers.js Wallet

WARNING

Local Accounts are currently experimental. Use with caution.

ts
import { createWalletClient, http } from 'viem'
import { getAccount } from 'viem/ethers' 
import { Wallet } from 'ethers'

const client = createWalletClient({
  transport: http()
})

const privateKey = '0x...' 
const account = getAccount(new Wallet(privateKey))

const hash = await client.sendTransaction({ 
  account,
  to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
  value: parseEther('0.001')
})

Released under the MIT License.