# Customizable Message Transmission Options

UIP allows users to tailor message transmission settings to meet specific application requirements, balancing priorities like speed and security. These options are encoded and stored in the encoded parameter option, enabling agents to execute transactions in line with user-defined preferences.&#x20;

## Propose Function

This function emits an event from the smart contract, which is picked up by our agents. The agents decode the event to extract details such as the destination chain, the message content, the block finalization option, any custom gas limits, and other relevant information. Once decoded, the message is transmitted to our EIB chain for further processing.

```solidity
function propose(
    uint256 destChainID,
    bytes32 selectorSlot,
    bytes calldata encodedParams,
    bytes calldata destAddress,
    bytes calldata payload
) external payable {
    _propose(
        _msgSender(), 
        destChainID, 
        selectorSlot, 
        agentParams, 
        destAddress, 
        payload
    );
}
```

<details>

<summary>Solidity Example Code</summary>

```solidity
function sendMessage(
        uint256 chainID,
        uint256 blockFinalizationOption,
        uint256 customGasLimit,
        bytes calldata destAddress,
        string calldata _msg
    ) external payable {
        TransmitterParamsLib.TransmitterParams memory transmitterParams = TransmitterParamsLib.TransmitterParams(
            blockFinalizationOption,
            customGasLimit
        );
        bytes memory encodedParams = abi.encodePacked(transmitterParams.blockFinalizationOption, transmitterParams.customGasLimit);
        
        IEndpoint(endpoint).propose{value: msg.value}(
            chainID,
            SelectorLib.encodeDefaultSelector(
                DEFAULT_SELECTOR
            ),
            encodedParams,
            destAddress,
            abi.encode(abi.encode(_msg), abi.encode(_msgSender()))
        );
    }
```

</details>

<details>

<summary>Solana Example Code</summary>

We're currently working on Solana integration as part of our next milestone. We have prepared guides for teams and developers interestered in early access. To learn more or request access, visit our [contact page](https://entangle.zendesk.com/hc/en-us/requests/new).

</details>

### Parameter Definitions

<table><thead><tr><th width="205.99993896484375">Parameter</th><th>Description</th></tr></thead><tbody><tr><td>destChainID</td><td>The identifier of the destination chain.</td></tr><tr><td>selectorSlot</td><td>A default selector for the <code>execute</code> function in the endpoint contract (this value should remain unchanged).</td></tr><tr><td>encodedParams</td><td>Encoded parameters such as <code>blockFinalizationOption</code> and <code>customGasLimit</code> in<code>byte</code> format (details on creating these parameters are provided below).</td></tr><tr><td>destAddress</td><td>The address of the recipient on the destination chain.</td></tr><tr><td>payload</td><td>The payload is any data which should be carried to the destination chain. Use <code>abi.encode(...)</code> to convert your data into "bytes" format.</td></tr></tbody></table>

### Encoded Parameter Option Definitions

The transmission options are stored in a struct called the  `TransmitterParams`.  For up-to-date parameter definitions please refer to the latest implementation of the `TransmitterParamsLib`.

```solidity
struct TransmitterParams {
    uint256 blockFinalizationOption;
    uint256 customGasLimit;
}
```

The transmission options descriped below are then encoded into bytes and stored in the `encodedParams` parameter of the propse function.

<table><thead><tr><th width="205.99993896484375">Option</th><th>Description</th></tr></thead><tbody><tr><td>blockFinalizationOption</td><td>Defines the number of blocks to wait before retrieving message events from the source chain and execution events from the destination chain.</td></tr><tr><td>customGasLimit</td><td>Specifies the gaslimit for transaction execution on destination chain.</td></tr></tbody></table>

### Encoding Parameters

To encode these parameters into bytes, use the `abi.encodePacked()` function and pass in the `TransmitterParams` options one by one, as shown in the example below.

```solidity
bytes memory encodedParams = abi.encodePacked(transmitterParams.blockFinalizationOption, transmitterParams.customGasLimit);
```

## Block Finalization

UIP gives full control to developers. One such way is via the block finalization option which allows you to fine tune the block wait time. By default the standard type is recommended and used. However, if you wish to use another option, we provide extra details and use cases for each finalization type.

### Block Finalization Option Descriptions

{% hint style="danger" %}
Warning: Use the "Unsafe" option with **EXTREME CAUTION**. By selecting it, you explicitly acknowledge and accept the risk that the transaction or event might be reverted due to a block reorg. This could lead to data inconsistency or financial loss.
{% endhint %}

<table><thead><tr><th width="140.3333740234375">Finalization Type</th><th>Description</th></tr></thead><tbody><tr><td>Standard</td><td>The default and safest option. It adheres to the full finalization process defined by the source network. This ensures the highest or close to the highest level of security and immutability.</td></tr><tr><td>Fast</td><td>Prioritizes speed while maintaining a reasonable level of safety. It uses a reduced finalization process that is less strict than Standard Finalization but still guarantees secure delivery.</td></tr><tr><td>Unsafe</td><td>The fastest option, but it bypasses standard finalization processes. This dramatically reduces confirmation time but introduces the risk of block restructuring (reorgs).</td></tr></tbody></table>

### Block Finalization Option Behaviour Explanations

<table><thead><tr><th width="140.3333740234375">Finalization Type</th><th>Behaviour</th></tr></thead><tbody><tr><td>Standard</td><td>Confirmation occurs only after the standard block finalization period (or block depth) specified by the source network has elapsed.</td></tr><tr><td>Fast</td><td>Confirmation occurs after a minimal finalization process, ensuring the block sequence is unlikely to be reverted.</td></tr><tr><td>Unsafe</td><td>Confirmation is immediate or near-immediate, based on minimal criteria. There's no guarantee that the confirmed transaction will be permanent.</td></tr></tbody></table>

### Block Finalization Option Use Cases

<table><thead><tr><th width="140.3333740234375">Finalization Type</th><th>Use Case</th></tr></thead><tbody><tr><td>Standard</td><td>Recommended for applications handling high-value transactions or where data integrity is paramount.</td></tr><tr><td>Fast</td><td>Suitable for most applications.</td></tr><tr><td>Unsafe</td><td>Only recommended for experimental purposes, low-value transactions where the risk of reorg is acceptable, or in specific scenarios where immediate confirmation is more critical than data integrity (e.g., certain types of data feeds where eventual consistency is sufficient). Thoroughly understand the implications before using this option.</td></tr></tbody></table>

### Recommended Values for Block Finalization

Below is a list of recommended values for block finalization for different networks and finalization types.

| Network   | Standard | Fast | Unsafe |
| --------- | -------- | ---- | ------ |
| Base      | 195      | 30   | 1      |
| Entangle  | 1        | 1    | 1      |
| Ethereum  | 32       | 12   | 1      |
| Mantle    | 195      | 30   | 1      |
| Avalanche | 5        | 2    | 1      |
| Sonic     | 20       | 10   | 1      |
| Polygon   | 100      | 50   | 1      |
| Solana    | 32       | 16   | 2      |
| Berachain | 5        | 2    | 1      |
| Binance   | 40       | 5    | 1      |
| Arbitrum  | 1500     | 240  | 5      |
| Abstract  | 900      | 20   | 1      |
| Manta     | 40       | 5    | 1      |
| Immutable | 195      | 20   | 1      |
| Optimism  | 195      | 30   | 1      |
