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

# How the Hyperlane prover works

> Cross-chain verification using Hyperlane's modular interoperability stack

The Hyperlane Prover enables cross-chain intent verification using Hyperlane's modular interoperability stack. It receives messages via `IMessageRecipient` and extends `MessageBridgeProver` for common proving functionality.

## Architecture

```
Destination Chain                Source Chain
━━━━━━━━━━━━━━━━                ━━━━━━━━━━━━━━
Portal                           Portal
    ↓                                ↑
HyperProver                      HyperProver
    ↓                                ↑
Hyperlane Mailbox ──────────→ Hyperlane Mailbox
```

## Configuration

```solidity theme={null}
constructor(
    address mailbox,          // Hyperlane mailbox on this chain
    address portal,           // Portal contract address
    bytes32[] memory provers  // Trusted prover addresses on other chains
)
```

**Key Points:**

* `mailbox`: Chain-specific Hyperlane mailbox address
* `portal`: Portal contract that initiates proving
* `provers`: Whitelist of trusted provers on source chains (bytes32 format for cross-VM compatibility)
* `minGasLimit`: Set to 0 in constructor (no minimum enforced, unlike LayerZero)

## Proving Flow

### Sending Proofs (Destination → Source)

Called by Portal after intent fulfillment:

```solidity theme={null}
portal.prove{value: fee}(
    address(prover),
    sourceChainDomainID,
    intentHashes,
    data
);
```

**Data Parameter:**

```solidity theme={null}
abi.encode(
    HyperProver.UnpackedData({
        sourceChainProver: bytes32(uint256(uint160(sourceProverAddress))),
        metadata: bytes(""),        // Hyperlane metadata or empty for default
        hookAddr: address(0)        // Post-dispatch hook or zero for default
    })
)
```

### Receiving Proofs (Source Chain)

Hyperlane mailbox calls `handle()` with message containing:

* 8 bytes: destination chain ID
* 64 bytes per intent: `[intentHash (32 bytes)][claimant (32 bytes)]`

```solidity theme={null}
function handle(
    uint32 origin,
    bytes32 sender,
    bytes calldata messageBody
) public payable
```

Only whitelisted senders accepted via `isWhitelisted(sender)`.

## Fee Calculation

```solidity theme={null}
function fetchFee(
    uint64 domainID,
    bytes calldata encodedProofs,
    bytes calldata data
) public view returns (uint256)
```

Queries Hyperlane mailbox using `quoteDispatch()` for accurate fee. Always call before proving to avoid reverts.

## Domain IDs

**Critical:** Hyperlane uses custom domain IDs, not chain IDs.

```solidity theme={null}
params.destinationDomain = uint32(domainID);
```

The `sourceChainDomainID` parameter must be Hyperlane's domain ID. Consult [Hyperlane Documentation](https://docs.hyperlane.xyz/docs/reference/domains) for mappings.

**Example:**

* Ethereum: Chain ID 1 → Domain ID 1
* Arbitrum: Chain ID 42161 → Domain ID 42161
* Optimism: Chain ID 10 → Domain ID 10

Note: Many Hyperlane domains match chain IDs, but not all (e.g., testnets).

## Metadata and Hooks

### Default Configuration

```solidity theme={null}
metadata: bytes("")
hookAddr: address(0)
```

Uses mailbox's default hook:

```solidity theme={null}
params.hook = IMailbox(MAILBOX).defaultHook();
```

### Custom Hook

Specify custom post-dispatch hook for advanced configurations:

```solidity theme={null}
HyperProver.UnpackedData({
    sourceChainProver: sourceProver,
    metadata: customMetadata,
    hookAddr: customHookAddress
})
```

**Hook Use Cases:**

* Custom gas payment strategies
* Message aggregation
* Alternative security models

### Metadata

Pass custom metadata for hook configuration:

```solidity theme={null}
metadata: encodedMetadata
```

Metadata format depends on the hook being used. See Hyperlane documentation for hook-specific encoding.

## Security

### Whitelisting

Only provers in the whitelist can send messages:

```solidity theme={null}
function isWhitelisted(bytes32 sender) internal view returns (bool)
```

### Access Control

* Only Hyperlane mailbox can call `handle()`
* Only Portal can call `prove()`
* Zero domain ID rejected: `if (origin == 0) revert ZeroDomainID()`

### Validation

Sender validation in `handle()`:

```solidity theme={null}
if (sender == bytes32(0)) revert SenderCannotBeZeroAddress();
```

## Integration Example

```solidity theme={null}
// Deploy prover
bytes32[] memory trustedProvers = new bytes32[](1);
trustedProvers[0] = bytes32(uint256(uint160(ethereumProverAddress)));

HyperProver prover = new HyperProver(
    hyperlaneMailbox,  // Chain-specific mailbox
    portalAddress,
    trustedProvers
);

// Fulfill and prove
bytes memory proverData = abi.encode(
    HyperProver.UnpackedData({
        sourceChainProver: bytes32(uint256(uint160(ethereumProver))),
        metadata: "",
        hookAddr: address(0)  // Use default hook
    })
);

uint256 fee = prover.fetchFee(1, encodedProofs, proverData);

portal.fulfillAndProve{value: route.nativeAmount + fee}(
    intentHash,
    route,
    rewardHash,
    claimant,
    address(prover),
    1,  // Ethereum domain ID
    proverData
);
```

## Advantages

* **Lower Costs**: Generally cheaper than LayerZero
* **Modular Security**: Flexible hook system for custom security models
* **Simpler Configuration**: No delegate setup, domain IDs often match chain IDs
* **Transparent Security**: Open-source validators and relayers

## Limitations

* **Smaller Chain Coverage**: \~30 chains vs LayerZero's 50+
* **Less Mature Tooling**: Fewer third-party integrations and explorers
* **Hook Complexity**: Advanced features require understanding hook system
* **Bridge Dependency**: Relies on Hyperlane infrastructure availability

## Errors

* `MailboxCannotBeZeroAddress()`: Invalid mailbox in constructor
* `ZeroDomainID()`: Origin domain is zero in handle()
* `SenderCannotBeZeroAddress()`: Zero sender in handle()
* `DomainIdTooLarge(uint64)`: Domain ID exceeds uint32.max
* `NonPortalCaller(address)`: Unauthorized prove() caller
* `NotWhitelisted(bytes32)`: Sender not in whitelist

## Constant

```solidity theme={null}
string public constant PROOF_TYPE = "Hyperlane";
```

Identifies this prover's mechanism type.
