> ## Documentation Index
> Fetch the complete documentation index at: https://docs.layerzero.network/llms.txt
> Use this file to discover all available pages before exploring further.

# LayerZero Simple Config Generator

> Use Simple Config Generator with LayerZero V2. Developer tools for building and debugging omnichain applications. LayerZero enables crosschain messaging.

The LayerZero Simple Config Generator makes use of the `@layerzerolabs/metadata-tools` package to provide a streamlined approach to configuring your OApp connections. It allows for a more simplified LayerZero config file.

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

<Warning>
  **Production deployments should use multiple required DVNs from independent operators.** The examples below use `<SECONDARY_DVN>` as a placeholder so that the config does not silently resolve to a single-DVN configuration. Replace it with a real DVN name from [DVN Addresses](/v2/deployments/dvn-addresses) before wiring. See the [Integration Checklist](/v2/tools/integration-checklist#set-security-and-executor-configurations-on-every-pathway) for production DVN guidance.
</Warning>

Here's how to use it:

1. Install metadata-tools: `pnpm add -D @layerzerolabs/metadata-tools`

2. Create a new [LZ config](/v2/concepts/glossary#lz-config) file named `layerzero.config.ts` (or edit your existing one) in the project root and use the examples below as a starting point:

<CodeGroup>
  ```typescript wrap EVM Chains Only theme={null}
     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 avalancheContract: OmniPointHardhat = {
       eid: EndpointId.AVALANCHE_V2_TESTNET,
       contractName: 'MyOFT',
     };

     const polygonContract: OmniPointHardhat = {
       eid: EndpointId.AMOY_V2_TESTNET,
       contractName: 'MyOFT',
     };

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

     export default async function () {
       // note: pathways declared here are automatically bidirectional
       // if you declare A,B there's no need to declare B,A
       const connections = await generateConnectionsConfig([
         [
           avalancheContract, // Chain A contract
           polygonContract, // Chain B contract
           [['LayerZero Labs', '<SECONDARY_DVN>'], []], // [ requiredDVN[], [ optionalDVN[], threshold ] ]
           [1, 1], // [A to B confirmations, B to A confirmations]
           [EVM_ENFORCED_OPTIONS, EVM_ENFORCED_OPTIONS], // Chain B enforcedOptions, Chain A enforcedOptions
         ],
       ]);

       return {
         contracts: [{contract: avalancheContract}, {contract: polygonContract}],
         connections,
       };
     }
  ```

  ```typescript wrap EVM + Solana theme={null}
     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';

     export const avalancheContract: OmniPointHardhat = {
       eid: EndpointId.AVALANCHE_V2_TESTNET,
       contractName: 'MyOFT',
     };

     export const solanaContract: OmniPointHardhat = {
       eid: EndpointId.SOLANA_V2_TESTNET,
       address: 'HBTWw2VKNLuDBjg9e5dArxo5axJRX8csCEBcCo3CFdAy', // your OFT Store address
     };

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

     const SOLANA_ENFORCED_OPTIONS: OAppEnforcedOption[] = [
       {
         msgType: 1,
         optionType: ExecutorOptionType.LZ_RECEIVE,
         gas: 200000,
         value: 2039280, // SPL token account rent value in lamports
       },
     ];

     export default async function () {
       // note: pathways declared here are automatically bidirectional
       // if you declare A,B there's no need to declare B,A
       const connections = await generateConnectionsConfig([
         [
           avalancheContract, // Chain A contract
           solanaContract, // Chain B contract
           [['LayerZero Labs', '<SECONDARY_DVN>'], []], // [ requiredDVN[], [ optionalDVN[], threshold ] ]
           [1, 1], // [A to B confirmations, B to A confirmations]
           [SOLANA_ENFORCED_OPTIONS, EVM_ENFORCED_OPTIONS], // Chain B enforcedOptions, Chain A enforcedOptions
         ],
       ]);

       return {
         contracts: [{contract: avalancheContract}, {contract: solanaContract}],
         connections,
       };
     }
  ```
</CodeGroup>

* Note that only the Solana contract object requires `address` to be specified. Do not specify `address` for non-Solana contract objects.
* The above examples contain a minimal mesh with only one pathway (two chains) for demonstration purposes. You are able to add as many pathways as you need into the `connections` param, via `generateConnectionsConfig`.

3. If your pathways include Solana, run the Solana init config command:

```
npx hardhat lz:oft:solana:init-config --oapp-config layerzero.config.ts
```

4. Run the wire command:

<Tabs>
  <Tab title="EVM Only">
    ```bash wrap theme={null}
    npx hardhat lz:oapp:wire --oapp-config layerzero.config.ts
    ```

    The wire command processes all the transactions required to connect all pathways specified in the LZ Config file. You need to only run this once regardless of how many pathways there are. If you change anything in the LZ Config file, then it should be run again.
  </Tab>

  <Tab title="EVM + Solana">
    ```bash wrap theme={null}
    npx hardhat lz:oapp:wire --oapp-config layerzero.config.ts
    ```
  </Tab>
</Tabs>

## Key Features

* **Automatic Bidirectional Connections**: Define one pathway, get both directions automatically
* **Streamlined defaults**: Sensible structure for DVN and executor configuration that you must review and override per pathway (see Warning above)
* **Cross-VM Compatibility**: Works seamlessly with EVM chains and Solana
* **Reduced Complexity**: Fewer configuration parameters to manage
* **Less Error-Prone**: Automated configuration generation reduces manual errors

## Configuration Parameters

### Pathway Definition

```typescript wrap theme={null}
[
  contractA, // Source chain contract
  contractB, // Destination chain contract
  [['LayerZero Labs', '<SECONDARY_DVN>'], []], // DVN configuration
  [1, 1], // Confirmations for each direction
  [optionsA, optionsB], // Enforced options for each direction
];
```

### DVN Configuration

```typescript wrap theme={null}
[['LayerZero Labs', '<SECONDARY_DVN>'], []]; // [ requiredDVN[], [ optionalDVN[], threshold ] ]
```

* **Required DVNs**: Must verify the message for it to be considered valid
* **Optional DVNs**: Additional verifiers (with threshold) for enhanced security

### Enforced Options

```typescript wrap theme={null}
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>
  **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.
</Note>

## Next Steps

* **Migrate from Manual Config**: See the [Migrate to Simple Config](/v2/tools/migrate-to-simple-config) guide
* **Production Deployment**: Review and adjust settings for production environments
* **Gas Optimization**: Profile your contracts to set optimal gas limits
* **Custom DVNs**: Consider adding custom DVNs for enhanced security
