On this page

Destination composition

An Omniasset transfer can queue an optional LayerZero lzCompose call after the destination token is minted or unlocked. This lets builders add actions such as an order fill, vault deposit, or protocol notification without putting application failure inside bridge accounting.

Compose parameters

struct ComposeParams {
    address composer;
    uint128 gasLimit;
    bytes message;
}

Pass the same struct to quote and send:

Omnisea.ComposeParams memory compose = Omnisea.ComposeParams({
    composer: destinationApp,
    gasLimit: 300_000,
    message: abi.encode(action)
});

uint256 fee = bridge.quoteSendOriginal(
    dstEid, token, amount, recipient, isFirstTransfer, compose, options
);

bridge.sendOriginal{value: fee}(
    dstEid, token, amount, recipient, isFirstTransfer, compose, options
);

A plain transfer uses composer = address(0), gasLimit = 0, and an empty message.

Authentication

Inherit OmniseaComposer and implement _lzCompose:

contract DestinationApp is OmniseaComposer {
    constructor(address endpoint, address router)
        OmniseaComposer(endpoint, router) {}

    function _lzCompose(
        ComposeEnvelope memory envelope,
        address executor,
        bytes calldata extraData
    ) internal override {
        // envelope.localToken, recipient, amount, origin and app message
    }
}

The base contract requires msg.sender to be the local LayerZero endpoint and _from to be the local Omnisea Router. It also decodes the versioned envelope and applies a reentrancy guard.

Financial and notification flows

  • For a financial action, make the composer the bridge recipient. The tokens are in the composer before _lzCompose runs.
  • For a notification, keep the user as recipient. The composer receives the transfer context but no tokens.

Composition is independent from bridge credit. If the composer reverts, LayerZero can retry that compose call without minting or unlocking again. The composer should still be idempotent by GUID and expose a safe refund or claim path for any funds it controls.

Live financial composer

OmniMorphoBorrowComposer is the first live financial composer. A WBNB or BTCB transfer from BNB Chain credits omWBNB or omBTCB to the composer on Base. The authenticated callback then supplies that exact amount to the sender's Morpho position and borrows Base USDC to the selected receiver.

Expected market, authorization, oracle, supply, borrow, and LTV failures are caught inside the composer. Morpho effects roll back before it returns or records the arriving destination Omniasset. This makes a handled business failure a completed composition with a refund outcome, rather than a LayerZero retry that could repeat application intent.

The composer rejects duplicate GUIDs and keeps pending refunds separate by GUID and beneficiary. Read Borrow USDC cross-chain for the flow and Morpho Omnimarket contracts for its state and recovery model.

Gas

The LayerZero options must buy both normal lzReceive gas and index-0 lzCompose gas at least equal to ComposeParams.gasLimit. Read Executor options for the encoding.

Experimental Beta is Live-Learn more about the Pilot