Skip to main content
This guide explains how to configure Decentralized Verifier Networks (DVNs), Executors, and message libraries for your IOTA OApp or OFT using the SDK.
Production deployments should use multiple required DVNs from independent operators. A single-DVN configuration means a compromise of that one verifier results in unrestricted forged messages on the pathway. The examples on this page show the LayerZero Labs DVN with a <SECONDARY_PROVIDER> placeholder so the snippet does not silently model a single-DVN production setup. Replace <SECONDARY_PROVIDER> with a real non-LayerZero-Labs provider — see DVN Addresses for available providers per chain. See the Integration Checklist for production DVN guidance.

Overview

Configuration is done through the OApp SDK instance. All examples use sdk.getOApp(packageId) to get the OApp instance, then call SDK methods for configuration. Configuration flow:
  1. Set message libraries (optional)
  2. Configure DVNs for send/receive (optional but recommended)
  3. Set enforced options (optional)
  4. Set peer addresses (required - opens pathway, call last!)

SDK Setup

Configuration Methods

Set Peer

Address format: Use package ID for IOTA peers, 32-byte address for other chains.

Set Message Libraries

Default: Uses Endpoint defaults if not configured.

DVN Configuration

Configure Receive DVN (Inbound)

Configure Send DVN (Outbound)

Config types: 1 = Executor, 2 = Send ULN, 3 = Receive ULN DVN addresses: Use PACKAGE_DVN_LAYERZERO_ADDRESS[Stage.MAINNET] or see Deployed Contracts.

Set Enforced Options

Gas Limit Recommendations

Based on gas profiling:

OApp/OFT Operations

Enforced Options Examples

For EVM destinations:
For IOTA destinations:
Note: Based on gas profiling, IOTA lz_receive uses 2,000-5,000 gas units. No msg.value needed - IOTA handles storage internally.

Common Issues

Errors:
  • InvalidBCSBytes → Use OAppUlnConfigBcs.serialize() for DVN config
  • oapp_registry::get_messaging_channel abort code: 1 → Used object ID instead of package ID as peer
  • Channel not initialized → Registration creates MessagingChannel automatically (no manual init needed)

Next Steps