xhavic.com
GitHub (Coming Soon) Whitepaper
Docs / Bridging

Cross-Chain Messaging

How to send arbitrary messages between Ethereum and Xhavic for cross-chain contract calls.

Beyond asset transfers, the Xhavic bridge supports arbitrary message passing between Ethereum (L1) and Xhavic (L2). This enables cross-chain contract calls, governance execution, and multi-chain application logic.

How Messaging Works

L1 โ†’ L2 Messages

  1. Call the L1CrossDomainMessenger contract on Ethereum with your message
  2. The message is included in the next deposit batch
  3. The L2CrossDomainMessenger on Xhavic relays the message to the target contract
  4. The target contract executes with the original L1 sender as msg.sender (via xDomainMessageSender)

L2 โ†’ L1 Messages

  1. Call the L2CrossDomainMessenger contract on Xhavic
  2. The message is included in the next state root batch posted to L1
  3. After the 7-day challenge period, the message can be relayed on L1
  4. The L1CrossDomainMessenger delivers the message to the target contract

Message Parameters

DirectionLatencySecurity
L1 โ†’ L2~5-15 minutesInherits L1 finality
L2 โ†’ L1~7 daysRequires challenge period

Sending a Message (L1 โ†’ L2)

// On Ethereum
IL1CrossDomainMessenger messenger = IL1CrossDomainMessenger(messengerAddress);

messenger.sendMessage(
    l2TargetContract,    // Target contract on Xhavic
    abi.encodeCall(       // Encoded function call
        ITarget.doSomething,
        (param1, param2)
    ),
    500_000              // L2 gas limit
);

Sending a Message (L2 โ†’ L1)

// On Xhavic
IL2CrossDomainMessenger messenger = IL2CrossDomainMessenger(messengerAddress);

messenger.sendMessage(
    l1TargetContract,    // Target contract on Ethereum
    abi.encodeCall(
        ITarget.executeAction,
        (param1)
    ),
    200_000              // L1 gas limit
);

Receiving Messages

Target contracts verify the message origin using the messengerโ€™s xDomainMessageSender():

function onlyFromL1() external {
    require(
        msg.sender == address(crossDomainMessenger),
        "Not from messenger"
    );
    require(
        crossDomainMessenger.xDomainMessageSender() == trustedL1Contract,
        "Not from trusted L1 contract"
    );
    // Process message...
}

Use Cases

  • Governance โ€” DAO votes on L1 trigger parameter changes on L2
  • Token bridging โ€” Custom token bridges with application-specific logic
  • Oracle relaying โ€” Push L1 data (block hashes, prices) to L2 contracts
  • Multi-chain dApps โ€” Coordinate state between L1 and L2 deployments

Message Replay Protection

Each message includes a unique nonce to prevent replay attacks. Messages can only be relayed once and are marked as completed after execution.