UNPKG

@alcorexchange/alcor-swap-sdk

Version:

## Installation ​​ **npm** ``` npm i @alcorexchange/alcor-swap-sdk ``` **yarn** ``` yarn add @alcorexchange/alcor-swap-sdk ``` ## Usage ### Import:

206 lines (198 loc) 6.52 kB
import fs from "fs"; import { Pool } from "entities/pool"; import { Token } from "entities/token"; import { Trade } from "entities/trade"; import { asset, symbol } from "eos-common"; import { CurrencyAmount } from "../src/entities/fractions/currencyAmount"; import JSBI from "jsbi"; import { FeeAmount, TICK_SPACINGS } from "internalConstants"; import { encodeSqrtRatioX64 } from "utils/encodeSqrtRatioX64"; import { TickMath } from "utils/tickMath"; import { nearestUsableTick } from "utils/nearestUsableTick"; import { sqrt } from "utils/sqrt"; function parseToken(token) { return new Token( token.contract, asset(token.quantity).symbol.precision(), asset(token.quantity).symbol.code().to_string() ); } describe("Trade", () => { const token0 = new Token( "0x0000000000000000000000000000000000000001", 8, "t0", "token0" ); const token1 = new Token( "0x0000000000000000000000000000000000000002", 8, "t1", "token1" ); const token2 = new Token( "0x0000000000000000000000000000000000000003", 8, "t2", "token2" ); const token3 = new Token( "0x0000000000000000000000000000000000000004", 8, "t3", "token3" ); function v2StylePool( id: number, reserve0: CurrencyAmount<Token>, reserve1: CurrencyAmount<Token>, feeAmount: FeeAmount = FeeAmount.MEDIUM ) { console.log("feeAmount", feeAmount); const sqrtRatioX64 = encodeSqrtRatioX64( reserve1.quotient, reserve0.quotient ); const liquidity = sqrt( JSBI.multiply(reserve0.quotient, reserve1.quotient) ); return new Pool({ id, tokenA: reserve0.currency, tokenB: reserve1.currency, fee: feeAmount, sqrtPriceX64: sqrtRatioX64, liquidity, tickCurrent: TickMath.getTickAtSqrtRatio(sqrtRatioX64), ticks: [ { id: nearestUsableTick(TickMath.MIN_TICK, TICK_SPACINGS[feeAmount]), liquidityNet: liquidity, liquidityGross: liquidity, }, { id: nearestUsableTick(TickMath.MAX_TICK, TICK_SPACINGS[feeAmount]), liquidityNet: JSBI.multiply(liquidity, JSBI.BigInt(-1)), liquidityGross: liquidity, }, ], }); } const pool_0_1 = v2StylePool( 0, CurrencyAmount.fromRawAmount(token0, 100000), CurrencyAmount.fromRawAmount(token1, 100000) ); const pool_0_2 = v2StylePool( 1, CurrencyAmount.fromRawAmount(token0, 100000), CurrencyAmount.fromRawAmount(token2, 110000) ); const pool_0_3 = v2StylePool( 2, CurrencyAmount.fromRawAmount(token0, 100000), CurrencyAmount.fromRawAmount(token3, 90000) ); const pool_1_2 = v2StylePool( 3, CurrencyAmount.fromRawAmount(token1, 120000), CurrencyAmount.fromRawAmount(token2, 100000) ); const pool_1_3 = v2StylePool( 4, CurrencyAmount.fromRawAmount(token1, 120000), CurrencyAmount.fromRawAmount(token3, 130000) ); describe('#bestTradeExactIn', () => { it('throws with empty pools', async () => { await expect( Trade.bestTradeExactIn([], CurrencyAmount.fromRawAmount(token0, JSBI.BigInt(10000)), token2) ).rejects.toThrow('POOLS') }) it('throws with max hops of 0', async () => { await expect( Trade.bestTradeExactIn([pool_0_2], CurrencyAmount.fromRawAmount(token0, JSBI.BigInt(10000)), token2, { maxHops: 0 }) ).rejects.toThrow('MAX_HOPS') }) it.only('provides best route', async () => { const result = await Trade.bestTradeExactIn( [pool_0_1, pool_0_2, pool_1_2], CurrencyAmount.fromRawAmount(token0, 10000), token2 ) console.log("result", result) expect(result).toHaveLength(2) console.log("result[0].swaps[0].route.tokenPath", result[0].swaps[0].route.tokenPath) console.log("result[0].swaps[0].route.pools", result[0].swaps[0].route.pools) expect(result[0].swaps[0].route.pools).toHaveLength(1) // 0 -> 2 at 10:11 expect(result[0].swaps[0].route.tokenPath).toEqual([token0, token2]) expect(result[0].inputAmount.equalTo(CurrencyAmount.fromRawAmount(token0, JSBI.BigInt(10000)))).toBeTruthy() expect(result[0].outputAmount.equalTo(CurrencyAmount.fromRawAmount(token2, JSBI.BigInt(9971)))).toBeTruthy() expect(result[1].swaps[0].route.pools).toHaveLength(2) // 0 -> 1 -> 2 at 12:12:10 expect(result[1].swaps[0].route.tokenPath).toEqual([token0, token1, token2]) expect(result[1].inputAmount.equalTo(CurrencyAmount.fromRawAmount(token0, JSBI.BigInt(10000)))).toBeTruthy() expect(result[1].outputAmount.equalTo(CurrencyAmount.fromRawAmount(token2, JSBI.BigInt(7004)))).toBeTruthy() }) }) describe("#bestTradeExactOut", () => { it("throws with empty pools", async () => { await expect( Trade.bestTradeExactOut( [], token0, CurrencyAmount.fromRawAmount(token2, JSBI.BigInt(100)) ) ).rejects.toThrow("POOLS"); }); it("throws with max hops of 0", async () => { await expect( Trade.bestTradeExactOut( [pool_0_2], token0, CurrencyAmount.fromRawAmount(token2, JSBI.BigInt(100)), { maxHops: 0, } ) ).rejects.toThrow("MAX_HOPS"); }); it("provides best route", async () => { const result = await Trade.bestTradeExactOut( [pool_0_1, pool_0_2, pool_1_2], token0, CurrencyAmount.fromRawAmount(token2, 10000) ); expect(result).toHaveLength(2); expect(result[0].swaps[0].route.pools).toHaveLength(1); // 0 -> 2 at 10:11 expect(result[0].swaps[0].route.tokenPath).toEqual([token0, token2]); expect( result[0].inputAmount.equalTo( CurrencyAmount.fromRawAmount(token0, 10032) ) ).toBeTruthy(); expect( result[0].outputAmount.equalTo( CurrencyAmount.fromRawAmount(token2, 10000) ) ).toBeTruthy(); expect(result[1].swaps[0].route.pools).toHaveLength(2); // 0 -> 1 -> 2 at 12:12:10 expect(result[1].swaps[0].route.tokenPath).toEqual([ token0, token1, token2, ]); expect( result[1].inputAmount.equalTo( CurrencyAmount.fromRawAmount(token0, 15488) ) ).toBeTruthy(); expect( result[1].outputAmount.equalTo( CurrencyAmount.fromRawAmount(token2, 10000) ) ).toBeTruthy(); }); }); });