Use Viem
In this tutorial, you'll send a transaction of 0.001 ETH from one account to another using the Viem TypeScript library.
Prerequisites
- Node.js
- Install TypeScript
- Install
ts-node
- An Ethereum account
Use MetaMask or similar to create an Ethereum account for testing.
Steps
1. Select your network and verify funds
-
Sepolia - To use the Sepolia testnet, ensure that your account has Sepolia ETH. You can use the MetaMask faucet to add more funds.
-
Alternative network - To use an alternative network, ensure that your account has testnet ETH for that network.
noteWhen using an alternative network, update the chain name in the script (in Step 6) with the alternative network name from the Viem supported chains list.
2. Create a project directory
Create a new directory for your project using the command line:
mkdir infura
Change into the new directory:
cd infura
3. Initialize the project
Create a package.json
file with default values:
npm init -y
Generate a tsconfig.json
file, which is used to configure TypeScript compiler options:
tsc --init --resolveJsonModule true
4. Install the required packages
Install the required packages in the project directory.
npm i viem
npm install -D tslib @types/node
5. Create a config.ts
file
Create a config.ts
file in your project directory to store the private key of the sending account:
- Syntax
- Example
import { privateKeyToAccount } from "viem/accounts"
export const account = privateKeyToAccount("<PRIVATE-KEY>")
import { privateKeyToAccount } from "viem/accounts"
export const account = privateKeyToAccount("0x561...x...61df")
In the config.ts
file, replace <PRIVATE-KEY>
with the private key of your Ethereum account.
A transaction must be signed with the sender's private key. Make sure that you prefix the private key
value with 0x
. The private key you export from MetaMask isn't prefixed with 0x
.
Never disclose your private key. Anyone with your private keys can steal the assets controlled by those keys.
6. Create a sendTransaction.ts
file
In the project directory, create a sendTransaction.ts
file, which configures and sends the transaction. For example:
import { http, createWalletClient, parseEther } from "viem"
import { sepolia } from "viem/chains"
import { account } from "./config"
// Create a wallet client to interact with Ethereum accounts.
const walletClient = createWalletClient({
chain: sepolia,
transport: http("https://sepolia.infura.io/v3/<YOUR-API-KEY>")
})
async function sendTx() {
// Create and send the transaction object.
const hash = await walletClient.sendTransaction({
account,
to: "0xc2CB3fb3924b8DE3A63C1da570a8dBaf2a533eA7",
value : parseEther ("0.001")
})
console.log("Mining transaction... ")
console.log(`Tx mined in https://sepolia.etherscan.io/tx/${hash}`)
}
sendTx()
In the sendTransaction.ts
file:
- Update the
chain
name if you're using an alternative network. - Replace
<YOUR-API-KEY>
with your Infura API key. - Update the
to
account in the code if you wish to send test ETH to an account of your choice.
7. Execute the transaction
To execute the transaction, run:
ts-node sendTransaction.ts
ts-node
is a TypeScript execution engine for Node.js. It allows you to run TypeScript files without
manually compiling them into JavaScript first.
An alternative way to execute your transaction using Node.js is to compile your sendTransaction.ts
file to JavaScript
first, and then run the compiled JavaScript file:
tsc sendTransaction.ts
node sendTransaction.js
You can also run the TypeScript file, sendTransaction.ts
, directly from your code development environment (such as
VS Code) without using ts-node
or pre-compiling to JavaScript.
The following is an example output:
Mining transcation...
Tx mined https://sepolia.etherscan.io/tx/0x310588719e733118f50c0a1608e13b4e8bd5eb5891d546d89795c2041833abb6
You can search for the transaction on a block explorer such as Sepolia Etherscan.
8. (Optional) Fine tune the transaction details
Viem automatically determines the gas limit and fees. If you want to change the default values, update
the sendTransaction
method to include an estimateGas
result (gasLimit
) and the maxFeePerGas
and
maxPriorityFeePerGas
parameters.
To do this you will also need to declare an httpClient
to interface with JSON-RPC methods like eth_estimateGas
.
The following is a full code overview:
import { http, createWalletClient, createPublicClient, parseEther, parseGwei } from "viem"
import { sepolia } from "viem/chains"
import { account } from "./config"
// Create a wallet client to interact with Ethereum accounts.
const walletClient = createWalletClient({
chain: sepolia,
transport: http("https://sepolia.infura.io/v3/<YOUR-API-KEY>")
})
// Create a public client to interact with JSON-RPC API methods.
const httpClient = createPublicClient({
chain: sepolia,
transport: http("https://sepolia.infura.io/v3/<YOUR-API-KEY>"),
})
async function sendTx() {
// Estimate gas limit.
const limit = await httpClient.estimateGas({
account,
to: "0xc2CB3fb3924b8DE3A63C1da570a8dBaf2a533eA7",
value: parseEther("0.001")
})
// Create and send the transaction object.
const hash = await walletClient.sendTransaction({
account,
to: "0xc2CB3fb3924b8DE3A63C1da570a8dBaf2a533eA7",
value : parseEther ("0.001"),
maxFeePerGas: parseGwei("20"),
maxPriorityFeePerGas: parseGwei ("2"),
gas: limit,
})
console.log("Mining transaction... ")
console.log(`Tx: https://sepolia.etherscan.io/tx/${hash}`)
}
sendTx()