Skip to main content

Monitoring Liquidity Pools on Orca

Monitoring and fetching details about liquidity pools is crucial for understanding their current state, whether you want to gather insights about a Splash Pool, a Concentrated Liquidity Pool, or all pools between specific token pairs.

1. Overview of Pool Monitoring

Fetching liquidity pool details helps developers gain insight into the current state of the pool, whether it is initialized or uninitialized, and retrieve relevant metrics like liquidity, price, and fee rates.

The SDKs offer three main functions to help developers monitor the pools:

  • Fetch Splash Pool: Fetches the details of a specific Splash Pool.
  • Fetch Concentrated Liquidity Pool: Fetches the details of a specific Concentrated Liquidity Pool.
  • Fetch Pools: Fetches all possible liquidity pools between two token mints, with various tick spacings.

Initialized vs. Uninitialized Pools

Each token pair can have multiple pools based on different tick spacings, corresponding to various fee tiers. When fetching pool data, it's possible to request a pool with a tick spacing that hasn't been used to create a pool for the given token pair. In this case, you'll receive a pool object with default parameters and an indication that the pool has not been set up.

When fetching all pools for a token pair, which iterates through all possible tick spacings, both initialized and uninitialized pools can be returned, allowing you to identify pools that have not yet been created.

2. Getting Started Guide

Fetching a pool by Address

If you already have the address of a Whirlpool:

  1. Whirlpool Address: Provide the address of the specific Whirlpool you want to fetch.
  2. Fetch Pool Details: Use the function to fetch the details of the Whirlpool at the provided address.
use orca_whirlpools::{
fetch_whirlpool, set_whirlpools_config_address, WhirlpoolsConfigInput,
};
use solana_client::nonblocking::rpc_client::RpcClient;
use solana_sdk::pubkey::Pubkey;
use std::str::FromStr;

#[tokio::main]
async fn main() {
set_whirlpools_config_address(WhirlpoolsConfigInput::SolanaDevnet).unwrap();
let rpc = RpcClient::new("https://api.devnet.solana.com".to_string());
let whirlpool_address = Pubkey::from_str("3KBZiL2g8C7tiJ32hTv5v3KM7aK9htpqTw4cTXz1HvPt").unwrap(); // SOL/devUSDC

let whirlpool = fetch_whirlpool(&rpc, whirlpool_address).await.unwrap();

println!("Pool data: {:?}", whirlpool.data);
}

Fetching a Splash Pool by Token Pair

  1. Token Mint Addresses: Provide the mint addresses of the two tokens that make up the liquidity pool.
  2. Fetch Pool Details: Use the appropriate function to fetch the details of the specified Splash Pool.
use orca_whirlpools::{
fetch_splash_pool, set_whirlpools_config_address, PoolInfo, WhirlpoolsConfigInput,
};
use solana_client::nonblocking::rpc_client::RpcClient;
use solana_sdk::pubkey::Pubkey;
use std::str::FromStr;

async fn main() {
set_whirlpools_config_address(WhirlpoolsConfigInput::SolanaDevnet).unwrap();
let rpc = RpcClient::new("https://api.devnet.solana.com".to_string());
let token_a = Pubkey::from_str("So11111111111111111111111111111111111111112").unwrap();
let token_b = Pubkey::from_str("BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k").unwrap(); // devUSDC

let pool_info = fetch_splash_pool(&rpc, token_a, token_b).await.unwrap();

match pool_info {
PoolInfo::Initialized(pool) => println!("Pool is initialized: {:?}", pool),
PoolInfo::Uninitialized(pool) => println!("Pool is not initialized: {:?}", pool),
}
}

Fetching a Concentrated Liquidity Pool by Token Pair

  1. Token Mint Addresses: Provide the mint addresses of the two tokens that make up the liquidity pool.
  2. Tick Spacing: Specify the tick spacing, which defines the intervals for price ticks.
  3. Fetch Pool Details: Use the appropriate function to fetch the details of the specified Concentrated Liquidity Pool.
use orca_whirlpools::{
fetch_concentrated_liquidity_pool, set_whirlpools_config_address, PoolInfo, WhirlpoolsConfigInput
};
use solana_client::nonblocking::rpc_client::RpcClient;
use solana_sdk::pubkey::Pubkey;
use std::str::FromStr;

#[tokio::main]
async fn main() {
set_whirlpools_config_address(WhirlpoolsConfigInput::SolanaDevnet).unwrap();
let rpc = RpcClient::new("https://api.devnet.solana.com".to_string());
let token_a = Pubkey::from_str("So11111111111111111111111111111111111111112").unwrap();
let token_b = Pubkey::from_str("BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k").unwrap(); // devUSDC
let tick_spacing = 64;

let pool_info = fetch_concentrated_liquidity_pool(&rpc, token_a, token_b, tick_spacing).await.unwrap();

match pool_info {
PoolInfo::Initialized(pool) => println!("Pool is initialized: {:?}", pool),
PoolInfo::Uninitialized(pool) => println!("Pool is not initialized: {:?}", pool),
}
}

Fetching Pools by Token Pairs

  1. Token Mint Addresses: Provide the mint addresses of the two tokens that make up the liquidity pool.
  2. Fetch Pool Details: Use the appropriate function to fetch the details of all pools for the specified token pair.
use orca_whirlpools::{
fetch_whirlpools_by_token_pair, set_whirlpools_config_address, PoolInfo, WhirlpoolsConfigInput,
};
use solana_client::nonblocking::rpc_client::RpcClient;
use solana_sdk::pubkey::Pubkey;
use std::str::FromStr;

#[tokio::main]
async fn main() {
set_whirlpools_config_address(WhirlpoolsConfigInput::SolanaDevnet).unwrap();
let rpc = RpcClient::new("https://api.devnet.solana.com".to_string());
let token_a = Pubkey::from_str("So11111111111111111111111111111111111111112").unwrap();
let token_b = Pubkey::from_str("BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k").unwrap(); // devUSDC

let pool_infos = fetch_whirlpools_by_token_pair(&rpc, token_a, token_b)
.await
.unwrap();

for pool_info in pool_infos {
match pool_info {
PoolInfo::Initialized(pool) => println!("Pool is initialized: {:?}", pool),
PoolInfo::Uninitialized(pool) => println!("Pool is not initialized: {:?}", pool),
}
}
}

3. Using Pool Data

After fetching pool information, you can use it to:

  1. Check if Pool Exists: Determine if a pool for a specific token pair and tick spacing has been created.
  2. Monitor Liquidity: Track the amount of liquidity in the pool over time.
  3. Track Prices: Monitor the current price of tokens in the pool.
  4. Calculate Fees: Calculate expected fees based on the pool's fee rate and volume.
  5. Data Analytics: Build analytics dashboards tracking pool performance and metrics.

4. Best Practices

When monitoring pools, consider these best practices:

  • Caching: Implement caching to reduce RPC calls, especially for frequently accessed pools.
  • Error Handling: Properly handle cases where pools might not exist.
  • Batch Requests: When possible, batch your requests to reduce the number of RPC calls.
  • Rate Limiting: Be mindful of RPC rate limits when monitoring multiple pools.
  • Data Freshness: Determine how recent the data needs to be for your application.