Configuration with setConfig Function

Learn how to use the Blockdaemon-Animoca's decentralized verifier network (Oracle).



Simplify your configuration process with oapp-utils-bd. An easy-to-use tool and automated alternative to the SetConfig function.

Users need to configure their application at initialization time by calling the setConfig function, and can choose the number of oracles (or DVNs) that validate each message in a given chain.

In LayerZero V2, the verification of messages is now handled by the Security Stack and execution by Executors:

  • Security Stack: Your application's selected DVNs.
  • Executor (Optional): Your application's selected automated caller for receiving messages.

1. Configuration Parameters

The configuration parameters you can use to customize your OApp are:

Config TypeDescription
confirmationsThe number of confirmed blocks to wait for. Set to 0 to use the default settings provided by LayerZero.
requiredDVNCountThe required number of DVNs to validate a message. If a single oracle is sufficient, this can be set to 1.
requiredDVNsA list of required DVN addresses. See the full list of Blockdaemon-Animoca oracles here.
optionalDVNCountThe number of optional oracles that can be involved in the validation process.
optionalDVNsThe list of optional DVN addresses.

2. Custom Configuration

To customize the behavior of your OApp, call the setConfig function from your OApp's endpoint to adjust protocol settings.

2.1. setConfig Function

You can customize various parameters using the OApp-authenticated setConfig function. This function takes the address of the OApp, the library address, and an array of SetConfigParam structures.

/// @dev authenticated by the _oapp
function setConfig(
  address _oapp,
  address _lib,
  SetConfigParam[] calldata _params
) external onlyRegistered(_lib) {

    IMessageLib(_lib).setConfig(_oapp, _params);

2.2. SetConfigParam Structure

The SetConfigParam structure contains information about the configuration, such as the endpoint ID (eid), the configuration type (configType), and the actual configuration data (config).

struct SetConfigParam {
    uint32 eid;
    uint32 configType;
    bytes config;

Configuration Types

Configuration types such as ULN and Executor are identified by their respective constants.


3. Setting your Configuration

To customize the communication features of an OApp, modify the configuration of the DVN and the executor. Follow these steps:

3.1. Define Parameters

Define parameters such as confirmations, DVN thresholds, and DVN addresses for the ULN configuration.

// Using ethers v5
const confirmations = 0; // Use LayerZero provided defaults
const optionalDVNsThreshold = 0;
const requiredDVNs = [<blockdaemonVerifierAddress>];
const optionalDVNs = [];
const requiredDVNsCount = requiredDVNs.length;
const optionalDVNsCount = optionalDVNs.length;

// Configuration type
const configTypeUln = 2; // As defined for CONFIG_TYPE_ULN

Replace blockdaemonVerifierAddress with the Blockdaemon-Animoca oracle address for the relevant Blockchain, which can be found here: Blockdaemon-Animoca Oracle Addresses.

3.2. Encode Parameters to Bytes

Encode ULN configuration parameters into bytes using the defaultAbiCoder from ethers.

const ulnConfigEncoded = ethers.utils.defaultAbiCoder.encode(
  ['uint64', 'uint8', 'uint8', 'uint8', 'address[]', 'address[]'],

3.3. Define SetConfigParam

Create a SetConfigParam object with the remote chain endpoint ID, configuration type (e.g., ULN), and encoded ULN configuration.

const setConfigParamUln = {
  eid: REMOTE_CHAIN_ENDPOINT_ID, // Replace with your remote chain's endpoint ID (source or destination)
  configType: configTypeUln,
  config: ulnConfigEncoded,

3.4. Call setConfig

After configuring the parameters, call the setConfig function in the OApp. See the example below.

const tx = await endpointContract.setConfig(oappAddress, messageLibraryAddress, [

await tx.wait();

Your OApp is now configured to require confirmation from specific DVNs before delivering messages.

4. Setting Multiple Configurations

You can configure multiple chain paths in one function call by including multiple SetConfigParam structures in the array argument.

// Call setConfig with multiple configurations
const tx = await oappContract.setConfig(oappAddress, messageLibraryAddress, [
  setUConfigParamUlnChainA, // Configuration for the first destination chain
  setConfigParamUlnChainB, // Configuration for the second destination chain
  // ... add as many configurations as needed

await tx.wait();



Make sure each structure has a unique eid for the remote chain and the chain has properly coded configuration parameters.

5. Resetting Configurations

Reset the configuration to the default provided by LayerZero by calling setConfig with a parameter that contains a null value. Here’s how you can do it:

5.1. Encode Null Parameters to Bytes

Define a null value and encode it in bytes, similar to the encoding in the ULN configuration.

const nilConfirmations = 0;
const nilDVNsCount = 0;
const nilDVNsThreshold = 0;
const nilDVNs = [];

// Configuration type remains the same
const configTypeUln = 2; // As defined for CONFIG_TYPE_ULN

const nilUlnConfigEncoded = ethers.utils.defaultAbiCoder.encode(
  ['uint64', 'uint8', 'uint8', 'uint8', 'address[]', 'address[]'],
  [nilConfirmations, nilDVNsCount, nilDVNsCount, nilDVNsThreshold, nilDVNs, nilDVNs],

const resetConfigParamUln = {
  eid: REMOTE_CHAIN_ENDPOINT_ID, // Replace with the endpoint ID you want to reset
  configType: configTypeUln,
  config: nilUlnConfigEncoded,

5.2. Call setConfig for Reset

Call the setConfig function with the address of the OApp, the address of the message library, and an array of the null configurations.

const resetTx = await endpointContract.setConfig(oappAddress, messageLibraryAddress, [
await resetTx.wait();

Your configurations will be reset, and you can make further adjustments.

6. Verify the Configuration

To verify that the configuration was successfully committed, call the getConfig function on the LayerZero endpoint. This function requires the OApp address (_oapp), library address (_lib), endpoint ID (_eid), and configuration type (_configType).

function getConfig(
    address _oapp,
    address _lib,
    uint32 _eid,
    uint32 _configType
) external view returns (bytes memory config);

Below is the sample function to get the configuration as a byte array.

const ulnConfigBytes = await contract.getConfig(oappAddress, libAddress, eid, configType);

👋 Need Help?

Contact us through email or our support page for any issues, bugs, or assistance you may need.