Skip to content

Commit d0dac6f

Browse files
Add Viem tutorial. (#1920)
* Add Viem tutorial. Signed-off-by: bgravenorst <[email protected]> * Minor updates. Signed-off-by: bgravenorst <[email protected]> * Add missing packages. Signed-off-by: bgravenorst <[email protected]> * Added what's new. Signed-off-by: bgravenorst <[email protected]> * Typo. Signed-off-by: bgravenorst <[email protected]> * Apply suggestions from code review Co-authored-by: Alexandra Carrillo <[email protected]> * Fix typo. Signed-off-by: bgravenorst <[email protected]> --------- Signed-off-by: bgravenorst <[email protected]> Co-authored-by: Alexandra Carrillo <[email protected]>
1 parent 93ac0ad commit d0dac6f

File tree

7 files changed

+234
-6
lines changed

7 files changed

+234
-6
lines changed

docs/whats-new.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ of the [MetaMask developer page](https://metamask.io/developer/).
1111

1212
## March 2025
1313

14+
- Added a tutorial for [sending a transaction using Viem](/services/tutorials/ethereum/send-a-transaction/send-a-transaction-viem). ([#1920](https://github.com/MetaMask/metamask-docs/pull/1920))
1415
- Documented [Base subscription methods](/services/reference/base/json-rpc-methods/subscription-methods).
1516
([#1916](https://github.com/MetaMask/metamask-docs/pull/1916))
1617
- Added full table for [Gas API supported networks](/services/get-started/endpoints/#gas-api).

services/tutorials/ethereum/send-a-transaction/send-a-transaction-ethers.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ Replace the following values in the `.env` file:
9898

9999
- `<NETWORK>` with `sepolia` or the alternative network you are using.
100100
- `<YOUR-API-KEY>` with your API key of the web3 project.
101-
- `<PRIVATE-KEY>` with the [private key of your Ethereum account](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key). A transaction must be signed with the sender's private key. Make sure that you prefix the `SIGNER_PRIVATE_KEY` value with `0x`. The private key you export from MetaMask isn't prefixed with `0x`.
101+
- `<PRIVATE-KEY>` with the [private key of your Ethereum account](https://support.metamask.io/configure/accounts/how-to-export-an-accounts-private-key/). A transaction must be signed with the sender's private key. Make sure that you prefix the `SIGNER_PRIVATE_KEY` value with `0x`. The private key you export from MetaMask isn't prefixed with `0x`.
102102

103103
:::danger
104104

services/tutorials/ethereum/send-a-transaction/send-a-transaction-go.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ func main() {
129129
Replace the following values in the script:
130130

131131
- `<YOUR-API-KEY>` with the Infura API key.
132-
- `<PRIVATE-KEY>` with the [private key of your Ethereum account](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key).
132+
- `<PRIVATE-KEY>` with the [private key of your Ethereum account](https://support.metamask.io/configure/accounts/how-to-export-an-accounts-private-key/).
133133
- `<ADDRESS-TO>` with the address of the recipient of funds.
134134

135135
If using a different Ethereum network, update the URL in the script.

services/tutorials/ethereum/send-a-transaction/send-a-transaction-py.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Create a `.env` file in your project directory to store the private key of your
5151
PRIVATE_KEY = <PRIVATE-KEY>
5252
```
5353

54-
Find out how to access the [private key of your Ethereum account](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key). Make sure that you prefix the `<PRIVATE_KEY>` value with `0x`. The
54+
Find out how to access the [private key of your Ethereum account](https://support.metamask.io/configure/accounts/how-to-export-an-accounts-private-key/). Make sure that you prefix the `<PRIVATE_KEY>` value with `0x`. The
5555
private key you export from MetaMask will not be prefixed with `0x`.
5656

5757
:::danger
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
---
2+
description: Send a transaction using Viem.
3+
---
4+
5+
import Tabs from '@theme/Tabs';
6+
import TabItem from '@theme/TabItem';
7+
8+
# Use Viem
9+
10+
In this tutorial, you'll send a transaction of 0.001 ETH from one account to another using the [Viem](https://viem.sh/)
11+
TypeScript library.
12+
13+
## Prerequisites
14+
15+
- [Node.js](https://nodejs.org/en/download/)
16+
- [Install TypeScript](https://www.typescriptlang.org/download/)
17+
- [Install `ts-node`](https://www.npmjs.com/package/ts-node)
18+
- An Ethereum account
19+
20+
:::info
21+
Use [MetaMask](https://metamask.io/) or similar to create an Ethereum account for testing.
22+
:::
23+
24+
## Steps
25+
26+
### 1. Select your network and verify funds
27+
28+
- **Sepolia** - To use the Sepolia testnet, ensure that your account has Sepolia ETH.
29+
You can use the [MetaMask faucet](/developer-tools/faucet) to add more funds.
30+
- **Alternative network** - To use an alternative network, ensure that your account has testnet ETH
31+
for that network.
32+
33+
:::note
34+
When using an alternative network, update the chain name in the script (in Step 6) with the
35+
alternative network name from the [Viem supported chains list](https://github.com/wevm/viem/blob/main/src/chains/index.ts).
36+
:::
37+
38+
### 2. Create a project directory
39+
40+
Create a new directory for your project using the command line:
41+
42+
```bash
43+
mkdir infura
44+
```
45+
46+
Change into the new directory:
47+
48+
```bash
49+
cd infura
50+
```
51+
52+
### 3. Initialize the project
53+
54+
Create a `package.json` file with default values:
55+
56+
```bash
57+
npm init -y
58+
```
59+
60+
Generate a `tsconfig.json` file, which is used to configure TypeScript compiler options:
61+
62+
```bash
63+
tsc --init --resolveJsonModule true
64+
```
65+
66+
### 4. Install the required packages
67+
68+
Install the required packages in the project directory.
69+
70+
```bash
71+
npm i viem
72+
```
73+
74+
```bash
75+
npm install -D tslib @types/node
76+
```
77+
78+
### 5. Create a `config.ts` file
79+
80+
Create a `config.ts` file in your project directory to store the private key of the sending account:
81+
82+
<Tabs>
83+
<TabItem value="Syntax" label="Syntax" default>
84+
85+
```tsx title="config.ts"
86+
import { privateKeyToAccount } from "viem/accounts"
87+
export const account = privateKeyToAccount("<PRIVATE-KEY>")
88+
```
89+
</TabItem>
90+
<TabItem value="Example" label="Example" default>
91+
92+
```tsx title="config.ts"
93+
import { privateKeyToAccount } from "viem/accounts"
94+
export const account = privateKeyToAccount("0x561...x...61df")
95+
```
96+
97+
</TabItem>
98+
</Tabs>
99+
100+
In the `config.ts` file, replace `<PRIVATE-KEY>` with the [private key of your Ethereum account](https://support.metamask.io/configure/accounts/how-to-export-an-accounts-private-key/).
101+
A transaction must be signed with the sender's private key. Make sure that you prefix the private key
102+
value with `0x`. The private key you export from MetaMask isn't prefixed with `0x`.
103+
104+
:::danger
105+
Never disclose your private key. Anyone with your private keys can steal the assets controlled by those keys.
106+
:::
107+
108+
### 6. Create a `sendTransaction.ts` file
109+
110+
In the project directory, create a `sendTransaction.ts` file, which configures and sends the transaction. For example:
111+
112+
```tsx
113+
import { http, createWalletClient, parseEther } from "viem"
114+
import { sepolia } from "viem/chains"
115+
import { account } from "./config"
116+
117+
// Create a wallet client to interact with Ethereum accounts.
118+
const walletClient = createWalletClient({
119+
chain: sepolia,
120+
transport: http("https://sepolia.infura.io/v3/<YOUR-API-KEY>")
121+
})
122+
123+
async function sendTx() {
124+
// Create and send the transaction object.
125+
const hash = await walletClient.sendTransaction({
126+
account,
127+
to: "0xc2CB3fb3924b8DE3A63C1da570a8dBaf2a533eA7",
128+
value : parseEther ("0.001")
129+
})
130+
131+
console.log("Mining transaction... ")
132+
console.log(`Tx mined in https://sepolia.etherscan.io/tx/${hash}`)
133+
}
134+
135+
sendTx()
136+
```
137+
138+
In the `sendTransaction.ts` file:
139+
140+
- Update the `chain` name if you're using an alternative network.
141+
- Replace `<YOUR-API-KEY>` with your Infura API key.
142+
- Update the `to` account in the code if you wish to send test ETH to an account of your choice.
143+
144+
### 7. Execute the transaction
145+
146+
To execute the transaction, run:
147+
148+
```bash
149+
ts-node sendTransaction.ts
150+
```
151+
152+
:::note
153+
`ts-node` is a TypeScript execution engine for Node.js. It allows you to run TypeScript files without
154+
manually compiling them into JavaScript first.
155+
:::
156+
157+
An alternative way to execute your transaction using Node.js is to compile your `sendTransaction.ts` file to JavaScript
158+
first, and then run the compiled JavaScript file:
159+
160+
```jsx
161+
tsc sendTransaction.ts
162+
node sendTransaction.js
163+
```
164+
165+
You can also run the TypeScript file, `sendTransaction.ts`, directly from your code development environment (such as
166+
VS Code) without using `ts-node` or pre-compiling to JavaScript.
167+
The following is an example output:
168+
169+
```bash
170+
Mining transcation...
171+
Tx mined https://sepolia.etherscan.io/tx/0x310588719e733118f50c0a1608e13b4e8bd5eb5891d546d89795c2041833abb6
172+
```
173+
174+
You can search for the transaction on a block explorer such as [Sepolia Etherscan](https://sepolia.etherscan.io/).
175+
176+
### 8. (Optional) Fine tune the transaction details
177+
178+
Viem automatically determines the gas limit and fees. If you want to change the default values, update
179+
the `sendTransaction` method to include an `estimateGas` result (`gasLimit`) and the `maxFeePerGas` and
180+
`maxPriorityFeePerGas` parameters.
181+
182+
To do this you will also need to declare an `httpClient` to interface with JSON-RPC methods like `eth_estimateGas`.
183+
184+
The following is a full code overview:
185+
186+
```tsx
187+
import { http, createWalletClient, createPublicClient, parseEther, parseGwei } from "viem"
188+
import { sepolia } from "viem/chains"
189+
import { account } from "./config"
190+
191+
// Create a wallet client to interact with Ethereum accounts.
192+
const walletClient = createWalletClient({
193+
chain: sepolia,
194+
transport: http("https://sepolia.infura.io/v3/<YOUR-API-KEY>")
195+
})
196+
197+
// Create a public client to interact with JSON-RPC API methods.
198+
const httpClient = createPublicClient({
199+
chain: sepolia,
200+
transport: http("https://sepolia.infura.io/v3/<YOUR-API-KEY>"),
201+
})
202+
203+
async function sendTx() {
204+
// Estimate gas limit.
205+
const limit = await httpClient.estimateGas({
206+
account,
207+
to: "0xc2CB3fb3924b8DE3A63C1da570a8dBaf2a533eA7",
208+
value: parseEther("0.001")
209+
})
210+
211+
// Create and send the transaction object.
212+
const hash = await walletClient.sendTransaction({
213+
account,
214+
to: "0xc2CB3fb3924b8DE3A63C1da570a8dBaf2a533eA7",
215+
value : parseEther ("0.001"),
216+
maxFeePerGas: parseGwei("20"),
217+
maxPriorityFeePerGas: parseGwei ("2"),
218+
gas: limit,
219+
})
220+
221+
console.log("Mining transaction... ")
222+
console.log(`Tx: https://sepolia.etherscan.io/tx/${hash}`)
223+
224+
}
225+
226+
sendTx()
227+
```

services/tutorials/ethereum/send-a-transaction/use-ethers.js-infuraprovider-or-web3provider.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,13 @@ Create a `.env` file in your project directory to store the project and Ethereum
6060

6161
```
6262
REACT_APP_API_KEY="<YOUR-API-KEY>"
63-
REACT_APP_PRIVATE_KEY="<Private-Key>"
63+
REACT_APP_PRIVATE_KEY="<PRIVATE-KEY>"
6464
```
6565

6666
Ensure you replace the following values in the `.env` file:
6767

6868
- `<YOUR-API-KEY>` with the API key of the Ethereum project.
69-
- `<Private-Key>` with the [private key of your Ethereum account](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key).
69+
- `<PRIVATE-KEY>` with the [private key of your Ethereum account](https://support.metamask.io/configure/accounts/how-to-export-an-accounts-private-key/).
7070

7171
:::danger
7272

services/tutorials/ethereum/send-a-transaction/use-web3.js.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ Replace the following values in the `.env` file:
100100

101101
- `<NETWORK>` with `sepolia` or the alternative network you are using.
102102
- `<YOUR-API-KEY>` with your API key of the web3 project.
103-
- `<PRIVATE-KEY>` with the [private key of your Ethereum account](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key). A transaction must be signed with the sender's private key. Make sure that you prefix the `SIGNER_PRIVATE_KEY` value with `0x`. The private key you export from MetaMask isn't prefixed with `0x`.
103+
- `<PRIVATE-KEY>` with the [private key of your Ethereum account](https://support.metamask.io/configure/accounts/how-to-export-an-accounts-private-key/). A transaction must be signed with the sender's private key. Make sure that you prefix the `SIGNER_PRIVATE_KEY` value with `0x`. The private key you export from MetaMask isn't prefixed with `0x`.
104104

105105
:::danger
106106

0 commit comments

Comments
 (0)