@layerzerolabs/toolbox-hardhat
One-stop-shop for developing LayerZero applications with hardhat
Installation
yarn add @layerzerolabs/toolbox-hardhat
pnpm add @layerzerolabs/toolbox-hardhat
npm install @layerzerolabs/toolbox-hardhat
Configuration
1. Add @layerzerolabs/toolbox-hardhat to your config
To use @layerzerolabs/toolbox-hardhat you will need to import it in your hardhat config file.
TypeScript (hardhat.config.ts)
import "@layerzerolabs/toolbox-hardhat";
JavaScript (hardhat.config.js)
require("@layerzerolabs/toolbox-hardhat");
2. Connect your networks
LayerZero deploys EndpointV2 contracts on all supported chains. These contracts are identified by their endpoint ID (eid for short).
In order to wire your contracts, @layerzerolabs/toolbox-hardhat needs to know the mapping between the networks defined in your hardhat config and the endpoint ID.
Previously we required your network names to exactly match the names we use. In order to be more flexible, we decided to switch this more explicit, albeit more verbose configuration.
Head to your hardhat config to set the eid ↔︎ network mapping.
TypeScript (hardhat.config.ts)
import { HardhatUserConfig } from "hardhat/types";
import { EndpointId } from "@layerzerolabs/lz-definitions";
const config: HardhatUserConfig = {
networks: {
fuji: {
eid: EndpointId.AVALANCHE_V2_TESTNET,
url: "https://api.avax-test.network/ext/bc/C/rpc",
},
mainnet: {
eid: EndpointId.ETHEREUM_V2_MAINNET,
url: "https://eth.llamarpc.com",
},
},
};
export default config;
JavaScript (hardhat.config.js)
const { EndpointId } = require("@layerzerolabs/lz-definitions");
const config = {
networks: {
fuji: {
eid: EndpointId.AVALANCHE_V2_TESTNET,
url: "https://api.avax-test.network/ext/bc/C/rpc",
},
mainnet: {
eid: EndpointId.ETHEREUM_V2_MAINNET,
url: "https://eth.llamarpc.com",
},
},
};
module.exports = config;
3. Configure your LayerZero OApp Config
To use the lz:oapp:wire task you must first fill out your layerzero.config file.
LayerZero configuration:
For example:
TypeScript (layerzero.config.ts)
import {
OAppOmniGraphHardhat,
OmniPointHardhat,
} from "@layerzerolabs/ua-devtools-evm-hardhat";
import { EndpointId } from "@layerzerolabs/lz-definitions";
import { ExecutorOptionType } from "@layerzerolabs/lz-v2-utilities";
const sepoliaContract: OmniPointHardhat = {
eid: EndpointId.SEPOLIA_V2_TESTNET,
contractName: "MyOApp",
};
const fujiContract: OmniPointHardhat = {
eid: EndpointId.AVALANCHE_V2_TESTNET,
contractName: "MyOApp",
};
const graph: OAppOmniGraphHardhat = {
contracts: [
{
contract: fujiContract,
},
{
contract: sepoliaContract,
},
],
connections: [
{
from: fujiContract,
to: sepoliaContract,
config: {
sendLibrary: "0x0000000000000000000000000000000000000000",
receiveLibraryConfig: {
receiveLibrary: "0x0000000000000000000000000000000000000000",
gracePeriod: BigInt(0),
},
receiveLibraryTimeoutConfig: {
lib: "0x0000000000000000000000000000000000000000",
expiry: BigInt(0),
},
sendConfig: {
executorConfig: {
maxMessageSize: 99,
executor: "0x0000000000000000000000000000000000000000",
},
ulnConfig: {
confirmations: BigInt(42),
requiredDVNs: [],
optionalDVNs: [
"0x0000000000000000000000000000000000000000",
"0x0000000000000000000000000000000000000000",
],
optionalDVNThreshold: 2,
},
},
receiveConfig: {
ulnConfig: {
confirmations: BigInt(42),
requiredDVNs: [],
optionalDVNs: [
"0x0000000000000000000000000000000000000000",
"0x0000000000000000000000000000000000000000",
],
optionalDVNThreshold: 2,
},
},
enforcedOptions: [
{
msgType: 1,
optionType: ExecutorOptionType.LZ_RECEIVE,
gas: 200000,
value: 1,
},
{
msgType: 1,
optionType: ExecutorOptionType.NATIVE_DROP,
amount: 1,
receiver: "0x0000000000000000000000000000000000000000",
},
{
msgType: 2,
optionType: ExecutorOptionType.COMPOSE,
index: 0,
gas: 200000,
value: 1,
},
{
msgType: 2,
optionType: ExecutorOptionType.COMPOSE,
index: 1,
gas: 300000,
value: 1,
},
],
},
},
],
};
export default graph;
Usage
Tasks
This package comes with several hardhat tasks to speed up your workflow. In order to prevent name collisions, these have been prefixed with lz::
lz:oapp:wire
Wires the individual OApp contracts together, calling setPeer.
pnpm hardhat lz:oapp:wire