Integration
Liquidity Provision
LP RPCs

Liquidity Provider / Market Maker RPCs

Here are the RPCs and subscriptions that are useful for liquidity providers that are available on the State Chain.

The following RPCs are only available on chainflip-node.

WebSocket subscriptions

Example usages are using a Websocket utility such as Websocat (opens in a new tab):

cf_subscribe_scheduled_swaps

Subscribes to a stream of all swaps that are scheduled to be executed in the next few blocks in a given pool. Note that all Chainflip swaps get scheduled 2 State Chain blocks after the deposit that triggers it is witnessed, so there is approximately 12 seconds between a swap first appearing in the subscription and it being executed. The subscription is designed to help liquidity providers see what swaps are coming in and prepare for them.

Parameters:

Returns:

A websocket notification is returned on every State Chain block, each of which is a json object containing:

  • block_hash: string,
  • block_number: number,
  • swaps: Array<ScheduledSwap>

where ScheduledSwap contains the following details of an upcoming swap as a json object:

  • swap_id: number
  • base_asset: Asset,
  • quote_asset: Asset,
  • side: Side,
  • amount: u256 (hex-encoded)
  • source_asset: Asset (optional),
  • source_amount: u256 (hex-encoded, optional)
  • execute_at: number

Example

wscat -c ws://localhost:9944
> {"id":1, "jsonrpc":"2.0", "method": "cf_subscribe_scheduled_swaps", "params": ["FLIP", "USDC"]}

Here we subscribe to all swaps involving the FLIP/USDC pool. Say users request the swaps FLIP->USDC and BTC->FLIP and their corresponding deposits have just been witnessed. The subscription returns one websocket notification on every State Chain block. Here is what a possible notification for block 84 might look like:

{
    "block_hash":"0x00d717c77802650d08267f5c2d90efcf4dccde271ea9d69359d30f3de2f3e32e",
    "block_number":84,
    "swaps": [
        {
            "swap_id":1,
            "base_asset":{
                "chain":"Ethereum",
                "asset":"FLIP"
            },
            "quote_asset":{
                "chain":"Ethereum",
                "asset":"USDC"
            },
            "side":"sell",
            "amount":"0x1ad5814560a6c1005b",
            "execute_at":85
        },
        {
            "swap_id":2,
            "base_asset":{
                "chain":"Ethereum",
                "asset":"FLIP"
            },
            "quote_asset":{
                "chain":"Ethereum",
                "asset":"USDC"
            },
            "side":"buy",
            "amount":"0x1d540d83",
            "source_asset":{
                "chain":"Bitcoin",
                "asset":"BTC"
            },
            "source_amount":"0x4b877c",
            "execute_at":86
        }
    ]
}

Note that the FLIP->USDC swap will be executed in the next block (85). Note also that only the second leg (USDC->FLIP) of the BTC->FLIP is returned since it is the one that involves the pool we requested. IMPORTANT: while the amount field in the first swap is the exact amount that will be executed, the amount in the second swap cannot be known precisely before the corresponding first leg (BTC->USDC) is executed, and thus we only return an approximate amount computed by simulating all scheduled swaps given the current state of the liquidity pool. All swaps with approximate amounts additionally include source_asset and source_amount fields to give liquidity providers an option to use a custom method for approximating intermediate amounts.

The notification for the next block (85) would look like the following under this example:

{
    "block_hash":"0xcd3e34680895f3f98a0fb7f74265cc0b23ed8dc89cddb0cd3e6c60700985d74e",
    "block_number":85,
    "swaps": [
        {
            "swap_id":2,
            "base_asset":{
                "chain":"Ethereum",
                "asset":"FLIP"
            },
            "quote_asset":{
                "chain":"Ethereum",
                "asset":"USDC"
            },
            "side":"buy",
            "amount":"0x1d540d83",
            "source_asset":{
                "chain":"Bitcoin",
                "asset":"BTC"
            },
            "source_amount":"0x4b877c",
            "execute_at":86
        }
    ]
}

Using swap_id to identify swaps, swap 1 has already been executed and is thus not present. However, swap 2 appears again as it is still scheduled for execution in the next block. In practice a swap can be expected to appear in at least two websocket notifications. Note that in the rare case of swaps failing (e.g. due to insufficient liquidity in the pool), they will be re-scheduled for the next block, and will appear again in the subscription.

cf_subscribe_prewitness_swaps

Subscribes to all potential incoming swaps of a particular direction. Swaps are only executed after a certain number of block confirmations for each chain, so this RPC allows you to see swaps that are potential but not yet confirmed. This is useful for liquidity providers to see what swaps are coming in and prepare for them.

WARNING: Because these are witnessed before confirmation, they are not guaranteed to be executed at all or at that time, since blockchains can re-org.

The current number of confirmations (where 0 confirmations is just in mempool and not in a block) required for each chain are:

Mainnet (Berghain)

ChainConfirmations
BTC3
ETH7
DOTFinalisation

Testnet (Perseverance)

ChainConfirmations
BTC6
ETH7
DOTFinalisation

For BTC and ETH we use probabilistic finality, for DOT we use deterministic finality.

Example

{"jsonrpc":"2.0","id":"1","method":"cf_subscribe_prewitness_swaps","params":["Btc", "Eth"]}

cf_subscribe_pool_price

Subscribes to the current price of a pair in a particular direction. This is useful for liquidity providers to see the current price of a pool. Note {"from_asset": "BTC", "to_asset": "USDC } is not equivalent to {"from_asset": "USDC", "to_asset": "BTC"}, therefore the prices maybe different.

It returns the price at the time of beginning the subscription as the first item in the stream. Subsequent items are only returned if there is a change in the price.

Example

{
    "jsonrpc": "2.0",
    "id": "1",
    "method": "cf_subscribe_pool_price",
    "params": {
        "from_asset": "BTC",
        "to_asset": "USDC"
    }
}
{
    "jsonrpc": "2.0",
    "method": "cf_subscribe_pool_price",
    "params": {
        "subscription": "zynJAJ4qG4mIvBEl",
        "result": {
            "price": "0x101487bee1c17ddb45ce0badfbe6eff13",
            "sqrt_price": "0x100a4096906976f1080c4042d",
            "tick": 50
        }
    }
}

RPC requests

Examples are using curl.

cf_required_asset_ratio_for_range_order

Returns the ratio of assets that would be required to create a range order at the specified tick range.

Parameters:

  • Base Asset.
  • Pair Asset.
  • A JSON array of two i32, representing the start and end of the price range the order is over as ticks. The first number should always be less than the second.

Return:

  • Base and Pair Asset amounts as u256. The ratio of these two amounts is the needed ratio for range orders over the same range given the current price, i.e. the asset composition of all range orders with the same range will match this ratio.

Example

  • Request:
curl -H "Content-Type: application/json" \
    -d '{"id":1, "jsonrpc":"2.0", "method": "cf_required_asset_ratio_for_range_order", "params": ["Eth", "Usdc", [-400000, 400000]]}' \
    http://localhost:9944

Response:

{"jsonrpc":"2.0","result":{"base":"0x48fdda050e625251db12baf14c6258c","pair":"0x13979e2ae923a625b6119832"},"id":1}

cf_pool_info

Returns the fees percentages LP's earn in the given pool.

Parameters:

Return:

  • The fees liquidity providers earn on swaps using their limit orders or range orders in hundredth's of a pip, i.e. 1 = 0.00001%.

Example

  • Request:
curl -H "Content-Type: application/json" \
    -d '{"id":1, "jsonrpc":"2.0", "method": "cf_pool_info", "params": {"base_asset": "ETH", "quote_asset": "USDC"}}' \                   
    http://localhost:9944
  • Response:
{
   "jsonrpc":"2.0",
   "result":{
      "limit_order_fee_hundredth_pips":20,
      "range_order_fee_hundredth_pips":20,
      "range_order_total_fees_earned":{
         "base":"0x92d398d746f9a",
         "quote":"0x50925"
      },
      "limit_order_total_fees_earned":{
         "base":"0x0",
         "quote":"0x0"
      },
      "range_total_swap_inputs":{
         "base":"0x70047cb8257ef2652",
         "quote":"0x3d7844834"
      },
      "limit_total_swap_inputs":{
         "base":"0x0",
         "quote":"0x0"
      }
   },
   "id":1
}

cf_pool_depth

Returns depth of a specified pool between two prices.

Parameters:

  • Base Asset.
  • Pair Asset.
  • A JSON array of two ticks as i32, representing the range of prices over which depth will be calculated. The first number should always be less than the second.

Return:

  • The amount of each of the pool's two assets available for sale inside the given price range. The depth of limit orders and range orders at separately stated.

Example

Request:

curl -H "Content-Type: application/json" -d '{"id":1, "jsonrpc":"2.0", "method": "cf_pool_depth", "params": ["ETH", "USDC", [0, 1000]]}' http://localhost:9944

Response:

{
  "jsonrpc": "2.0",
  "result": {
    "base": {
      "limit_orders": { "price": null, "depth": "0x0" },
      "range_orders": {
        "price": "0x15d21b1217b76a34437fca3a9",
        "depth": "0x8c3f38916066"
      }
    },
    "pair": {
      "limit_orders": { "price": null, "depth": "0x0" },
      "range_orders": { "price": "0x15d21b1217b76a34437fca3a9", "depth": "0x0" }
    }
  },
  "id": 1
}

cf_pool_liquidity

Returns all the liquidity available for swaps in a particular pool.

Parameters:

Return:

  • For limit orders two lists of prices (as ticks) and the amount/depth available at those prices.
  • For range orders, an ordered list of pairs. The first element of the pair is a tick/price and the second is the liquidity between that tick and the next tick in the list. Forming a histogram of the liquidity in the range order pool.

Example

Request:

curl -H "Content-Type: application/json" \
    -d '{"id":1, "jsonrpc":"2.0", "method": "cf_pool_liquidity", "params": {"base_asset": "ETH", "pair_asset": "USDC"}}' \
    http://localhost:9944

Response:

{
  "jsonrpc": "2.0",
  "result": {
    "limit_orders": { "base": [], "pair": [] },
    "range_orders": [
      [-887272, 3161961432402363],
      [887272, 0]
    ]
  },
  "id": 1
}

cf_pool_orders

Returns all the orders associated with a specified account in a particular pool.

Parameters:

Return:

Example

Request:

curl -H "Content-Type: application/json" \
    -d '{"id":1, "jsonrpc":"2.0", "method": "cf_pool_orders", "params": {"base_asset": "ETH", "pair_asset": "USDC", "lp": "cFPdef3hF5zEwbWUG6ZaCJ3X7mTvEeAog7HxZ8QyFcCgDVGDM"}}' \
    http://localhost:9944

Response:

{
  "jsonrpc": "2.0",
  "result": {
    "limit_orders": { "base": [], "pair": [] },
    "range_orders": [[0, { "start": -887272, "end": 887272 }, 3161961432402363]]
  },
  "id": 1
}

cf_pool_orderbook

Returns an orderbook representation of all the liquidity in the specified pool. For example if you make a request with an orders count of 1, it will return 1 ask and 1 bid that each represent the sum of all asks and bids respectively. The returned ask's and bid's prices will be approximately in an logarithm distribution going from the best price to the worst, for example it could be something like the first ask/bid represents all liquidity within 0.01% of the best price, then the next all liquidity between 0.01%->0.1% of the best price, then next between 0.1%->1.0%, and so on until there is no more liquidity.

Parameters:

  • Base Asset.
  • Quote Asset.
  • The number of orders to return. As this is increased the returned orderbook representation will more accurately reflect the pool's liquidity distribution. This number is inclusively bounded between 1 and 16384.

Return:

A list of asks and a list of bids. The number of asks and bids will be equal to or less than the specified number of orders. There may be zero asks or bids if no liquidity exists to either ask or bid. Each ask and bid has two properties a sqrt_price and an amount.

  • The amount is quoted in the base asset's smallest unit, i.e. for ETH that is 10^-18 ETH.
  • The sqrt_price is the sqrt of the price in units of the quote asset, represented as a fixed point number with 96 fractional bits. Note prices are in each asset's smallest unit i.e. for ETH 10^-18, and for USDC 10^-6, so the price 10000 USDC/ETH represented as sqrt_price would be round(sqrt(10000 * 10^18 / 10^6)*2^96) ≈ 7.9228162E36. We use this representation as it ensures a high degree of precision across a large range of possible prices.

Example

Request:

curl -H "Content-Type: application/json" \
    -d '{"id":1, "jsonrpc":"2.0", "method": "cf_pool_orderbook", "params": {"base_asset": "ETH", "quote_asset": "USDC", "orders": 10}}' \
    http://localhost:9944

Response:

{
    "jsonrpc": "2.0",
    "result": {
        "asks": [
            {
                "amount": "0x54b2cec31723f8b04",
                "sqrt_price": "0x2091b342e50d7f26cdc582"
            },
            {
                "amount": "0x5b475d13fc0374e",
                "sqrt_price": "0x1e38a26ccc8cad8ff5ed7d0e"
            },
            {
                "amount": "0x625ecb4a48690",
                "sqrt_price": "0x1c0ae64c925b19f39a41ff17bd"
            },
            {
                "amount": "0x6a03445844f",
                "sqrt_price": "0x1a055f3578ef64659516605ff66d"
            },
            {
                "amount": "0x723fbd69d",
                "sqrt_price": "0x18252720d1c42e3ba5952fd2fe89fb"
            },
            {
                "amount": "0x7b20059",
                "sqrt_price": "0x16678d870594b3379bb55bece63777cb"
            },
            {
                "amount": "0x84b0d",
                "sqrt_price": "0x14ca1409cb331360845a79ebe43373e18e"
            },
            {
                "amount": "0x8ef",
                "sqrt_price": "0x134b7afbfbb5777da858f99704921055bfe0"
            },
            {
                "amount": "0x9",
                "sqrt_price": "0x12848533e1997da57a9773adec9795a3626203"
            }
        ],
        "bids": [
            {
                "amount": "0x9a488cdb615edf25fd",
                "sqrt_price": "0x62bac2a2b8f0b98b9ceb"
            },
            {
                "amount": "0x1217d98319cd00bc28de",
                "sqrt_price": "0x349e212a7a008282ff9"
            },
            {
                "amount": "0x21f2ffe1f3cc8bebab567",
                "sqrt_price": "0x1c0ae0758c0acee837"
            },
            {
                "amount": "0x3fb3690cb0511666161b4d",
                "sqrt_price": "0xef1f790088e3f323"
            },
            {
                "amount": "0x77868270bada4c06b5c9e64",
                "sqrt_price": "0x7f7094efc08a808"
            },
            {
                "amount": "0xe045b383a1b21969cebb4976",
                "sqrt_price": "0x43eaad48a59f17"
            },
            {
                "amount": "0x1a4d08d014973bf8ba1c33904f",
                "sqrt_price": "0x241d6cfa0a79c"
            },
            {
                "amount": "0x3159920b20889ed50eabfa6edc8",
                "sqrt_price": "0x123884db5748"
            }
        ]
    },
    "id": 1
}

cf_pool_range_order_liquidity_value

Returns the value of a hypothetical range order, e.g. the assets would would be returned to an LP's free balance if they were to close/cancel such a range order.

Parameters:

  • Base Asset.
  • Pair Asset.
  • A JSON array of two i32, representing the start and end of the price range the order is over as ticks. The first number should always be less than the second.
  • The liquidity of the range order as an amount.

Return:

  • The value of the hypothetical range order if it where burnt now, in amounts of the base and pair assets.

Example

Request:

curl -H "Content-Type: application/json" \
    -d '{"id":1, "jsonrpc":"2.0", "method": "cf_pool_range_order_liquidity_value", "params": {"base_asset": "Eth", "pair_asset": "Usdc", "tick_range": [0, 1000], "liquidity": 10000000000}}' \
    http://localhost:9944

Response:

{ "jsonrpc": "2.0", "result": { "base": "0x1d116fb8", "pair": "0x0" }, "id": 1 }

cf_asset_balances

Returns the balances of all assets for a specified account.

Parameters:

Return:

  • A list of asset balances for the specified account.

Example

Request:

curl -H "Content-Type: application/json" \
    -d '{"id":1, "jsonrpc":"2.0", "method": "cf_asset_balances", "params": {"account_id": "cFPdef3hF5zEwbWUG6ZaCJ3X7mTvEeAog7HxZ8QyFcCgDVGDM"}}' \
    http://localhost:9944

Response:

{
   "jsonrpc":"2.0",
   "result":[
      {
         "chain":"Ethereum",
         "asset":"ETH",
         "amount":9999999999637114
      },
      {
         "chain":"Ethereum",
         "asset":"FLIP",
         "amount":999999999999994976
      },
      {
         "chain":"Ethereum",
         "asset":"USDC",
         "amount":600040000000
      },
      {
         "chain":"Polkadot",
         "asset":"DOT",
         "amount":9802700011
      },
      {
         "chain":"Bitcoin",
         "asset":"BTC",
         "amount":99883
      }
   ],
   "id":1
}

cf_scheduled_swaps

Returns all scheduled swaps in a pool. Works similarly to cf_subscribe_scheduled_swaps.

Parameters:

Example:

curl -H "Content-Type: application/json" \
    -d '{"id":1, "jsonrpc":"2.0", "method": "cf_scheduled_swaps", "params": ["FLIP", "USDC"]}' \
    http://localhost:9944

Response:

{
    "jsonrpc":"2.0",
    "result":[
        {
            "swap_id":1,
            "base_asset":{
                "chain":"Ethereum",
                "asset":"FLIP"
            },
            "quote_asset":{
                "chain":"Ethereum",
                "asset":"USDC"
            },
            "side":"sell",
            "amount":"0x1ad5814560a6c1005b",
            "execute_at":170
        }
    ],
    "id":1
}
;