> ## 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.

# Read CLI Setup Guide

> To start leveraging LayerZero Read (`lzRead`), LayerZero offers CLI examples that streamline the setup and configuration process, similar to the standard...

To start leveraging LayerZero Read (`lzRead`), LayerZero offers CLI examples that streamline the setup and configuration process, similar to the standard CLI examples provided for other LayerZero functionalities.

## Using the Read CLI

To begin using `lzRead`, follow the steps below. These instructions utilize the same commands as the standard setup for OApps but include minor adjustments specific to configuring read capabilities.

### Create Your lzRead Repo

Run the following command to create a new LayerZero OApp with read capabilities enabled:

```
LZ_ENABLE_READ_EXAMPLE=1 npx create-lz-oapp@latest
```

This command initializes a new project with the necessary configurations to support lzRead. The project creation wizard will guide you through selecting a template and setting up your development environment.

```bash wrap theme={null}
✔ Where do you want to start your project? … ./my-lz-read-oapp
✔ Which example would you like to use as a starting point? › OApp Read
✔ What package manager would you like to use in your project? › pnpm
```

This will set up a repository with example contracts, crosschain unit tests for read operations, custom LayerZero read configuration files, deployment scripts, and more.

Follow the normal setup process defined above (adding networks to your `hardhat.config.ts`, adding your `MNEMONIC` or` PRIVATE_KEY` to `.env`, etc.)

```typescript wrap theme={null}
// hardhat.config.ts
import { EndpointId } from '@layerzerolabs/lz-definitions';

networks: {
  ethereum: {
    eid: EndpointId.ETHEREUM_V2_MAINNET,
    url: process.env.RPC_URL_ETHEREUM,
    accounts,
  },
  arbitrum: {
    eid: EndpointId.ARBITRUM_V2_MAINNET,
    url: process.env.RPC_URL_ARBITRUM,
    accounts,
  },
  polygon: {
    eid: EndpointId.POLYGON_V2_MAINNET,
    url: process.env.RPC_URL_POLYGON,
    accounts,
  },
},
```

Refer to the [LayerZero Endpoint Addresses](../../../deployments/deployed-contracts) to ensure the networks you add have deployed endpoints.

To see a list of available commands, run `npx hardhat`:

```bash wrap theme={null}
lz:read:resolve-command             Task for debugging read commands
lz:oapp-read:wire                   Wire LayerZero Read OApp
lz:oapp-read:config:get             Get Read OApp configuration
lz:oapp-read:config:init            Initialize Read OApp configuration
lz:oapp-read:config:get:channel     Get information of read channels for networks
```

Each command serves a specific purpose in managing and configuring your lzRead setup.

All of the standard CLI methods available in the [LayerZero CLI Setup Guide](../../../get-started/create-lz-oapp/start) can also be found in this newly initialized project. Take some time to familiarize yourself with the project commands and layout.

In general each of the `lzRead` CLI methods have been modified from the base CLI, so all `lz:oapp:` and `lz:oapp:read` methods should behave similarly.

### Configure LayerZero Config

Unlike standard OApp configurations, `lzRead` requires specific settings in the `layerzero.config.ts` file. Instead of configuring `connections`, you'll focus solely on defining `contracts` and `read channels`:

```typescript wrap theme={null}
// layerzero.config.ts
import {ChannelId, EndpointId} from '@layerzerolabs/lz-definitions';
import {OAppReadOmniGraphHardhat} from '@layerzerolabs/oapp-evm';
import {ethers} from 'ethers';

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

const config: OAppReadOmniGraphHardhat = {
  contracts: [
    {
      contract: arbitrumContract, // Dummy contract address
      config: {
        readLibrary: '0xbcd4CADCac3F767C57c4F402932C4705DF62BEFf',
        readChannels: [
          {
            channelId: ChannelId.READ_CHANNEL_1,
            active: true,
          },
        ],
        readConfig: {
          ulnConfig: {
            requiredDVNs: ['0x1308151a7ebac14f435d3ad5ff95c34160d539a5'],
            executor: '0x31CAe3B7fB82d847621859fb1585353c5720660D',
          },
        },
      },
    },
  ],
  connections: [], // No connections needed for read-only setup
};

export default config;
```

You can generate this config file based on the networks specified in your `hardhat.config.ts` by running:

```bash wrap theme={null}
npx hardaht lz:oapp-read:config:init --contract-name <READ_CONTRACT_NAME> --oapp-config <NEW_CONFIG_FILE_NAME>
```

This will produce a new `layerzero.config.ts` file based on the `READ_CONTRACT_NAME` and available networks in your hardhat project.

Key configuration details include:

* `contracts`: Define the contracts you intend to interact with. In this example, the origin chain Arbitrum has the child `OAppRead` contract address.

* `readLibrary`: The address of the Read Library (`ReadLib1002`) contract deployed on your network.

* `readChannels`: Specify the read channels you want to activate.

* `readConfig`: Configure the Read Library settings, including required Decentralized Verifier Networks (DVNs) and the executor address.

### Wire Your Read OApp

After configuring `layerzero.config.ts`, execute the following command to wire your Read OApp:

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

This command sets up the necessary connections and configurations based on your `layerzero.config.ts` file, enabling your OApp to perform read operations.

### Debugging Malformed or Unresolvable Commands

LayerZero provides a Hardhat task to assist in debugging and resolving read commands. This task helps identify and troubleshoot issues with your read commands.

To resolve a read command, run the following command in your terminal:

```bash wrap theme={null}
npx hardhat lz:read:resolve-command --command <READ_COMMAND>
```

If the command is correctly formed and resolvable, the task will provide the expected target data.

If the command is [Malformed](./overview#debugging-read-commands) or [Unresolvable](./overview#debugging-read-commands), the task will output relevant error messages to help you pinpoint the issue.

Based on the feedback from the resolver task, make necessary adjustments to your command construction or target contract configurations.

### Testing Contracts

Ensuring the reliability of your `lzRead` setup involves thorough testing. LayerZero provides a `TestHelper` tailored for Foundry unit tests, enabling you to simulate crosschain reads in your tests.

For lzRead, this helper has been extended to support read-specific functionalities. Some limitations of this testing method should be understood:

* **Command Validation**: Does not simulate whether a command is `malformed` or `unresolvable`.

To fully ensure contract functionality, it's recommended to conduct tests on mainnet even after unit testing, to ensure that the mocked state in your unit tests matches the behaviour found onchain.
