Usage

This section explains how to integrate and use the Tycho-Orderbook crate in your project.

1. Adding the Dependency

You can clone the repository and point the SDK dependency to the locally forked SDK.

The SDK is not yet published on crates.io.

git clone https://github.com/0xMerso/tycho-orderbook-sdk sdk

In the Cargo.toml of your project.

[dependencies]
tycho-orderbook = { path = "../sdk" } 

For a complete code example, please go directly to Quickstart.

2. Instantiate the provider and build an orderbook

The OrderbookBuilder structure is used to build an OrderbookProvider, which creates a stream of data and events for the specified network.

The builder requires a Tycho ProtocolStreamBuilder takes into account numerous configuration parameters, such as supported exchanges (Uniswap, Curve, etc.) and pool filters (minimum TVL).

let network = networks.clone().into_iter().find(|x| x.name == name).expect("Network not found");
let mut psb = ProtocolStreamBuilder::new(&network.tycho, chain)
        .exchange::<UniswapV2State>(TychoSupportedProtocol::UniswapV2.to_string().as_str(), filter.clone(), None)
        .exchange::<UniswapV3State>(TychoSupportedProtocol::UniswapV3.to_string().as_str(), filter.clone(), None)
        .exchange::<UniswapV4State>(TychoSupportedProtocol::UniswapV4.to_string().as_str(), filter.clone(), Some(u4))
        .auth_key(Some(key.clone()))
        .skip_state_decode_failures(true)
        .set_tokens(tokens.clone())
        .await;

let builder = OrderbookBuilder::new(network.clone(), psb, key.clone(), tokens.clone());
match builder.build(xstate).await {
         Ok(provider: OrderbookProvider) => {
                 [..]
         }
}

The OrderbookProvider structure is the crate's main component. It listens to Tycho streams, and opens a stream on which the client will listen for new events. Each time a new event is emitted, you'll know which states have changed, i.e. liquidity pools that have executed swaps.

The OrderbookProvider has a shared memory state which is used to internally update data that includes liquidity pool (= component) data. More importantly, this Arc Mutex structure contains pointers to the simulation functions provided by Tycho for each component, used to compute the orderbooks.


if let Some(event) = stream.recv().await {
    [...]
    OrderbookEvent::NewHeader(block, updated) => {
        // You are notified by the stream when liquidity pool state change
    }
}

You can now trigger the recalculation of the orderbook.

provider.get_orderbook(DefaultOrderbookSolver,
    OrderbookRequestParams { tag: key.clone(), point: None }
).await

The solver is used here to find the optimal path for a given trade (for example, how much to allocate for 100 ETH on 5 ETH-USDC pools).

The orderbook returned is as follow.

#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Orderbook {
    [...]
    pub base: SrzToken,
    /// Token1. Output then output token
    pub quote: SrzToken,
    /// Array of resulat for the optimal single hop route
    pub bids: Vec<TradeResult>,
    /// Array of resulat for the optimal single hop route
    pub asks: Vec<TradeResult>,
    /// All components used to build the orderbook (= pools that include both token0 and token1)
    pub pools: Vec<SrzProtocolComponent>,
    [...]
}

An orderbook is characterized by a tag, which is the address of base token, a dash '-', and the address of the quote token. For instance, for BTC-USDC on ethereum, BTC is the base token.

0x2260fac5e5542a773aa44fbcfedf7c193bc2c599-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48

The base token is the first token, the quote is the second, in the same order as when you request an orderbook with the 0xTokenBase-0xTokenQuote tag.

To create an orderbook and obtain its formalised bids/asks, using OrderbookProvider, you need to do:

obp.get_orderbook(OrderbookRequestParams { tag: tag.clone(), point: None }, Some(simufns)).await
let depth = book.depth(None);   

The point structure for SinglePointSimulation can be filled in to simulate a single trade, i.e a given degree of depth in the orderbook in fact.

3. Execution

You can execute any transaction using the SDK, which will build the transaction to be executed on Tycho Router contract, and approve it beforehand with Permit2.

You will find more information on the Tycho documentation here.


let request = ExecutionRequest {
    sender: sender.to_string().clone(),
    tag: book.tag.clone(),
    input: book.base.clone(),
    output: book.quote.clone(),
    amount,
    expected,
    distribution: way.distribution.clone(),
    components: book.pools.clone(),
};

// Build transactions
match book.create(network.clone(), request, originals.clone(), pk.clone()).await {
    Ok(payload) => {
        // Broadcast
        match book.send(network.clone(), payload, pk.clone()).await {}
    }
}

For a complete code example, please go directly to Quickstart.

Last updated

Was this helpful?