Skip to content

Local Accounts (Private Key, Mnemonic, etc)

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

There are three types of Local Accounts in viem:

Below are the steps to integrate a Private Key Account, but the same steps can be applied to Mnemonic & HD Accounts.

1: 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:

import { createWalletClient, http } from 'viem'
import { mainnet } from 'viem/chains'
 
const client = createWalletClient({
  chain: mainnet,
  transport: http()
})

2: Set up your Local Account

Next, we will instantiate a Private Key Account using privateKeyToAccount:

import { createWalletClient, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts' 
import { mainnet } from 'viem/chains'
 
const client = createWalletClient({
  chain: mainnet,
  transport: http()
})
 
const account = privateKeyToAccount('0x...') 

3: Consume Wallet Actions

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

import { createWalletClient, http, parseEther } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { mainnet } from 'viem/chains'
 
const client = createWalletClient({
  chain: mainnet,
  transport: http()
})
 
const account = privateKeyToAccount('0x...')
 
const hash = await client.sendTransaction({ 
  account,
  to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
  value: parseEther('0.001')
})

Optional: Hoist the Account

If you do not wish to pass an account around to every Action that requires an account, you can also hoist the account into the Wallet Client.

import { createWalletClient, http, parseEther } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { mainnet } from 'viem/chains'
 
const account = privateKeyToAccount('0x...')
 
const client = createWalletClient({ 
  account, 
  chain: mainnet,
  transport: http()
})
 
const hash = await client.sendTransaction({
  account, 
  to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
  value: parseEther('0.001')
})

Optional: Extend with Public Actions

When using a Local Account, you may be finding yourself using a Public Client instantiated with the same parameters (transport, chain, etc) as your Wallet Client.

In this case, you can extend your Wallet Client with Public Actions to avoid having to handle multiple Clients.

import { createWalletClient, http, publicActions } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { mainnet } from 'viem/chains'
 
const account = privateKeyToAccount('0x...')
 
const client = createWalletClient({
  account,
  chain: mainnet,
  transport: http()
}).extend(publicActions) 
 
const { request } = await client.simulateContract({ ... }) // Public Action
const hash = await client.writeContract(request) // Wallet Action