Skip to main content

Crate lfi

Crate lfi 

Source
Expand description

Rust client for the LI.FI cross-chain bridge and DEX aggregator API

LI.FI is a multi-chain liquidity aggregation protocol that integrates multiple bridges and DEXs to provide optimal cross-chain swap routes. It offers a unified API for accessing liquidity across 20+ chains.

§Features

  • Cross-chain swaps: Swap tokens across different blockchains in a single transaction
  • Bridge aggregation: Access multiple bridges (Stargate, Hop, Connext, Across, etc.)
  • DEX aggregation: Optimal routing through DEXs on each chain
  • Route optimization: Find the best route by price, speed, or security
  • Transaction tracking: Monitor cross-chain transaction status

§Quick Start

use lfi::{Client, QuoteRequest, chains};

#[tokio::main]
async fn main() -> Result<(), lfi::Error> {
    // Create a client with an integrator identifier (recommended)
    let client = Client::with_integrator("my-app")?;

    // Get a quote for swapping 1 ETH on Ethereum to USDC on Arbitrum
    let request = QuoteRequest::new(
        chains::ETHEREUM,                                  // Source chain
        chains::ARBITRUM,                                  // Destination chain
        "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",      // Native ETH
        "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",      // USDC on Arbitrum
        "1000000000000000000",                             // 1 ETH in wei
        "0xYourWalletAddress",
    ).with_slippage(0.5);

    let quote = client.get_quote(&request).await?;
    println!("Estimated output: {}", quote.estimate.to_amount);

    // Get transaction data to execute
    if let Some(tx) = quote.transaction_request {
        println!("Send transaction to: {}", tx.to);
        println!("Data: {}", tx.data);
        println!("Value: {}", tx.value);
    }

    Ok(())
}

§Getting Multiple Routes

Use the advanced routes API to get multiple route options:

use lfi::{Client, RoutesRequest, RoutesOptions, RouteOrder, chains};

#[tokio::main]
async fn main() -> Result<(), lfi::Error> {
    let client = Client::with_integrator("my-app")?;

    let options = RoutesOptions::new()
        .with_slippage(0.5)
        .with_order(RouteOrder::Cheapest);  // Sort by best output

    let request = RoutesRequest::new(
        chains::ETHEREUM,
        "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",  // USDC on Ethereum
        "100000000",                                    // 100 USDC (6 decimals)
        "0xYourWalletAddress",
        chains::BASE,
        "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",  // USDC on Base
    ).with_options(options);

    let response = client.get_routes(&request).await?;

    for route in &response.routes {
        println!("Route via {:?}", route.steps.iter().map(|s| &s.tool).collect::<Vec<_>>());
        println!("  Output: {}", route.to_amount);
        println!("  Gas cost: {:?}", route.gas_cost_usd);
    }

    Ok(())
}

§Tracking Cross-Chain Transactions

Monitor the status of cross-chain swaps:

use lfi::{Client, StatusRequest, TransactionStatus};

#[tokio::main]
async fn main() -> Result<(), lfi::Error> {
    let client = Client::new()?;

    let request = StatusRequest::new("0xYourTxHash")
        .with_bridge("stargate")
        .with_from_chain(lfi::chains::ETHEREUM)
        .with_to_chain(lfi::chains::ARBITRUM);

    loop {
        let status = client.get_status(&request).await?;

        match status.status {
            TransactionStatus::Done => {
                println!("Transaction complete!");
                if let Some(receiving) = status.receiving {
                    println!("Received tx: {}", receiving.tx_hash);
                }
                break;
            }
            TransactionStatus::Pending => {
                println!("Still processing...");
                tokio::time::sleep(std::time::Duration::from_secs(10)).await;
            }
            TransactionStatus::Failed => {
                println!("Transaction failed: {:?}", status.substatus_message);
                break;
            }
            _ => break,
        }
    }

    Ok(())
}

§Supported Chains

LI.FI supports 20+ chains including:

  • EVM chains: Ethereum, Polygon, Arbitrum, Optimism, Base, BSC, Avalanche, etc.
  • L2s: zkSync, Scroll, Linea, Mantle, Blast, Mode
  • Non-EVM: Solana (via specific bridges)

Use the chains module for common chain IDs:

use lfi::chains;

let eth = chains::ETHEREUM;      // 1
let arb = chains::ARBITRUM;      // 42161
let base = chains::BASE;         // 8453
let op = chains::OPTIMISM;       // 10

§Integrator String

LI.FI recommends using an integrator string for production applications. This helps track API usage and enables features like fee collection:

use lfi::{Client, Config};

// Simple way
let client = Client::with_integrator("my-dapp")?;

// With full configuration
let config = Config::new()
    .with_integrator("my-dapp")
    .with_fee(0.3)  // 0.3% integrator fee
    .with_referrer("0xYourReferrerAddress");

let client = Client::with_config(config)?;

§Bridge and Exchange Selection

You can control which bridges and exchanges are used:

use lfi::{QuoteRequest, chains};

let request = QuoteRequest::new(
    chains::ETHEREUM,
    chains::ARBITRUM,
    "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
    "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
    "1000000000",
    "0xYourAddress",
)
.with_allowed_bridges(vec!["stargate".to_string(), "hop".to_string()])
.with_denied_exchanges(vec!["sushiswap".to_string()]);

§Error Handling

All API methods return Result<T, lfi::Error>:

use lfi::{Client, QuoteRequest, Error, chains};
use lfi::error::DomainError;

async fn get_quote(client: &Client) -> Result<(), Error> {
    let request = QuoteRequest::new(
        chains::ETHEREUM,
        chains::ARBITRUM,
        "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
        "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
        "1000000000000000000",
        "0xYourAddress",
    );

    match client.get_quote(&request).await {
        Ok(quote) => println!("Got quote: {}", quote.estimate.to_amount),
        Err(Error::Domain(DomainError::NoRouteFound)) => println!("No route available"),
        Err(Error::RateLimited { retry_after }) => {
            println!("Rate limited, retry after {:?}", retry_after);
        }
        Err(e) => println!("Error: {}", e),
    }

    Ok(())
}

Re-exports§

pub use client::Client;
pub use client::Config;
pub use error::Error;
pub use error::Result;
pub use types::chains;
pub use types::Action;
pub use types::BridgeOptions;
pub use types::Chain;
pub use types::ChainId;
pub use types::ChainsResponse;
pub use types::Connection;
pub use types::ConnectionsRequest;
pub use types::ConnectionsResponse;
pub use types::Estimate;
pub use types::ExchangeOptions;
pub use types::FeeCost;
pub use types::GasCost;
pub use types::GasPrice;
pub use types::GasPricesResponse;
pub use types::Insurance;
pub use types::Quote;
pub use types::QuoteRequest;
pub use types::Route;
pub use types::RouteOrder;
pub use types::RoutesOptions;
pub use types::RoutesRequest;
pub use types::RoutesResponse;
pub use types::StatusRequest;
pub use types::StatusResponse;
pub use types::Step;
pub use types::StepType;
pub use types::Token;
pub use types::TokenAmount;
pub use types::TokensRequest;
pub use types::TokensResponse;
pub use types::Tool;
pub use types::ToolDetails;
pub use types::ToolType;
pub use types::ToolsResponse;
pub use types::TransactionInfo;
pub use types::TransactionRequest;
pub use types::TransactionStatus;

Modules§

client
HTTP client for the LI.FI API
error
Error types for the LI.FI API client
types
Types for the LI.FI API

Structs§

HttpClientConfig
HTTP client configuration
RetryConfig
Configuration for retry behavior
RetryError
Error wrapper that includes retry information

Constants§

DEFAULT_BASE_URL
Default base URL for the LI.FI API

Traits§

RetryableError
Determines if an error should be retried

Functions§

config_with_integrator
Create a config with an integrator identifier
default_config
Create a default LI.FI config
with_retry
Execute an async operation with retries
with_simple_retry
Simple retry wrapper for operations that return Result with any error type