Skip to main content
Version: Endpoint V2

Migrate to Simple Config

The LayerZero Simple Config Generator provides a streamlined approach to configuring your OApp connections across supported VMs (EVM, Solana, etc.). This guide will help you migrate from manual configuration to the Simple Config approach.

note

Current Support: The Simple Config Generator currently supports EVM chains and Solana. Aptos support is not yet available.

Why Migrate to Simple Config?

The Simple Config Generator offers several advantages over manual configuration:

  • Reduced complexity: Fewer configuration parameters to manage
  • Automatic bidirectional connections: Define one pathway, get both directions
  • Built-in best practices: Uses recommended DVN and executor configurations
  • Cross-VM compatibility: Works seamlessly with EVM chains, Solana, and other supported VMs
  • Less error-prone: Automated configuration generation reduces manual errors
  • VM-agnostic: Same configuration approach works across different virtual machines

Before Migration: Manual Configuration

In the traditional manual approach, you would need to:

  1. Define each connection direction separately
  2. Manually specify send and receive libraries
  3. Configure ULN settings for each direction
  4. Set up executor configurations
  5. Define enforced options for each pathway
  6. Handle VM-specific configurations separately

Here's an example of manual configuration for EVM chains:

connections: [
// ETH <--> ARB PATHWAY: START
{
from: ethereumContract,
to: arbitrumContract,
},
{
from: arbitrumContract,
to: ethereumContract,
},
// ETH <--> ARB PATHWAY: END
];

// Then define config settings for each direction
connections: [
{
from: ethereumContract,
to: arbitrumContract,
config: {
sendLibrary: contractsConfig.ethereum.sendLib302,
receiveLibraryConfig: {
receiveLibrary: contractsConfig.ethereum.receiveLib302,
gracePeriod: BigInt(0),
},
sendConfig: {
executorConfig: {
maxMessageSize: 10000,
executor: contractsConfig.ethereum.executor,
},
ulnConfig: {
confirmations: BigInt(15),
requiredDVNs: [
contractsConfig.ethereum.horizenDVN,
contractsConfig.ethereum.polyhedraDVN,
contractsConfig.ethereum.lzDVN,
],
optionalDVNs: [],
optionalDVNThreshold: 0,
},
},
receiveConfig: {
ulnConfig: {
confirmations: BigInt(20),
requiredDVNs: [
contractsConfig.ethereum.lzDVN,
contractsConfig.ethereum.horizenDVN,
contractsConfig.ethereum.polyhedraDVN,
],
optionalDVNs: [],
optionalDVNThreshold: 0,
},
},
enforcedOptions: [
{
msgType: 1,
optionType: ExecutorOptionType.LZ_RECEIVE,
gas: 65000,
value: 0,
},
{
msgType: 2,
optionType: ExecutorOptionType.LZ_RECEIVE,
gas: 65000,
value: 0,
},
{
msgType: 2,
optionType: ExecutorOptionType.COMPOSE,
index: 0,
gas: 50000,
value: 0,
},
],
},
},
// Repeat for the reverse direction...
];

After Migration: Simple Config

With the Simple Config Generator, the same configuration becomes much simpler and works across all VMs:

import {ExecutorOptionType} from '@layerzerolabs/lz-v2-utilities';
import {OAppEnforcedOption, OmniPointHardhat} from '@layerzerolabs/toolbox-hardhat';
import {EndpointId} from '@layerzerolabs/lz-definitions';
import {generateConnectionsConfig} from '@layerzerolabs/metadata-tools';

const ethereumContract: OmniPointHardhat = {
eid: EndpointId.ETHEREUM_V2_MAINNET,
contractName: 'MyOFT',
};

const arbitrumContract: OmniPointHardhat = {
eid: EndpointId.ARBITRUM_V2_MAINNET,
contractName: 'MyOFT',
};

const EVM_ENFORCED_OPTIONS: OAppEnforcedOption[] = [
{
msgType: 1,
optionType: ExecutorOptionType.LZ_RECEIVE,
gas: 65000,
value: 0,
},
];

export default async function () {
const connections = await generateConnectionsConfig([
[
ethereumContract, // Chain A contract
arbitrumContract, // Chain B contract
[['LayerZero Labs'], []], // [ requiredDVN[], [ optionalDVN[], threshold ] ]
[15, 20], // [A to B confirmations, B to A confirmations]
[EVM_ENFORCED_OPTIONS, EVM_ENFORCED_OPTIONS], // Chain A enforcedOptions, Chain B enforcedOptions
],
]);

return {
contracts: [{contract: ethereumContract}, {contract: arbitrumContract}],
connections,
};
}

Migration Steps

1. Install Required Dependencies

pnpm add -D @layerzerolabs/metadata-tools

2. Update Your Configuration File

Replace your manual layerzero.config.ts with the Simple Config approach:

import {ExecutorOptionType} from '@layerzerolabs/lz-v2-utilities';
import {OAppEnforcedOption, OmniPointHardhat} from '@layerzerolabs/toolbox-hardhat';
import {EndpointId} from '@layerzerolabs/lz-definitions';
import {generateConnectionsConfig} from '@layerzerolabs/metadata-tools';

// Define your contracts
const contractA: OmniPointHardhat = {
eid: EndpointId.CHAIN_A_ENDPOINT_ID,
contractName: 'YourContract',
};

const contractB: OmniPointHardhat = {
eid: EndpointId.CHAIN_B_ENDPOINT_ID,
contractName: 'YourContract',
};

// Define enforced options (gas settings for destination chain execution)
const EVM_ENFORCED_OPTIONS: OAppEnforcedOption[] = [
{
msgType: 1,
optionType: ExecutorOptionType.LZ_RECEIVE,
gas: 80000,
value: 0,
},
];

export default async function () {
const connections = await generateConnectionsConfig([
[
contractA, // Chain A contract
contractB, // Chain B contract
[['LayerZero Labs'], []], // [ requiredDVN[], [ optionalDVN[], threshold ] ]
[1, 1], // [A to B confirmations, B to A confirmations]
[EVM_ENFORCED_OPTIONS, EVM_ENFORCED_OPTIONS], // Chain A enforcedOptions, Chain B enforcedOptions
],
]);

return {
contracts: [{contract: contractA}, {contract: contractB}],
connections,
};
}

3. Update Your Deployment Scripts

Replace your manual wire commands with the Simple Config approach:

npx hardhat lz:oapp:wire --oapp-config layerzero.config.ts

Key Differences

AspectManual ConfigSimple Config
Connection DefinitionDefine each direction separatelyDefine once, get bidirectional
DVN ConfigurationManual specificationAutomated with metadata
Executor SetupManual configurationAutomated with metadata
Library SelectionManual specificationAutomated with metadata
VM-Specific HandlingSeparate configs per VMUnified approach
Configuration Length100+ lines per pathway~20 lines per pathway
Error ProneHigh (manual configuration)Low (automated generation)

Configuration Parameters Explained

note

Custom Metadata: For advanced use cases, you can provide custom metadata by passing a fetchMetadata function to generateConnectionsConfig. This allows you to extend the default metadata with custom DVNs and executors.

Pathway Definition

[
contractA, // Source chain contract
contractB, // Destination chain contract
[['LayerZero Labs'], []], // DVN configuration
[15, 20], // Confirmations for each direction
[optionsA, optionsB], // Enforced options for each direction
];

DVN Configuration

[['LayerZero Labs'], []]; // [ requiredDVN[], [ optionalDVN[], threshold ] ]
  • Required DVNs: Must verify the message for it to be considered valid
  • Optional DVNs: Additional verifiers (with threshold) for enhanced security

Confirmations

[15, 20]; // [A to B confirmations, B to A confirmations]

The number of block confirmations to wait before considering a message verified.

Enforced Options

const EVM_ENFORCED_OPTIONS: OAppEnforcedOption[] = [
{
msgType: 1, // Message type (1 = OFT, 2 = OApp)
optionType: ExecutorOptionType.LZ_RECEIVE, // Option type
gas: 80000, // Gas limit for destination execution
value: 0, // Value to send (usually 0)
},
];

VM-Specific Considerations

EVM Chains

  • Use contractName for contract identification
  • Gas values represent actual gas units
  • Value is typically 0

Solana

  • Use address for contract identification (required)
  • Gas values represent compute units
  • Value represents lamports (typically 2039280 for SPL token account rent)
note

Aptos Support: Aptos is not yet supported by the Simple Config Generator. Use manual configuration for Aptos integrations.

Migration Checklist

  • Install @layerzerolabs/metadata-tools
  • Update layerzero.config.ts to use Simple Config format
  • Define your contract objects with correct EIDs
  • Configure enforced options for your use case
  • Set appropriate DVN requirements
  • Handle VM-specific requirements (address for Solana contract objects)
  • Test by running npx hardhat lz:oapp:wire --oapp-config layerzero.config.ts (if there were no config changes, there should be no transactions to be submitted)

Troubleshooting

Common Issues

  1. Missing Dependencies: Ensure @layerzerolabs/metadata-tools is installed
  2. Incorrect EndpointId: Verify you are using the correct Endpoint ID (if using Endpoint V2, the constant name should include V2)
  3. VM-Specific Requirements: Remember to specify address for Solana contracts and value for enforced options msgType 1 when sending to Solana.
  4. Gas Estimation: Profile your contracts to set appropriate gas limits

Getting Help

If you encounter issues during migration:

  1. Check the Simple Config documentation
  2. Review the examples in devtools
  3. Consult VM-specific documentation.

The Simple Config Generator significantly reduces the complexity of LayerZero configuration while maintaining the same functionality and security guarantees as manual configuration.