Build Omnichain Fungible Token (OFTs) on Rootstock with Layerzero
Rootstock supports LayerZero, a cross-chain messaging protocol. You can build omnichain applications (OApps) that send messages and tokens between Rootstock and other EVM chains. Fees, latency, and trust assumptions still depend on each route and endpoint configuration.
This tutorial shows how to implement OFT (Omnichain Fungible Token) transfers between Rootstock Testnet and Ethereum Sepolia using LayerZero OFT V2.
What you'll learn
- Set up Hardhat for cross-chain deployments
- Deploy an OFT contract for token transfers between chains
- Configure LayerZero endpoints for cross-chain communication
- Execute transfers between Rootstock and Ethereum Sepolia testnets using the crosschain transfer feature.
Prerequisites
To complete this tutorial, you'll need:
- Node.js: v18.18.0+
- RPC Providers (Rootstock, Alchemy)
- Etherscan API Key
- Sign up to get an API Key. This will be used for verifying the contracts.
- Metamask: Install and connect to Ethereum Sepolia and Rootstock Testnet
- Test Funds: Sepolia ETH and Rootstock rBTC
Important: Ensure you have sufficient test tokens on both networks.
Why teams use LayerZero on Rootstock
- Asset movement: You route value through LayerZero’s OFT and related patterns instead of ad hoc bridges. Each path still has its own fees, latency, and trust model.
- Cost and speed: Rootstock and the destination chain set gas and confirmation time. Compare endpoints before you commit user flows to a route.
- Reach: You can surface Rootstock assets on other EVM chains where your users already hold wallets and liquidity.
- Liquidity: Omnichain designs let you reference liquidity on multiple chains. Depth and slippage depend on how you split pools and incentives.
- Delivery semantics: LayerZero documents message delivery and executor behavior. Read the path config for your deployment. Do not assume “guaranteed” delivery without checking DVNs and limits.
- Composable flows: OApps can chain sends, receives, and off-chain steps. Complexity and failure modes grow with each hop, so design retries and monitoring explicitly.
Use cases for cross-chain dApps on Rootstock
LayerZero messaging supports more than simple transfers. Typical patterns include:
- Cross-chain DEX liquidity: Pool liquidity across chains. Trading rBTC and other assets still follows each pool’s rules and bridge path.
- Cross-chain lending and borrowing: Users supply or borrow on one chain while collateral or settlement lives on another. You must align liquidation, oracles, and bridge timing with your risk model.
- Omnichain governance: Votes and execution can span chains when you wire proposals to LayerZero messages. Latency and quorum rules need explicit handling per chain.
- Cross-chain yield: Vaults can rebalance across chains. Yield and principal risk depend on each venue’s contracts and the bridge path you use.
- NFTs across chains: Marketplaces can list or settle on different chains than mint. Bitcoin finality on Rootstock does not remove smart contract or bridge risk on the other side.
Getting started
Clone and cd into the Layerzero Starter Kit project, and run npm install.
git clone https://github.com/rsksmart/rsk-layerzero-xERC20.git
cd rsk-layerzero-xERC20
Set up environment variables
Rename the .env.example file to .env and update the environment variables with your own values.
MNEMONIC=
EVM_PRIVATE_KEY=
RPC_URL_SEPOLIA=
RPC_URL_ROOTSTOCK_TESTNET=
ETHERSCAN_API_KEY=
Choose either Mnemonic or the Private Key as your preferred value and set only one. Note to ensure the wallet has ETH and test rBTC. See the prerequisites section. By default, the examples support both mnemonic-based and private key-based authentication. Setup RPC url’s for Sepolia and Rootstock using Alchemy and the Rootstock RPC API. To verify the contracts from the Sepolia explorer, use the Etherscan API key. Note: Do not share these variables with third parties as you risk losing your real assets.
Configure chains
To configure the kit to deploy to your preferred chains, go to hardhat.config.ts file and replace the code below in the networks section.
Note: For better performance and reliability, use a custom RPC endpoint as suggested in the prerequisites section.
networks: {
'sepolia-testnet': {
eid: EndpointId.SEPOLIA_V2_TESTNET,
url: process.env.RPC_URL_SEPOLIA || 'https://ethereum-sepolia-rpc.publicnode.com',
accounts,
},
'rootstock-testnet': {
eid: EndpointId.ROOTSTOCK_V2_TESTNET,
url: process.env.RPC_URL_ROOTSTOCK_TESTNET || 'https://public-node.testnet.rsk.co',
accounts,
}
}
Deploying contracts
After adding your PRIVATE_KEY to the .env file and adding networks in your hardhat.config.ts, run the command to deploy your LayerZero contracts:
npx hardhat lz:deploy
We will specify the target chains for our OFT deployment. This action will generate a /deployments folder containing the necessary deployment assets.

Use the default networks provided. To select other options, see the instructions above.

- Use the default script provided. Press Enter to proceed.

During this step, the deployer and the token contract address will be requested. Enter y to confirm.

Save the deployer address and contract address, as this will be used later in this tutorial to verify the contracts.