@eth-optimism/viem and viem packages are an easy way to add bridging functionality to your javascript-based application.
They also provide some safety rails to prevent common mistakes that could cause tokens to be made inaccessible.
Behind the scenes, @eth-optimism/viem package uses the Standard Bridge contracts to transfer tokens.
Make sure to check out the Standard Bridge guide if you want to learn more about how the bridge works under the hood.
Supported networks
Viem supports any of the OP Stack networks. If you want to use a network that isn’t included by default, you can add it to Viem’s chain configurations.Dependencies
Create a demo project
You’re going to use the@eth-optimism/viem package for this tutorial.
Since the @eth-optimism/viem package is a Node.js library, you’ll need to create a Node.js project to use it.
Make a Project Folder
Initialize the Project
Install the `@eth-optimism/viem`
Install viem
cast installed
you can run cast wallet new in your terminal to create a new wallet and get
the private key.Get ETH on Sepolia and OP Sepolia
This tutorial explains how to bridge tokens from Sepolia to OP Sepolia. You will need to get some ETH on both of these testnets.Add a private key to your environment
You need a private key to sign transactions. Set your private key as an environment variable with theexport command.
Make sure this private key corresponds to an address that has ETH on both Sepolia and OP Sepolia.
Start the Node REPL
You’re going to use the Node REPL to interact with the@eth-optimism/viem.
To start the Node REPL, run the following command in your terminal:
Import dependencies
You need to import some dependencies into your Node REPL session. The@eth-optimism/viem package uses ESM modules, and to use in the Node.js REPL, you need to use dynamic imports with await.
Here’s how to do it:
Import the @eth-optimism/viem package
Set session variables
You’ll need a few variables throughout this tutorial. Let’s set those up now.Load your private key
Create the RPC providers and wallets
- L1 Public Client: For reading data from the Sepolia network
- L1 Wallet Client: For signing and sending transactions on Sepolia
- L2 Public Client: For reading data from OP Sepolia
- L2 Wallet Client: For signing and sending transactions on OP Sepolia
<YOUR_API_KEY> with your API key from a RPC provider.Set the L1 and L2 ERC-20 addresses
oneToken representing the full unit (10^18 wei) to simplify our deposit and withdrawal operations.Get L1 tokens
You’re going to need some tokens on L1 that you can bridge to L2. The L1 testing token located at0x5589BB8228C07c4e15558875fAf2B859f678d129 has a faucet function that makes it easy to get tokens.
Set the ERC20 ABI
balanceOf: Allows us to check token balances for any addressfaucet: A special function in this test token that mints new tokens to the callerapprove: Required to grant the bridge permission to transfer tokens on our behalfallowance: To check how many tokens we’ve approved for the bridgedecimalsandsymbol: Provide token metadata
Request some tokens
faucet function on the L1 test token contract to receive free tokens for testing.
This transaction will mint new tokens directly to our wallet address.The function doesn’t require any parameters - it simply credits a predetermined amount to whoever calls it.
We store the transaction hash for later reference and wait for the transaction to be confirmed.Check your token balance
balanceOf function on the L1 token contract.This step confirms that we’ve successfully received tokens before proceeding with the bridging process.
The balance is returned in the smallest unit (wei), but we format it into a more readable form using the formatEther utility function from viem, since this token uses 18 decimal places.Deposit tokens
Now that you have some tokens on L1, you can deposit those tokens into theL1StandardBridge contract.
You’ll then receive the same number of tokens on L2 in return.
Define the amount to deposit
oneToken that represents 1 full token in its base units (wei).
ERC-20 tokens typically use 18 decimal places, so 1 token equals 10^18 wei.This constant helps us work with precise token amounts in our transactions, avoiding rounding errors and ensuring exact value transfers.
We’ll use this value for both deposits and withdrawalsAllow the Standard Bridge to access your tokens
approve function on the token contract.We specify the bridge address from the chain configuration and the exact amount we want to bridge.
This approval transaction must be confirmed before the bridge can move our tokens.Wait for approval
waitForTransactionReceipt function to monitor the transaction until it’s included in a block.The receipt provides confirmation details, including which block includes our transaction.
This step ensures our approval is finalized before attempting to bridge tokens.Deposit your tokens
depositERC20 function from the @eth-optimism/viem package.This function handles all the complex interactions with the L1StandardBridge contract for us.
We provide:- The addresses of both the L1 and L2 tokens
- The amount to bridge
- The target chain (OP Sepolia)
- Our wallet address as the recipient on L2
- A minimum gas limit for the L2 transaction
depositERC20 will fail
if you try to deposit ETH from a smart contract wallet without specifying a
recipient. Add the recipient option to the depositERC20 call to fix
this. Check out the @eth-optimism/viem
docs for
more info on the options you can pass to depositERC20.Wait for the deposit to be relayed
Check your token balance on L1
L1StandardBridge contract.
This step helps confirm that the first part of the bridging process completed successfully:Check your token balance on L2
Withdraw tokens
You just bridged some tokens from L1 to L2. Nice! Now you’re going to repeat the process in reverse to bridge some tokens from L2 to L1.Initiate the withdrawal
withdrawOptimismERC20 function from the @eth-optimism/viem package.
This function interacts with the L2StandardBridge contract to initialize the withdrawal process.
We specify:- The L2 token address
- The amount to withdraw (we’re using half of a token in this tutorial)
- Our address as the recipient on L1
- A minimum gas limit for the transaction
Wait for the transaction receipt
Check your token balance on L2
Next steps
Congrats! You’ve just deposited and withdrawn tokens using@eth-optimism/viem package.
You should now be able to write applications that use the @eth-optimism/viem package to transfer ERC-20 tokens between L1 and L2.
Although this tutorial used Sepolia and OP Sepolia, the same process works for Ethereum and OP Mainnet.