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

# Messaging flow

> LI.FI Messaging flow Documentation

# LI.FI Messaging Flow Documentation

## Overview

LI.FI Messaging Flow enables seamless interactions with centralized and hybrid exchanges that use message-based APIs (such as Hyperliquid) instead of traditional on-chain transactions. **This flow delivers gasless, approval-free operations for cross-chain transfers involving protocols that operate with off-chain signed messages.**

Traditional DeFi operations require users to send on-chain transactions, manage gas fees, and approve token spending for each interaction. Messaging flow eliminates these friction points by using off-chain signed messages (EIP-712) that are relayed to destination protocols through LI.FI's backend infrastructure.

## Key Benefits of Messaging Flow

* **No Token Approvals Required**: Unlike transaction-based flows, messaging flow doesn't require users to approve token spending
* **Gasless Operations**: Users sign messages off-chain without paying gas fees for the message itself (some operation might require fee payments, not gas)
* **Asynchronous Execution**: Messages are relayed and processed asynchronously, with status tracking via `taskId`
* **Seamless Integration**: Works out-of-the-box with LI.FI API, SDK, and Widget

***

## How Messaging Flow Works

The messaging flow operates through a multi-step process that replaces traditional on-chain transactions with off-chain signed messages:

1. **Quote/Route Generation**: User requests a quote or route with `executionType=message` (will generate ONLY message-based routes) or `executionType=all` (both transaction and messages options)
2. **Message Creation**: LI.FI generates an EIP-712 typed message containing the operation details
3. **User Signature**: User signs the message off-chain in their wallet (no gas required)
4. **Message Relay**: Signed message is submitted to LI.FI's `/v1/advanced/relay` endpoint
5. **Backend Processing**: LI.FI backend validates and forwards the message to the destination protocol (e.g., Hyperliquid)
6. **Task Tracking**: Backend returns a `taskId` for tracking the asynchronous operation
7. **Status Monitoring**: Status can be checked via `/v1/status` endpoint using the `taskId` parameter

### Flow Diagram

```
User Wallet → Sign EIP-712 Message (off-chain, no gas)
     ↓
LI.FI SDK/API → POST /v1/advanced/relay
     ↓
LI.FI Backend → Validates & relays to protocol
     ↓
Returns taskId → Track via GET /v1/status?taskId=...
     ↓
Protocol Execution → (e.g., Hyperliquid withdrawal)
```

***

## Key Differences from Transaction Flow

| Aspect              | Transaction Flow                   | Messaging Flow                      |
| ------------------- | ---------------------------------- | ----------------------------------- |
| **Execution Type**  | On-chain transaction               | Off-chain signed message            |
| **Gas Fees**        | User pays gas for each transaction | No gas for signing messages         |
| **Token Approvals** | Required (separate transaction)    | Not required (`skipApproval: true`) |
| **Status Tracking** | `txHash`                           | `taskId`                            |
| **User Action**     | Send transaction                   | Sign typed message                  |

### Important Parameters

* **`estimate.skipApproval`**: Automatically set to `true` for messaging flows, indicating no approval transaction is needed
* **`estimate.executionType`**: Set to `"message"` to identify steps that use messaging flow
* **`typedData`**: Contains the EIP-712 message structure that users need to sign

***

## The executionType Parameter

The `executionType` parameter controls which types of routes are returned by the LI.FI API. This optional parameter is available in:

* `GET /v1/quote`
* `POST /v1/advanced/routes`

### Values

* **`transaction`** (default): Returns only routes using traditional on-chain transactions, **excluding** messaging flow routes
* **`message`**: Returns only routes that use messaging flow
* **`all`**: Returns both transaction-based and message-based routes

### Example Usage

**Get only message-based routes:**

```bash theme={"system"}
curl -X GET 'https://li.quest/v1/quote?fromChain=1337&toChain=999&fromToken=0x8F254b963e8468305d409b33aA137C6700000000&toToken=0x9FDBdA0A5e284c32744D2f17Ee5c74B284993463&fromAddress=0x552008c0f6870c2f77e5cC1d2eb9bdff03e30Ea0&fromAmount=1000000&executionType=message'
```

**Get all available routes (both types):**

```bash theme={"system"}
curl -X GET 'https://li.quest/v1/quote?fromChain=1337&toChain=999&fromToken=0x8F254b963e8468305d409b33aA137C6700000000&toToken=0x9FDBdA0A5e284c32744D2f17Ee5c74B284993463&fromAddress=0x552008c0f6870c2f77e5cC1d2eb9bdff03e30Ea0&fromAmount=1000000&executionType=all'
```

***

## The /relay Endpoint

### POST /v1/advanced/relay

**Purpose**: Submit signed EIP-712 messages for relaying to destination protocols.

**Endpoint**: `https://li.quest/v1/advanced/relay`

### Request Body

The request body is a `RelayRequest` object containing:

* **Step Information**: Standard LI.FI step data (tool, action, estimate)
* **Typed Data**: Array of signed EIP-712 messages
* **Signature**: User's signature for each message

### Request Schema

```typescript theme={"system"}
{
  id: string                    // Step ID
  type: 'lifi'                  // Step type
  tool: string                  // Bridge tool (e.g., 'hyperliquidSA')
  toolDetails: {                // Tool metadata
    key: string
    name: string
    logoURI: string
  }
  action: {                     // Transfer action details
    fromChainId: number
    toChainId: number
    fromToken: Token
    toToken: Token
    fromAmount: string
    fromAddress: string
    toAddress: string
    slippage?: number
  }
  estimate: {                   // Estimated results
    fromAmount: string
    toAmount: string
    toAmountMin: string
    tool: string
    executionDuration: number
    approvalAddress: string
    skipApproval: true          // Always true for messaging flow
    feeCosts: FeeCost[]
    gasCosts: GasCost[]
    executionType: string
  }
  includedSteps: Step[]         // Nested steps
  typedData: TypedData[]        // EIP-712 messages with signatures
}
```

### Response

**Success Response** (`200 OK`):

```json theme={"system"}
{
  "status": "ok",
  "data": {
    "taskId": "0x3078316542363633386445386335373163373837443762433234463938624641373335343235373331437c313735393438383039323538347c65646461643630632d373730392d346165312d623431652d3834643834333064306135623a30"
  }
}
```

**Error Response** (`400 Bad Request`):

```json theme={"system"}
{
  "status": "error",
  "data": {
    "code": 400,
    "message": "Invalid request"
  }
}
```

### Response Fields

* **`status`**: Either `"ok"` or `"error"`
* **`data.taskId`**: Unique hex-encoded identifier for tracking the message relay operation
* **`data.code`**: Error code (only present when status is "error")
* **`data.message`**: Error message (only present when status is "error")

***

## Status Tracking with taskId

After relaying a message, you receive a `taskId` that uniquely identifies the operation. Use this to track the message processing status.

### GET /v1/status

**Endpoint**: `https://li.quest/v1/status`

**Query Parameters**:

* **`taskId`** (optional): The task ID returned from `/relay` endpoint
* **`txHash`** (optional): Transaction hash (for traditional transactions)
* **`toChain`** (optional): Destination chain ID or key
* **`bridge`** (optional): Bridge tool identifier
* **`fromChain`** (optional): Source chain ID or key

**Note**: You must provide either `taskId` or `txHash`. For messaging flow, use `taskId`.

### Example Request

```bash theme={"system"}
curl -X GET 'https://li.quest/v1/status?taskId=0x3078316542363633386445386335373163373837443762433234463938624641373335343235373331437c313735393438383039323538347c65646461643630632d373730392d346165312d623431652d3834643834333064306135623a30'
```

### Response Format

The status endpoint returns the current state of the transfer:

```json theme={"system"}
{
  "status": "DONE",
  "substatus": "COMPLETED",
  "sending": {
    "txHash": "0x...",
    "amount": "1000000",
    "token": {
      /* token details */
    },
    "chainId": 1337,
    "timestamp": 1234567890
  },
  "receiving": {
    "txHash": "0x...",
    "amount": "1000000",
    "token": {
      /* token details */
    },
    "chainId": 999,
    "timestamp": 1234567890
  }
}
```

## Current Usage & Supported Protocols

Messaging flow is currently used for interactions with the following protocols:

### 1. Hyperliquid (Primary Use Case)

**Protocol**: [Hyperliquid](https://hyperliquid.xyz/)
**Operation**: Withdrawals from Hyperliquid to EVM chains
**Bridge Tool**: `hyperliquidSA`
**Message Type**: `SendAsset`, \`\`

**How it works**:

1. User has tokens on Hyperliquid spot account
2. Signs a `SendAsset` message to withdraw to an EVM chain
3. LI.FI relays the message to Hyperliquid's API
4. Hyperliquid processes the withdrawal and sends tokens to destination chain

### 2. Unit Protocol

**Protocol**: [Unit Protocol](https://unit.network/)
**Operation**: Withdrawals to Hyperliquid via Unit bridge
**Bridge Tool**: `unit`
**Message Type**: `SpotSend`
**Chain IDs**:

* From: 1337 (Hyperliquid/Hypercore)
* To: EVM chains, Bitcoin, Solana

***

## Supported Message Types

### Hyperliquid

LI.FI Messaging Flow supports three EIP-712 message types for Hyperliquid operations. Each message type follows a specific structure and is used for different operations.

#### 1. SpotSend

**Purpose**: Spot token transfers
**Use Case**: Used by Unit protocol for deposits to Hyperliquid
**Bridge Tool**: `unit`

**Message Structure**:

```typescript theme={"system"}
{
  type: 'spotSend',
  signatureChainId: '0x1',
  hyperliquidChain: 'Mainnet',
  destination: '0x...',           // Recipient address
  token: 'USOL:0x49b67c39...',   // Token identifier
  amount: '1.0',                  // Amount to transfer
  time: 1234567890                // Timestamp in milliseconds
}
```

#### 2. SendAsset

**Purpose**: Asset transfers between DEXs (spot accounts)
**Use Case**: Used for Hyperliquid withdrawals to EVM chains
**Bridge Tool**: `hyperliquidSA`

**Message Structure**:

```typescript theme={"system"}
{
  type: 'sendAsset',
  signatureChainId: '0x1',
  hyperliquidChain: 'Mainnet',
  destination: '0x2000...00fe',        // System address
  sourceDex: 'spot',                    // Source DEX type
  destinationDex: 'spot',               // Destination DEX type
  token: 'USOL:0x49b67c39...',         // Token identifier
  amount: '1.0',                        // Amount to transfer
  fromSubAccount: '',                   // Agent wallet address (if used)
  nonce: 1757944034747                  // Timestamp/nonce
}
```

**Note**: All messages follow the EIP-712 typed data standard and include domain information:

```typescript theme={"system"}
{
  domain: {
    name: 'HyperliquidSignTransaction',
    version: '1',
    chainId: 999,
    verifyingContract: '0x0000000000000000000000000000000000000000'
  },
  types: { /* EIP712Domain and message types */ },
  primaryType: 'HyperliquidTransaction:SendAsset',
  message: { /* message content */ }
}
```

***

## Integration Guide

### Using the API Directly

**Step 1: Get a Quote/Route**

Request a quote with `executionType=message` or `executionType=all`:

```bash theme={"system"}
curl -X GET 'https://li.quest/v1/quote?fromChain=1337&toChain=999&fromToken=0x8F254b963e8468305d409b33aA137C6700000000&toToken=0x9FDBdA0A5e284c32744D2f17Ee5c74B284993463&fromAddress=0x552008c0f6870c2f77e5cC1d2eb9bdff03e30Ea0&fromAmount=1000000&executionType=all'
```

**Step 2: Identify Message Steps**

Check the route for steps with `estimate.executionType === "message"` and `estimate.skipApproval === true`.

**Step 3: Sign the Message**

Use the `typedData` from the route to request a signature from the user's wallet:

```typescript theme={"system"}
const signature = await walletClient.signTypedData({
  domain: typedData.domain,
  types: typedData.types,
  primaryType: typedData.primaryType,
  message: typedData.message,
})
```

**Step 4: Relay the Message**

Submit the signed message to the `/relay` endpoint:

```bash theme={"system"}
curl -X POST 'https://li.quest/v1/advanced/relay' \
  -H 'Content-Type: application/json' \
  -H 'x-lifi-api-key: YOUR_API_KEY' \
  -d '{
    "id": "step-id",
    "typedData": [{
      ...typedData,
      "signature": "0x..."
    }],
    ...stepData
  }'
```

**Step 5: Track Status**

Use the returned `taskId` to check status:

```bash theme={"system"}
curl -X GET 'https://li.quest/v1/status?taskId=RETURNED_TASK_ID'
```

***

### Best Practices

1. **Always check `estimate.skipApproval`**: If true, skip approval transaction
2. **Validate signatures**: Ensure the message is signed correctly before relaying
3. **Store taskId**: Save the taskId returned from `/relay` for status tracking
4. **Poll status endpoint**: Check status periodically until completion

***

## Limitations & Considerations

### Current Limitations

* **Supported Protocols**: Currently limited to Hyperliquid and Unit protocol

### Future Enhancements

As the messaging flow matures, additional protocols and chains may be supported. Protocol teams interested in integration can contact the LI.FI team.

***

## FAQ

**Q: Do I need to do anything special to use messaging flow?**
A: No. If you're using the LI.FI SDK or Widget, messaging routes are automatically included and handled. For direct API usage, set `executionType=all` to see message routes.

**Q: Why does my route have `skipApproval: true`?**
A: This indicates the route uses messaging flow and doesn't require a token approval transaction.

**Q: How long does it take for a message to be processed?**
A: Processing time varies by protocol. For Hyperliquid, withdrawals typically complete within a few seconds.

**Q: Can I cancel a message after relaying?**
A: Once a message is relayed and accepted by the protocol, it cannot be cancelled through LI.FI. Check with the specific protocol for their cancellation policies.

**Q: How do I know if a route uses messaging flow?**
A: Check the `estimate.executionType` field. If it's `"message"`, the route uses messaging flow.

***

## Next Steps

* **Integrate**: Use the LI.FI SDK, Widget, or API to access messaging flow routes
* **Test**: Try a small withdrawal from Hyperliquid using the messaging flow
* **Monitor**: Use the `taskId` to track your operations via the status endpoint
* **Contact**: Reach out to the [LI.FI team](https://li.fi/contact-us/) for protocol integration requests

For more information, visit the [LI.FI Documentation](https://docs.li.fi/).
