Swap Query x2y With Offline Data

Example of swap query usage of x2y with offline data.

The full example code of this chapter can be spotted here.

1. some imports

first some base imports

1import { TokenInfoFormatted } from 'iziswap-sdk/lib/base/types'
2import { Orders } from 'iziswap-sdk/lib/swapQuery/library/Orders'
3import { LogPowMath } from 'iziswap-sdk/lib/swapQuery/library/LogPowMath'
4import { iZiSwapPool } from 'iziswap-sdk/lib/swapQuery/iZiSwapPool'
5import { decimal2Amount } from 'iziswap-sdk/lib/base/token/token';
6import { SwapQuery } from 'iziswap-sdk/lib/swapQuery/library/State';
7import { SwapX2YModule } from 'iziswap-sdk/lib/swapQuery/swapX2YModule'
8import JSBI from 'jsbi';
9import { State } from 'iziswap-sdk/lib/pool/types';

2. construct order data

second, construct order data for swap, we should notice that the range of order data should cover currentPoint and lowPoint (low boundary of calling swapX2Y or swapX2YDesireY)

 1const liquidity = [
 2    '26728378980016527',
 3    '1918546082716318',
 4    '7295067906501307',
 5    '523230926682255801',
 6    '517854404858470812',
 7    '1918546082716318'
 8].map((e:string)=>JSBI.BigInt(e))
 9
10const liquidityDeltaPoint = [ -98560, -93920, -93760, -93720, -93360, -93280 ]
11
12const sellingX = [] as JSBI[]
13const sellingXPoint = [] as number[]
14
15const sellingY = [ '0', '100000000000000000', '1200000000000000', '422993654872524085' ].map((e:string)=>JSBI.BigInt(e))
16const sellingYPoint = [ -98560, -94760, -93920, -93560 ]
17
18const orders: Orders.Orders = {
19    liquidity,
20    liquidityDeltaPoint,
21    sellingX,
22    sellingXPoint,
23    sellingY,
24    sellingYPoint,
25}

in the above code, liquidityDeltaPoint is an strict ascending array of points where liquidity changed cross that point from left to right. and liquidity[i] is liquidity value at liquidityDeltaPoint[i]. sellingX and sellingXPoint is data of limit orders which sell tokenX in this pool. sellingY and sellingYPoint is data of limit orders which sell tokenY in this pool. sellingXPoint and sellingYPoint should be strict ascending order. if you want to know how to fetch those data from pool, we can see this page

3. construct pool data

 1const sqrtRate_96 = LogPowMath.getSqrtPrice(1)
 2
 3const swapQueryState: SwapQuery.State = {
 4    currentPoint: -93548,
 5    liquidity: JSBI.BigInt('523230926682255801'),
 6    sqrtPrice_96: LogPowMath.getSqrtPrice(-93548),
 7    liquidityX: JSBI.BigInt('25090486294305875')
 8}
 9
10const fee = 2000
11const pool = new iZiSwapPool(swapQueryState, orders, sqrtRate_96, pointDelta, fee)

4. do swap query

 1const lowPt = state.currentPoint - 1500;
 2
 3const tokenX = {
 4    address: '0x551197e6350936976DfFB66B2c3bb15DDB723250',
 5    decimal: 18
 6} as TokenInfoFormatted
 7const inputAmountStr = decimal2Amount(5, tokenX).toFixed(0)
 8
 9const {amountX, amountY} = SwapX2YModule.swapX2Y(pool, JSBI.BigInt(inputAmountStr), lowPt)
10
11console.log('cost: ', amountX.toString())
12console.log('acquire: ', amountY.toString())

Here, lowPt means lower bound of point or undecimal_price_x_by_y during swap. When we call interface like swapY2X or swapY2XDesireX, the parameter highPt means higher bound of point or undecimal_price_x_by_y during swap.

After we run codes above, amountX will store undecimal amount of tokenX during this swap and amountY will store undecimal amount of tokenY during this swap.

Notice, when we use those order data to call swapX2Y or swapX2YDesireY, we should garrentee following non-equalities:

1max(sellingYPoint[0], liquidityDeltaPoint[0]) <= lowPoint
2lowPoint <= currentPoint
3currentPoint <= liquidityDeltaPoint.last()

and if we want to call swapY2X or swapY2XDesireX, we should garrentee that.

1liquidityDeltaPoint[0] <= currentPoint
2currentPoint < highPoint
3highPoint <= min(sellingXPoint.last(), liquidityDeltaPoint.last())

otherwise, an iZiSwapError with corresponding errcode and infomation will be throwed in this interface.

If you are sure your swap will not exceed following range by limit amount or desire parameter.

1[max(sellingYPoint[0], liquidityDeltaPoint[0]), min(sellingXPoint.last(), liquidityDeltaPoint.last())]

you can add some fake data with very left or right point as guards to order data.

Notice that, when we call swapX2Y and swapX2YDesireY, amountX is amount of tokenX actually payed. When we call swapY2X and swapY2XDesireX, amountY is amount of tokenY actually payed.