@pontem/liquidswap-sdk
Advanced tools
Comparing version 0.1.0 to 0.2.0
@@ -33,10 +33,14 @@ "use strict"; | ||
: [toCoinInfo, fromCoinInfo]; | ||
const coinXReserve = (0, utils_1.d)(liquidityPoolResource.data.coin_x_reserve.value); | ||
const coinYReserve = (0, utils_1.d)(liquidityPoolResource.data.coin_y_reserve.value); | ||
const fromReserve = isSorted ? | ||
(0, utils_1.d)(liquidityPoolResource.data.coin_x_reserve.value) : | ||
(0, utils_1.d)(liquidityPoolResource.data.coin_y_reserve.value); | ||
const toReserve = isSorted ? | ||
(0, utils_1.d)(liquidityPoolResource.data.coin_y_reserve.value) : | ||
(0, utils_1.d)(liquidityPoolResource.data.coin_x_reserve.value); | ||
if (params.interactiveToken === 'to' && toReserve.lessThan(params.amount)) { | ||
throw new Error(`Insufficient funds in Liquidity Pool`); | ||
} | ||
const fee = (0, utils_1.d)(liquidityPoolResource.data.fee); | ||
const coinFromDecimals = +sortedFromCoinInfo.data.decimals; | ||
const coinToDecimals = +sortedToCoinInfo.data.decimals; | ||
const [fromReserve, toReserve] = isSorted | ||
? [coinXReserve, coinYReserve] | ||
: [coinYReserve, coinXReserve]; | ||
let rate; | ||
@@ -46,14 +50,13 @@ if (!params.amount) { | ||
} | ||
if (params.curveType === 'stable') { | ||
if (params.curveType === 'uncorrelated') { | ||
rate = params.interactiveToken === 'from' | ||
? (0, utils_1.getCoinOutWithFees)(params.amount, fromReserve, toReserve, fee) | ||
: (0, utils_1.getCoinInWithFees)(params.amount, toReserve, fromReserve, fee); | ||
return rate.toString(); | ||
} | ||
else { | ||
rate = params.interactiveToken === 'from' | ||
? (0, utils_1.getCoinsOutWithFeesStable)(params.amount, toReserve, fromReserve, (0, utils_1.d)(Math.pow(10, coinToDecimals)), (0, utils_1.d)(Math.pow(10, coinFromDecimals)), fee) | ||
: (0, utils_1.getCoinsInWithFeesStable)(params.amount, fromReserve, toReserve, (0, utils_1.d)(Math.pow(10, coinFromDecimals)), (0, utils_1.d)(Math.pow(10, coinToDecimals)), fee); | ||
return rate; | ||
? (0, utils_1.getCoinsOutWithFeesStable)(params.amount, fromReserve, toReserve, (0, utils_1.d)(Math.pow(10, coinFromDecimals)), (0, utils_1.d)(Math.pow(10, coinToDecimals)), fee) | ||
: (0, utils_1.getCoinsInWithFeesStable)(params.amount, toReserve, fromReserve, (0, utils_1.d)(Math.pow(10, coinToDecimals)), (0, utils_1.d)(Math.pow(10, coinFromDecimals)), fee); | ||
} | ||
return rate.toString(); | ||
}); | ||
@@ -78,6 +81,6 @@ } | ||
? params.fromAmount | ||
: (0, utils_1.withSlippage)(params.slippage, params.fromAmount).toFixed(0); | ||
: (0, utils_1.withSlippage)(params.slippage, params.fromAmount, true).toFixed(0); | ||
const toAmount = params.interactiveToken === 'to' | ||
? params.toAmount | ||
: (0, utils_1.withSlippage)(params.slippage, params.toAmount).toFixed(0); | ||
: (0, utils_1.withSlippage)(params.slippage, params.toAmount, false).toFixed(0); | ||
const args = [fromAmount.toString(), toAmount.toString()]; | ||
@@ -84,0 +87,0 @@ return { |
@@ -5,13 +5,14 @@ import { AptosClient } from "aptos"; | ||
import { AptosResourceType } from "./types/aptos"; | ||
export declare type SdkOptions = { | ||
interface INetworkOptions { | ||
nativeToken?: AptosResourceType; | ||
modules?: { | ||
CoinInfo: AptosResourceType; | ||
CoinStore: AptosResourceType; | ||
Scripts: AptosResourceType; | ||
} & Record<string, AptosResourceType>; | ||
} | ||
export interface SdkOptions { | ||
nodeUrl: string; | ||
networkOptions: { | ||
nativeToken: AptosResourceType; | ||
modules: { | ||
CoinInfo: AptosResourceType; | ||
CoinStore: AptosResourceType; | ||
Scripts: AptosResourceType; | ||
} & Record<string, AptosResourceType>; | ||
}; | ||
}; | ||
networkOptions?: INetworkOptions; | ||
} | ||
export declare class SDK { | ||
@@ -21,15 +22,9 @@ protected _client: AptosClient; | ||
protected _resources: ResourcesModule; | ||
protected _networkOptions: SdkOptions["networkOptions"]; | ||
protected _networkOptions: Required<INetworkOptions>; | ||
get Swap(): SwapModule; | ||
get Resources(): ResourcesModule; | ||
get client(): AptosClient; | ||
get networkOptions(): { | ||
nativeToken: string; | ||
modules: { | ||
CoinInfo: string; | ||
CoinStore: string; | ||
Scripts: string; | ||
} & Record<string, string>; | ||
}; | ||
get networkOptions(): Required<INetworkOptions>; | ||
constructor(options: SdkOptions); | ||
} | ||
export {}; |
@@ -7,5 +7,22 @@ "use strict"; | ||
const ResourcesModule_1 = require("./modules/ResourcesModule"); | ||
const initialNetworkOptions = { | ||
nativeToken: '0x1::aptos_coin::AptosCoin', | ||
modules: { | ||
Scripts: '0x190d44266241744264b964a37b8f09863167a12d3e70cda39376cfb4e3561e12::scripts_v2', | ||
CoinInfo: '0x1::coin::CoinInfo', | ||
CoinStore: '0x1::coin::CoinStore', | ||
}, | ||
}; | ||
class SDK { | ||
constructor(options) { | ||
this._networkOptions = options.networkOptions; | ||
var _a, _b; | ||
this._networkOptions = initialNetworkOptions; | ||
if (options.networkOptions) { | ||
if ((_a = options.networkOptions) === null || _a === void 0 ? void 0 : _a.nativeToken) { | ||
this._networkOptions.nativeToken = options.networkOptions.nativeToken; | ||
} | ||
if ((_b = options.networkOptions) === null || _b === void 0 ? void 0 : _b.modules) { | ||
this._networkOptions.modules = options.networkOptions.modules; | ||
} | ||
} | ||
this._client = new aptos_1.AptosClient(options.nodeUrl); | ||
@@ -12,0 +29,0 @@ this._swap = new SwapModule_1.SwapModule(this); |
@@ -19,3 +19,3 @@ import Decimal from 'decimal.js'; | ||
*/ | ||
export declare function withSlippage(slippage: Decimal, value: Decimal): number; | ||
export declare function withSlippage(slippage: Decimal, value: Decimal, isPlussed: boolean): number; | ||
export declare function extractAddressFromType(type: string): string; | ||
@@ -22,0 +22,0 @@ export declare function checkAptosType(type: any, options?: { |
@@ -107,6 +107,6 @@ "use strict"; | ||
*/ | ||
function withSlippage(slippage, value) { | ||
function withSlippage(slippage, value, isPlussed) { | ||
const multiply = new decimal_js_1.default(10000); | ||
const slippagePercent = slippage.mul(multiply); | ||
return value.minus(value.mul(slippagePercent).div(multiply)).toNumber(); | ||
return isPlussed ? value.plus(value.mul(slippagePercent).div(multiply)).toNumber() : value.minus(value.mul(slippagePercent).div(multiply)).toNumber(); | ||
} | ||
@@ -113,0 +113,0 @@ exports.withSlippage = withSlippage; |
@@ -30,3 +30,3 @@ import Decimal from 'decimal.js'; | ||
*/ | ||
export declare function getCoinsInWithFeesStable(coinOut: Decimal, reserveOut: Decimal, reserveIn: Decimal, scaleOut: Decimal, scaleIn: Decimal, fee: Decimal): string; | ||
export declare function getCoinsInWithFeesStable(coinOut: Decimal, reserveOut: Decimal, reserveIn: Decimal, scaleOut: Decimal, scaleIn: Decimal, fee: Decimal): Decimal; | ||
/** | ||
@@ -46,9 +46,9 @@ * Calculates coin_in value based on first coin value, scales and reserves | ||
* @param {Decimal} coinIn - amount of first('from') token | ||
* @param {Decimal} reserveIn - amount of reserves for first('from') token | ||
* @param {Decimal} reserveOut - amount of reserves for second('to') token | ||
* @param {Decimal} scaleIn - precision for the ('from')token in decimal places | ||
* @param {Decimal} scaleOut - precision for the ('to')token in decimal places | ||
* @param {Decimal} reserveIn - amount of reserves for first ('from') token | ||
* @param {Decimal} reserveOut - amount of reserves for second ('to') token | ||
* @param {Decimal} scaleIn - precision for the ('from') token in decimal places | ||
* @param {Decimal} scaleOut - precision for the ('to') token in decimal places | ||
* @param {Decimal} fee - amount of fee | ||
*/ | ||
export declare function getCoinsOutWithFeesStable(coinIn: Decimal, reserveIn: Decimal, reserveOut: Decimal, scaleIn: Decimal, scaleOut: Decimal, fee: Decimal): string; | ||
export declare function getCoinsOutWithFeesStable(coinIn: Decimal, reserveIn: Decimal, reserveOut: Decimal, scaleIn: Decimal, scaleOut: Decimal, fee: Decimal): Decimal; | ||
/** | ||
@@ -55,0 +55,0 @@ * Calculates coin_out value based on second coin value, scales and reserves |
@@ -55,4 +55,3 @@ "use strict"; | ||
.div(DENOMINATOR.minus(fee)) | ||
.plus(1) | ||
.toString(); | ||
.plus(1); | ||
} | ||
@@ -83,6 +82,6 @@ exports.getCoinsInWithFeesStable = getCoinsInWithFeesStable; | ||
* @param {Decimal} coinIn - amount of first('from') token | ||
* @param {Decimal} reserveIn - amount of reserves for first('from') token | ||
* @param {Decimal} reserveOut - amount of reserves for second('to') token | ||
* @param {Decimal} scaleIn - precision for the ('from')token in decimal places | ||
* @param {Decimal} scaleOut - precision for the ('to')token in decimal places | ||
* @param {Decimal} reserveIn - amount of reserves for first ('from') token | ||
* @param {Decimal} reserveOut - amount of reserves for second ('to') token | ||
* @param {Decimal} scaleIn - precision for the ('from') token in decimal places | ||
* @param {Decimal} scaleOut - precision for the ('to') token in decimal places | ||
* @param {Decimal} fee - amount of fee | ||
@@ -99,3 +98,3 @@ */ | ||
} | ||
return coin_out(coin_in_val_after_fees, scaleIn, scaleOut, reserveIn, reserveOut).toString(); | ||
return coin_out(coin_in_val_after_fees, scaleIn, scaleOut, reserveIn, reserveOut); | ||
} | ||
@@ -102,0 +101,0 @@ exports.getCoinsOutWithFeesStable = getCoinsOutWithFeesStable; |
@@ -10,2 +10,3 @@ module.exports = { | ||
}, | ||
testTimeout: 20000, | ||
} |
{ | ||
"name": "@pontem/liquidswap-sdk", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"description": "SDK for use any functions of LiquidSwap", | ||
@@ -5,0 +5,0 @@ "author": "Igor Demko <igor@pontem.network>", |
@@ -18,41 +18,44 @@ # LiquidSwap SDK | ||
const sdk = new SDK({ | ||
nodeUrl: 'https://fullnode.testnet.aptoslabs.com/v1', // Node URL | ||
networkOptions: { | ||
nativeToken: '0x1::aptos_coin::AptosCoin'', // Type of Native network token | ||
modules: { | ||
Scripts: | ||
'0x190d44266241744264b964a37b8f09863167a12d3e70cda39376cfb4e3561e12::scripts_v2', // This module is used for Swap | ||
CoinInfo: '0x1::coin::CoinInfo', // Type of base CoinInfo module | ||
CoinStore: '0x1::coin::CoinStore', // Type of base CoinStore module | ||
LiquidityPool: '0x05a97986a9d031c4567e15b797be516910cfcb4156312482efc6a19c0a30c948::liquidity_pool' // Liquidity pool module | ||
}, | ||
} | ||
nodeUrl: 'https://fullnode.mainnet.aptoslabs.com/v1', // Node URL, required | ||
/** | ||
networkOptions is optional | ||
networkOptions: { | ||
nativeToken: '0x1::aptos_coin::AptosCoin', - Type of Native network token | ||
modules: { | ||
Scripts: | ||
'0x190d44266241744264b964a37b8f09863167a12d3e70cda39376cfb4e3561e12::scripts_v2', - This module is used for Swap | ||
CoinInfo: '0x1::coin::CoinInfo', - Type of base CoinInfo module | ||
CoinStore: '0x1::coin::CoinStore', - Type of base CoinStore module | ||
}, | ||
} | ||
*/ | ||
}) | ||
``` | ||
### You want swap EXACTLY 1 APTOS to SLIPPAGED USDT amount | ||
### You want swap EXACTLY 1 APTOS to SLIPPAGED layerzero USDT amount | ||
```typescript | ||
(async () => { | ||
// Get BTC amount | ||
const amount = await sdk.Swap.calculateRates({ | ||
fromToken: '0x1::aptos_coin::AptosCoin', // APTOS | ||
toToken: '0x43417434fd869edee76cca2a4d2301e528a1551b1d719b75c350c3c97d15b8b9::coins::USDT', // USDT | ||
amount: new Decimal(1000000), // 1 APTOS (6 decimals) | ||
// Get USDT amount | ||
const output = await sdk.Swap.calculateRates({ | ||
fromToken: '0x1::aptos_coin::AptosCoin', | ||
toToken: '0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::USDT', // layerzero USDT | ||
amount: new Decimal(100000000), // 1 APTOS as Decimal amount | ||
curveType: 'uncorrelated', | ||
interactiveToken: 'from', | ||
curveType: 'stable', | ||
}) | ||
console.log(amount) // '1651.7512324524539471' (0.0016517512324524539471 USDT) | ||
console.log(amount) // '4995851.2364508969978' (4.995851 USDT) | ||
// Generate TX payload for swap 1 APTOS to maximum 0.01584723 BTC | ||
// and minimum 0.01584723 BTC - 5% (with slippage 5%) | ||
// Generate TX payload for swap 1 APTOS to maximum 4.995851 USDT | ||
// and minimum 4.746058 USDT - 5% (with slippage 5%) | ||
const txPayload = sdk.Swap.createSwapTransactionPayload({ | ||
fromToken: '0x1::aptos_coin::AptosCoin', | ||
toToken: '0x43417434fd869edee76cca2a4d2301e528a1551b1d719b75c350c3c97d15b8b9::coins::BTC', | ||
fromAmount: new Decimal(1000000), // 1 APTOS, | ||
toAmount: new Decimal(1584723), // 0.01584723 BTC, | ||
toToken: '0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::USDT', // layerzero USDT | ||
fromAmount: new Decimal(100000000), // 1 APTOS, | ||
toAmount: new Decimal(4995851), // 4.995851 USDT, | ||
interactiveToken: 'from', | ||
slippage: new Decimal(0.05), // 5% (1 - 100%, 0 - 0%) | ||
stableSwapType: 'high', | ||
curveType: 'stable', | ||
stableSwapType: 'normal', | ||
curveType: 'uncorrelated', | ||
}) | ||
@@ -67,7 +70,8 @@ console.log(txPayload); | ||
'0x1::aptos_coin::AptosCoin', | ||
'0x43417434fd869edee76cca2a4d2301e528a1551b1d719b75c350c3c97d15b8b9::coins::BTC', | ||
'0x190d44266241744264b964a37b8f09863167a12d3e70cda39376cfb4e3561e12::curves::Stable' | ||
'0xae478ff7d83ed072dbc5e264250e67ef58f57c99d89b447efd8a0a2e8b2be76e::coin::T', | ||
'0x190d44266241744264b964a37b8f09863167a12d3e70cda39376cfb4e3561e12::curves::Uncorrelated' | ||
], | ||
arguments: [ '1000000', '1505487' ] | ||
arguments: [ '100000000', '4746058' ] | ||
} | ||
*/ | ||
@@ -77,3 +81,3 @@ })() | ||
### You want get EXACTLY 0.001 BTC and send SLIPPAGED APTOS amount | ||
### You want get EXACTLY 1 BTC and send SLIPPAGED APTOS amount | ||
```typescript | ||
@@ -84,20 +88,20 @@ (async () => { | ||
fromToken: '0x1::aptos_coin::AptosCoin', | ||
toToken: '0x43417434fd869edee76cca2a4d2301e528a1551b1d719b75c350c3c97d15b8b9::coins::BTC', | ||
amount: new Decimal(100000), // 0.001 BTC | ||
toToken: '0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::USDT', | ||
amount: new Decimal(1000000), // 1 USDT | ||
interactiveToken: 'to', // 'from' - calculate TO amount, 'to' - calculate FROM amount | ||
curveType: 'stable', | ||
curveType: 'uncorrelated', | ||
}) | ||
console.log(amount) // '2741440067.7675726625' (2741.4400677675726625 APTOS) | ||
console.log(amount) // '20032733.69689480612' (0.20032734 APTOS) | ||
// Generate TX payload for get EXACTLY 0.001 BTC | ||
// and minimum send 2741.440068 + 5% (with slippage 5%) | ||
// Generate TX payload for get EXACTLY 1 USDT | ||
// and minimum send 0.20032734 + 5% (with slippage 5%) | ||
const txPayload = sdk.Swap.createSwapTransactionPayload({ | ||
fromToken: '0x1::aptos_coin::AptosCoin', | ||
toToken: '0x43417434fd869edee76cca2a4d2301e528a1551b1d719b75c350c3c97d15b8b9::coins::BTC', | ||
fromAmount: new Decimal(2741440068), // 2741.440068 APTOS, | ||
toAmount: new Decimal(100000), // 0.001 BTC, | ||
toToken: '0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::USDT', | ||
fromAmount: new Decimal(20032734), // 0.20032734 APTOS, | ||
toAmount: new Decimal(1000000), // 1 USDT, | ||
interactiveToken: 'to', | ||
slippage: new Decimal(0.05), // 5% (1 - 100%, 0 - 0%) | ||
stableSwapType: 'high', | ||
curveType: 'stable', | ||
stableSwapType: 'normal', | ||
curveType: 'uncorrelated', | ||
}) | ||
@@ -112,6 +116,6 @@ console.log(txPayload); | ||
'0x1::aptos_coin::AptosCoin', | ||
'0x43417434fd869edee76cca2a4d2301e528a1551b1d719b75c350c3c97d15b8b9::coins::BTC', | ||
'0x190d44266241744264b964a37b8f09863167a12d3e70cda39376cfb4e3561e12::curves::Stable' | ||
'0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::USDT', | ||
'0x190d44266241744264b964a37b8f09863167a12d3e70cda39376cfb4e3561e12::curves::Uncorrelated' | ||
], | ||
arguments: [ '2604368065', '100000' ] | ||
arguments: [ '21034371', '1000000' ] | ||
} | ||
@@ -118,0 +122,0 @@ */ |
import SDK from './main' | ||
import { d, decimalsMultiplier } from "./utils"; | ||
import { NETWORKS_MODULES } from "./constants"; | ||
const TokensMapping: Record<string, string> = { | ||
APTOS: '0x1::aptos_coin::AptosCoin', | ||
USDT: '0x43417434fd869edee76cca2a4d2301e528a1551b1d719b75c350c3c97d15b8b9::coins::USDT', | ||
BTC: '0x43417434fd869edee76cca2a4d2301e528a1551b1d719b75c350c3c97d15b8b9::coins::BTC', | ||
USDT: '0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::USDT', //layerzero | ||
BTC: '0xae478ff7d83ed072dbc5e264250e67ef58f57c99d89b447efd8a0a2e8b2be76e::coin::T', // wormhole wrapped BTC | ||
WETH: '0xcc8a89c8dce9693d354449f1f73e60e14e347417854f029db5bc8e7454008abb::coin::T' // wormhole WETH | ||
}; | ||
const CoinInfo: Record<string, { decimals: number }> = { | ||
APTOS: { decimals: 6 }, | ||
APTOS: { decimals: 8 }, | ||
USDT: { decimals: 6 }, | ||
BTC: { decimals: 8 } | ||
BTC: { decimals: 8 }, | ||
WETH: { decimals: 8 } | ||
} | ||
@@ -31,13 +32,3 @@ | ||
const sdk = new SDK({ | ||
nodeUrl: 'https://fullnode.testnet.aptoslabs.com/v1', | ||
networkOptions: { | ||
nativeToken: '0x1::aptos_coin::AptosCoin', | ||
modules: { | ||
Scripts: NETWORKS_MODULES.Scripts, | ||
Faucet: NETWORKS_MODULES.Faucet, | ||
LiquidityPool: NETWORKS_MODULES.LiquidityPool, | ||
CoinInfo: NETWORKS_MODULES.CoinInfo, | ||
CoinStore: NETWORKS_MODULES.CoinStore, | ||
}, | ||
} | ||
nodeUrl: 'https://fullnode.mainnet.aptoslabs.com/v1', | ||
}) | ||
@@ -50,3 +41,3 @@ test('calculateRates (from mode)', async () => { | ||
amount: convertToDecimals(1, 'APTOS'), | ||
curveType: 'stable', | ||
curveType: 'uncorrelated', | ||
interactiveToken: 'from', | ||
@@ -64,10 +55,8 @@ }) | ||
test('calculateRates (to mode)', async () => { | ||
console.log({amountInToMode: convertToDecimals('0.001', 'BTC')}); | ||
console.log(convertToDecimals('0.001', 'BTC'),); | ||
console.log({amountInToMode: convertToDecimals(1, 'USDT')}); | ||
const output = await sdk.Swap.calculateRates({ | ||
fromToken: TokensMapping.APTOS, | ||
toToken: TokensMapping.BTC, | ||
amount: convertToDecimals('0.001', 'BTC'), | ||
curveType: 'stable', | ||
toToken: TokensMapping.USDT, | ||
amount: convertToDecimals('1', 'USDT'), | ||
curveType: 'uncorrelated', | ||
interactiveToken: 'to', | ||
@@ -84,3 +73,42 @@ }) | ||
test('createSwapTransactionPayload (to mode)', async () => { | ||
test('calculateRates (from mode stable)', async () => { | ||
console.log({amountIn: convertToDecimals(1, 'APTOS')}); | ||
const output = await sdk.Swap.calculateRates({ | ||
fromToken: TokensMapping.APTOS, | ||
toToken: TokensMapping.WETH, | ||
amount: convertToDecimals('1', 'APTOS'), | ||
curveType: 'stable', | ||
interactiveToken: 'from', | ||
}) | ||
console.log({ | ||
amount: output, | ||
pretty: prettyAmount(output, 'WETH'), | ||
}); | ||
expect(1).toBe(1); | ||
}); | ||
test('calculateRates (to mode stable) and get error', async () => { | ||
console.log({amountIn: convertToDecimals(1, 'WETH')}); | ||
try { | ||
const output = await sdk.Swap.calculateRates({ | ||
fromToken: TokensMapping.APTOS, | ||
toToken: TokensMapping.WETH, | ||
amount: convertToDecimals('1', 'WETH'), | ||
curveType: 'stable', | ||
interactiveToken: 'to', | ||
}) | ||
console.log({ | ||
amount: output, | ||
pretty: prettyAmount(output, 'WETH'), | ||
}); | ||
} catch(e) { | ||
expect(e).toMatchObject(new Error('Insufficient funds in Liquidity Pool')); | ||
} | ||
}); | ||
test('createSwapTransactionPayload (uncorrelated from mode high)', async () => { | ||
const output = sdk.Swap.createSwapTransactionPayload({ | ||
@@ -90,20 +118,75 @@ fromToken: TokensMapping.APTOS, | ||
fromAmount: convertToDecimals('1', 'APTOS'), | ||
toAmount: convertToDecimals('0.01584723', 'BTC'), | ||
toAmount: convertToDecimals('4.995851', 'USDT'), | ||
interactiveToken: 'from', | ||
slippage: d(0.05), | ||
stableSwapType: 'high', | ||
curveType: 'stable', | ||
curveType: 'uncorrelated', | ||
}) | ||
console.log(output); | ||
expect(output).toStrictEqual({ | ||
type: 'entry_function_payload', | ||
function: '0x190d44266241744264b964a37b8f09863167a12d3e70cda39376cfb4e3561e12::scripts_v2::swap', | ||
typeArguments: [ | ||
'0x1::aptos_coin::AptosCoin', | ||
'0xae478ff7d83ed072dbc5e264250e67ef58f57c99d89b447efd8a0a2e8b2be76e::coin::T', | ||
'0x190d44266241744264b964a37b8f09863167a12d3e70cda39376cfb4e3561e12::curves::Uncorrelated' | ||
], | ||
arguments: ['100000000', '4746058'] | ||
}) | ||
}) | ||
expect(1).toBe(1) | ||
test('createSwapTransactionPayload (uncorrelated to mode high)', async () => { | ||
const output = sdk.Swap.createSwapTransactionPayload({ | ||
fromToken: TokensMapping.APTOS, | ||
toToken: TokensMapping.BTC, | ||
fromAmount: convertToDecimals('1', 'APTOS'), | ||
toAmount: convertToDecimals('4.995851', 'USDT'), | ||
interactiveToken: 'to', | ||
slippage: d(0.05), | ||
stableSwapType: 'high', | ||
curveType: 'uncorrelated', | ||
}) | ||
expect(output).toStrictEqual({ | ||
type: 'entry_function_payload', | ||
function: '0x190d44266241744264b964a37b8f09863167a12d3e70cda39376cfb4e3561e12::scripts_v2::swap_into', | ||
typeArguments: [ | ||
'0x1::aptos_coin::AptosCoin', | ||
'0xae478ff7d83ed072dbc5e264250e67ef58f57c99d89b447efd8a0a2e8b2be76e::coin::T', | ||
'0x190d44266241744264b964a37b8f09863167a12d3e70cda39376cfb4e3561e12::curves::Uncorrelated' | ||
], | ||
arguments: ['105000000', '4995851'] | ||
}) | ||
}); | ||
test('createSwapTransactionPayload (from mode)', async () => { | ||
test('createSwapTransactionPayload (stable from mode high)', async () => { | ||
const output = sdk.Swap.createSwapTransactionPayload({ | ||
fromToken: TokensMapping.APTOS, | ||
toToken: TokensMapping.BTC, | ||
fromAmount: convertToDecimals('2741.440068', 'APTOS'), | ||
toAmount: convertToDecimals('0.001', 'BTC'), | ||
toToken: TokensMapping.WETH, | ||
fromAmount: convertToDecimals('1', 'APTOS'), | ||
toAmount: convertToDecimals('0.000846', 'WETH'), | ||
interactiveToken: 'from', | ||
slippage: d(0.05), | ||
stableSwapType: 'high', | ||
curveType: 'stable', | ||
}) | ||
expect(output).toStrictEqual({ | ||
type: 'entry_function_payload', | ||
function: '0x190d44266241744264b964a37b8f09863167a12d3e70cda39376cfb4e3561e12::scripts_v2::swap', | ||
typeArguments: [ | ||
'0x1::aptos_coin::AptosCoin', | ||
'0xcc8a89c8dce9693d354449f1f73e60e14e347417854f029db5bc8e7454008abb::coin::T', | ||
'0x190d44266241744264b964a37b8f09863167a12d3e70cda39376cfb4e3561e12::curves::Stable' | ||
], | ||
arguments: ['100000000', '80370'] | ||
}) | ||
}); | ||
test('createSwapTransactionPayload (stable to mode high)', async () => { | ||
const output = sdk.Swap.createSwapTransactionPayload({ | ||
fromToken: TokensMapping.APTOS, | ||
toToken: TokensMapping.WETH, | ||
fromAmount: convertToDecimals('1', 'APTOS'), | ||
toAmount: convertToDecimals('0.000846', 'WETH'), | ||
interactiveToken: 'to', | ||
@@ -115,6 +198,61 @@ slippage: d(0.05), | ||
console.log(output); | ||
expect(output).toStrictEqual({ | ||
type: 'entry_function_payload', | ||
function: '0x190d44266241744264b964a37b8f09863167a12d3e70cda39376cfb4e3561e12::scripts_v2::swap_into', | ||
typeArguments: [ | ||
'0x1::aptos_coin::AptosCoin', | ||
'0xcc8a89c8dce9693d354449f1f73e60e14e347417854f029db5bc8e7454008abb::coin::T', | ||
'0x190d44266241744264b964a37b8f09863167a12d3e70cda39376cfb4e3561e12::curves::Stable' | ||
], | ||
arguments: ['105000000', '84600'] | ||
}); | ||
}); | ||
expect(1).toBe(1) | ||
test('createSwapTransactionPayload (stable from mode normal)', async () => { | ||
const output = sdk.Swap.createSwapTransactionPayload({ | ||
fromToken: TokensMapping.APTOS, | ||
toToken: TokensMapping.WETH, | ||
fromAmount: convertToDecimals('1', 'APTOS'), | ||
toAmount: convertToDecimals('0.000846', 'WETH'), | ||
interactiveToken: 'from', | ||
slippage: d(0.05), | ||
stableSwapType: 'normal', | ||
curveType: 'stable', | ||
}) | ||
expect(output).toStrictEqual({ | ||
type: 'entry_function_payload', | ||
function: '0x190d44266241744264b964a37b8f09863167a12d3e70cda39376cfb4e3561e12::scripts_v2::swap_unchecked', | ||
typeArguments: [ | ||
'0x1::aptos_coin::AptosCoin', | ||
'0xcc8a89c8dce9693d354449f1f73e60e14e347417854f029db5bc8e7454008abb::coin::T', | ||
'0x190d44266241744264b964a37b8f09863167a12d3e70cda39376cfb4e3561e12::curves::Stable' | ||
], | ||
arguments: ['100000000', '80370'] | ||
}) | ||
}); | ||
test('createSwapTransactionPayload (stable to mode normal)', async () => { | ||
const output = sdk.Swap.createSwapTransactionPayload({ | ||
fromToken: TokensMapping.APTOS, | ||
toToken: TokensMapping.WETH, | ||
fromAmount: convertToDecimals('1', 'APTOS'), | ||
toAmount: convertToDecimals('0.000846', 'WETH'), | ||
interactiveToken: 'to', | ||
slippage: d(0.05), | ||
stableSwapType: 'normal', | ||
curveType: 'stable', | ||
}) | ||
expect(output).toStrictEqual({ | ||
type: 'entry_function_payload', | ||
function: '0x190d44266241744264b964a37b8f09863167a12d3e70cda39376cfb4e3561e12::scripts_v2::swap_unchecked', | ||
typeArguments: [ | ||
'0x1::aptos_coin::AptosCoin', | ||
'0xcc8a89c8dce9693d354449f1f73e60e14e347417854f029db5bc8e7454008abb::coin::T', | ||
'0x190d44266241744264b964a37b8f09863167a12d3e70cda39376cfb4e3561e12::curves::Stable' | ||
], | ||
arguments: ['105000000', '84600'] | ||
}) | ||
}); | ||
}) |
@@ -1,2 +0,2 @@ | ||
import Decimal from 'decimal.js' | ||
import Decimal from 'decimal.js'; | ||
@@ -36,3 +36,3 @@ import { SDK } from "../sdk"; | ||
curveType: CurveType; | ||
} | ||
}; | ||
@@ -48,3 +48,3 @@ export type CreateTXPayloadParams = { | ||
curveType: CurveType; | ||
} | ||
}; | ||
@@ -68,3 +68,3 @@ export class SwapModule implements IModule { | ||
composeType(modules.CoinInfo, [params.fromToken]) | ||
) | ||
); | ||
@@ -74,9 +74,9 @@ const toCoinInfo = await this.sdk.Resources.fetchAccountResource<AptosCoinInfoResource>( | ||
composeType(modules.CoinInfo, [params.toToken]) | ||
) | ||
); | ||
if(!fromCoinInfo) { | ||
if (!fromCoinInfo) { | ||
throw new Error('From Coin not exists'); | ||
} | ||
if(!toCoinInfo) { | ||
if (!toCoinInfo) { | ||
throw new Error('To Coin not exists'); | ||
@@ -87,4 +87,4 @@ } | ||
if(!liquidityPoolResource) { | ||
throw new Error(`LiquidityPool (${liquidityPoolType}) not found`) | ||
if (!liquidityPoolResource) { | ||
throw new Error(`LiquidityPool (${liquidityPoolType}) not found`); | ||
} | ||
@@ -98,4 +98,13 @@ | ||
const coinXReserve = d(liquidityPoolResource.data.coin_x_reserve.value); | ||
const coinYReserve = d(liquidityPoolResource.data.coin_y_reserve.value); | ||
const fromReserve = isSorted ? | ||
d(liquidityPoolResource.data.coin_x_reserve.value) : | ||
d(liquidityPoolResource.data.coin_y_reserve.value); | ||
const toReserve = isSorted ? | ||
d(liquidityPoolResource.data.coin_y_reserve.value) : | ||
d(liquidityPoolResource.data.coin_x_reserve.value); | ||
if (params.interactiveToken === 'to' && toReserve.lessThan(params.amount)) { | ||
throw new Error(`Insufficient funds in Liquidity Pool`); | ||
} | ||
const fee = d(liquidityPoolResource.data.fee); | ||
@@ -106,7 +115,2 @@ | ||
const [fromReserve, toReserve] = isSorted | ||
? [coinXReserve, coinYReserve] | ||
: [coinYReserve, coinXReserve]; | ||
let rate; | ||
@@ -117,8 +121,6 @@ if (!params.amount) { | ||
if (params.curveType === 'stable') { | ||
if (params.curveType === 'uncorrelated') { | ||
rate = params.interactiveToken === 'from' | ||
? getCoinOutWithFees(params.amount, fromReserve, toReserve, fee) | ||
: getCoinInWithFees(params.amount, toReserve, fromReserve, fee); | ||
return rate.toString(); | ||
} else { | ||
@@ -128,6 +130,6 @@ rate = params.interactiveToken === 'from' | ||
params.amount, | ||
fromReserve, | ||
toReserve, | ||
fromReserve, | ||
d(Math.pow(10, coinFromDecimals)), | ||
d(Math.pow(10, coinToDecimals)), | ||
d(Math.pow(10, coinFromDecimals)), | ||
fee | ||
@@ -137,15 +139,14 @@ ) | ||
params.amount, | ||
toReserve, | ||
fromReserve, | ||
toReserve, | ||
d(Math.pow(10, coinToDecimals)), | ||
d(Math.pow(10, coinFromDecimals)), | ||
d(Math.pow(10, coinToDecimals)), | ||
fee | ||
) | ||
return rate; | ||
); | ||
} | ||
return rate.toString(); | ||
} | ||
createSwapTransactionPayload(params: CreateTXPayloadParams): TAptosTxPayload { | ||
if(params.slippage.gte(1) || params.slippage.lte(0 )) { | ||
if (params.slippage.gte(1) || params.slippage.lte(0)) { | ||
throw new Error(`Invalid slippage (${params.slippage}) value`); | ||
@@ -161,4 +162,4 @@ } | ||
isUnchecked | ||
? 'swap_unchecked' | ||
: params.interactiveToken === 'from' ? 'swap' : 'swap_into' | ||
? 'swap_unchecked' | ||
: params.interactiveToken === 'from' ? 'swap' : 'swap_into' | ||
); | ||
@@ -177,7 +178,7 @@ | ||
? params.fromAmount | ||
: withSlippage(params.slippage, params.fromAmount).toFixed(0); | ||
: withSlippage(params.slippage, params.fromAmount, true).toFixed(0); | ||
const toAmount = | ||
params.interactiveToken === 'to' | ||
? params.toAmount | ||
: withSlippage(params.slippage, params.toAmount).toFixed(0); | ||
: withSlippage(params.slippage, params.toAmount, false).toFixed(0); | ||
@@ -213,5 +214,3 @@ const args = [fromAmount.toString(), toAmount.toString()]; | ||
const liquidityPoolType = getPoolStr(params.fromToken, | ||
params.toToken, | ||
curve); | ||
const liquidityPoolType = getPoolStr(params.fromToken, params.toToken, curve); | ||
@@ -224,7 +223,7 @@ let liquidityPoolResource; | ||
liquidityPoolType | ||
) | ||
); | ||
} catch (e) { | ||
console.log(e) | ||
console.log(e); | ||
} | ||
return { liquidityPoolType, liquidityPoolResource } | ||
return { liquidityPoolType, liquidityPoolResource }; | ||
} | ||
@@ -231,0 +230,0 @@ } |
@@ -6,14 +6,26 @@ import {AptosClient} from "aptos"; | ||
export type SdkOptions = { | ||
nodeUrl: string, | ||
networkOptions: { | ||
nativeToken: AptosResourceType, | ||
modules: { | ||
CoinInfo: AptosResourceType, | ||
CoinStore: AptosResourceType, | ||
Scripts: AptosResourceType, | ||
} & Record<string, AptosResourceType>, | ||
} | ||
const initialNetworkOptions = { | ||
nativeToken: '0x1::aptos_coin::AptosCoin', | ||
modules: { | ||
Scripts: '0x190d44266241744264b964a37b8f09863167a12d3e70cda39376cfb4e3561e12::scripts_v2', | ||
CoinInfo: '0x1::coin::CoinInfo', | ||
CoinStore: '0x1::coin::CoinStore', | ||
}, | ||
} | ||
interface INetworkOptions { | ||
nativeToken?: AptosResourceType; | ||
modules?: { | ||
CoinInfo: AptosResourceType; | ||
CoinStore: AptosResourceType; | ||
Scripts: AptosResourceType; | ||
} & Record<string, AptosResourceType> | ||
} | ||
export interface SdkOptions { | ||
nodeUrl: string; | ||
networkOptions?: INetworkOptions; | ||
} | ||
export class SDK { | ||
@@ -23,3 +35,3 @@ protected _client: AptosClient; | ||
protected _resources: ResourcesModule; | ||
protected _networkOptions: SdkOptions["networkOptions"]; | ||
protected _networkOptions: Required<INetworkOptions>; | ||
@@ -43,3 +55,11 @@ get Swap() { | ||
constructor(options: SdkOptions) { | ||
this._networkOptions = options.networkOptions; | ||
this._networkOptions = initialNetworkOptions; | ||
if (options.networkOptions) { | ||
if (options.networkOptions?.nativeToken) { | ||
this._networkOptions.nativeToken = options.networkOptions.nativeToken; | ||
} | ||
if (options.networkOptions?.modules) { | ||
this._networkOptions.modules = options.networkOptions.modules; | ||
} | ||
} | ||
this._client = new AptosClient(options.nodeUrl); | ||
@@ -46,0 +66,0 @@ this._swap = new SwapModule(this); |
@@ -133,7 +133,6 @@ import { Buffer } from "buffer"; | ||
*/ | ||
export function withSlippage(slippage: Decimal, value: Decimal) { | ||
export function withSlippage(slippage: Decimal, value: Decimal, isPlussed: boolean) { | ||
const multiply = new Decimal(10000); | ||
const slippagePercent = slippage.mul(multiply); | ||
return value.minus(value.mul(slippagePercent).div(multiply)).toNumber(); | ||
return isPlussed ? value.plus(value.mul(slippagePercent).div(multiply)).toNumber() : value.minus(value.mul(slippagePercent).div(multiply)).toNumber(); | ||
} | ||
@@ -140,0 +139,0 @@ |
@@ -20,3 +20,3 @@ import Decimal from 'decimal.js'; | ||
fee: Decimal | ||
) { | ||
): Decimal { | ||
const { feePct, feeScale } = { feePct: fee, feeScale: d(DENOMINATOR) }; | ||
@@ -42,3 +42,3 @@ const feeMultiplier = feeScale.minus(feePct); | ||
fee: Decimal | ||
) { | ||
): Decimal { | ||
const feeMultiplier = DENOMINATOR.minus(fee); | ||
@@ -66,3 +66,3 @@ const newReservesOutSize = (reserveOutSize.minus(coinOutVal)).mul(feeMultiplier); | ||
fee: Decimal | ||
) { | ||
): Decimal { | ||
const r = coin_in(coinOut, scaleOut, scaleIn, reserveOut, reserveIn); | ||
@@ -73,4 +73,3 @@ return r | ||
.div(DENOMINATOR.minus(fee)) | ||
.plus(1) | ||
.toString(); | ||
.plus(1); | ||
} | ||
@@ -109,6 +108,6 @@ | ||
* @param {Decimal} coinIn - amount of first('from') token | ||
* @param {Decimal} reserveIn - amount of reserves for first('from') token | ||
* @param {Decimal} reserveOut - amount of reserves for second('to') token | ||
* @param {Decimal} scaleIn - precision for the ('from')token in decimal places | ||
* @param {Decimal} scaleOut - precision for the ('to')token in decimal places | ||
* @param {Decimal} reserveIn - amount of reserves for first ('from') token | ||
* @param {Decimal} reserveOut - amount of reserves for second ('to') token | ||
* @param {Decimal} scaleIn - precision for the ('from') token in decimal places | ||
* @param {Decimal} scaleOut - precision for the ('to') token in decimal places | ||
* @param {Decimal} fee - amount of fee | ||
@@ -123,3 +122,3 @@ */ | ||
fee: Decimal | ||
): string { | ||
): Decimal { | ||
let coin_in_val_after_fees = new Decimal(0); | ||
@@ -138,3 +137,3 @@ const coin_in_val_scaled = coinIn.mul(DENOMINATOR.minus(fee)); | ||
reserveOut | ||
).toString(); | ||
); | ||
} | ||
@@ -141,0 +140,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
152975
2287
120
0