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

# OApp Technical Reference

> LayerZero’s Omnichain Application (OApp) standard defines a common set of patterns and interfaces for any smart contract that needs to send and receive...

LayerZero’s **Omnichain Application (OApp)** standard defines a common set of patterns and interfaces for any smart contract that needs to send and receive messages across multiple blockchains. By inheriting OApp’s core functionality, higher-level primitives (such as OFT, ONFT, or any custom crosschain logic) can rely on a unified, secure messaging layer.

All OApp implementations must handle:

* **Message sending**: Encode and dispatch outbound messages
* **Message receiving**: Decode and process inbound messages
* **Fee handling**: Quote, collect, and refund native & ZRO fees
* **Peer management**: Maintain trusted mappings between chains
* **Channel management and security**: Control security and execution settings between chains

## Deployment

Every OApp needs to be deployed on each chain where it will operate. Initialization involves two steps:

### 1. Integrate with the local Endpoint

1. Pass the local Endpoint V2 address into your constructor or initializer.
2. The Endpoint’s delegate authority is set to your OApp and the address initializing unless overridden.
3. As a delegate, your OApp can call any `endpoint.*` security method (`setSendLibrary`, `setConfig`, etc.) in a secure, authorized manner.

### 2. Configure peers (directional peering)

1. On each chain, the owner calls `setPeer(eid, peerAddress)` to register the remote OApp’s address for a given Endpoint ID.
2. Repeat on the destination chain: register the source chain’s OApp address under its Endpoint ID.
3. Because trust is directional, the receiving OApp checks `peers[srcEid] == origin.sender` before processing inbound messages.

<Info>
  For guidelines on channel security, see [**Message Channel Security**](../protocol/message-security). For an example implementation, see the [**OFT Technical Reference**](./oft-reference).
</Info>

## Core Message Flow

OApps follow a three-step life cycle. Developers focus on local state changes and message encoding; LayerZero handles secure routing and final delivery.

| Phase                   | Actors                       | Responsibility                                               |
| ----------------------- | ---------------------------- | ------------------------------------------------------------ |
| **1. `send(...)`**      | OApp                         | Perform local state change and encode the message            |
| **3. Transport**        | LayerZero, DVNs, & Executors | Build, verify, and route the packet to the destination chain |
| **4. `lzReceive(...)`** | OApp                         | Validate origin, decode message, apply state change          |

### 1. `send(...)` Entrypoint

* **Developer-defined logic**
  1. Perform a local state change (e.g., burn or lock tokens, record intent).
  2. Encode all necessary data (addresses, amounts, or arbitrary instructions) into a byte array.
  3. Optionally accept execution options (gas limits, native gas transfers, or LayerZero Executor services).
* **Key points**
  * Your public `send(...)` handles only local logic and message construction.
  * All packet assembly, peer lookup, and fee handling occur inside the internal call to `endpoint.send(...)`.

### 2. Transport and Routing

* **Fee payment and validation**
  1. Ensure the caller has supplied exactly the required native or ZRO fee.
  2. When `endpoint.send(...)` executes, the Endpoint verifies that the fees match the quote from the chosen messaging library. Underpayment causes a revert.
* **Packet construction and dispatch**
  1. The Endpoint computes the next outbound nonce for `(sender, dstEid, receiver)` and builds a `Packet` struct with `nonce`, `srcEid`, `sender`, `dstEid`, `receiver`, `GUID`, and the raw `message`.
  2. It looks up which send library to use, either a per-OApp override or a default, for `(sender, dstEid)`.
  3. The send library serializes the `Packet` into an `encodedPacket` and returns a `MessagingFee` struct.
  4. The Endpoint emits a `PacketSent(...)` event so DVNs and Executors know which packet to process.
* **DVNs & Executors**
  * Paid DVNs pick up the packet, verify its integrity, and relay it to the destination chain’s Endpoint V2.
  * The destination library enforces DVN verification and block-confirmation requirements based on your receive config.
* **Destination Endpoint validation**
  1. Verify that the packet’s `srcEid` has a registered peer.
  2. Confirm that `origin.sender` matches `peers[srcEid]`.
* **Invoke `lzReceive(...)`**
  * If validation succeeds, the destination Endpoint calls your OApp’s public `lzReceive(origin, guid, message, executor, extraData)`.

### 3. `lzReceive(...)` Entrypoint

* **Access control and peer check**
  * Only the Endpoint may call `lzReceive`.
  * Immediately validate that `_origin.sender == peers[_origin.srcEid]`.
* **Internal `_lzReceive(...)` logic**
  1. Decode the byte array into original data types (addresses, amounts, or instructions).
  2. Execute the intended onchain business logic (e.g., mint tokens, unlock collateral, update balances).
  3. If there’s a composable hook, your OApp can invoke `sendCompose(...)` to bundle further crosschain calls.
* **Outcome**
  * Upon completion, the destination chain’s state reflects the source chain’s intent. Any post-processing (events, composable calls) occurs here.

This clear separation between local state updates in `send(...)` versus remote updates in `_lzReceive(...)` lets you focus on business logic while LayerZero’s Endpoint V2 manages transport intricacies.

## Security and Channel Management

Whether you’re using Solidity, Rust, or Move, these foundational patterns ensure consistent security, extensibility, and developer ergonomics.

### Security and roles

* **Owner**
  * Manages delegates, peers, and enforced gas settings
  * `setPeer(...)`: update trust mappings
  * `setDelegate(...)`: assign a new delegate for Endpoint configurations
  * `setEnforcedOptions(...)`: define per-chain minimum gas for inbound execution
* **Delegate**
  * Manages Endpoint settings and message-channel controls
  * `setSendLibrary(oappAddress, eid, newLibrary)`: override send library for `(oappAddress, eid)`.
  * `setReceiveLibrary(oappAddress, eid, newLibrary, gracePeriod)`: override receive library; `gracePeriod` lets the previous library handle retries.
  * `setReceiveLibraryTimeout(oappAddress, eid, library, newTimeout)`: update how long an old receive library remains valid.
  * `setConfig(oappAddress, libraryAddress, params[])`: adjust per-library settings (DVNs, Executors, confirmations).
  * `skip(oappAddress, srcEid, srcSender, nonce)`: advance the inbound nonce without processing when verification fails.
  * `nilify(oappAddress, srcEid, srcSender, nonce, payloadHash)`: treat the payload as empty and advance the inbound nonce.
  * `burn(oappAddress, srcEid, srcSender, nonce, payloadHash)`: permanently discard a malicious or irrecoverable payload.
    <Tip>
      Use multisigs or your preferred governance to manage Owner and Delegate roles.
    </Tip>

### Peering and Trust Management

* **`peers` mapping**
  * Store a mapping from `eid → bytes32 peerAddress`. Using `bytes32` lets you store addresses for various chains.
  * `setPeer(eid, peerAddress)` updates that mapping. Passing `bytes32(0)` disables the pathway.
* **Directional trust**
  * Registering on Chain A → Chain B does not register the reverse. Each side must call `setPeer` for the other.
  * On receipt, enforce `peers[origin.srcEid] == origin.sender` to confirm the message is from the expected contract.
* **Updating peers**
  * If you redeploy or upgrade an OApp, call `setPeer` on both old and new deployments to maintain continuity.

## Further Reading

* **[Message Channel Security](../protocol/message-security)**\
  Deep dive into Endpoint V2's cryptographic guarantees, signature verification, and relayer/oracle incentives.
* **[OFT Technical Reference](./oft-reference)**\
  A concrete OApp example for fungible token transfers, illustrating how to use OApp's core patterns without platform-specific code.
* **[Omnichain Composability](../applications/composer-standard)**\
  Patterns for building advanced crosschain primitives (AMM routers, multi-chain staking, governance) on top of OApp's hooks and the Executor model.
